packages feed

isobmff-builder-0.9.0.0: spec/BoxFieldsSpec.hs

module BoxFieldsSpec (spec) where

import Test.Hspec
import Data.ByteString.IsoBaseFileFormat.Boxes
-- import qualified Data.ByteString.Builder as B
import qualified Data.ByteString.Lazy as BL
-- import qualified Data.Binary.Get as Binary
import Control.Exception (evaluate)
import qualified Data.Text as T

-- import qualified Data.ByteString.Builder as B import qualified Data.ByteString.Lazy as BL import
-- qualified Data.Binary.Get as Binary
spec :: Spec
spec =
  do describe "boxSize of Data.Text.Text" $
       it "returns string length + 1 (for the null termination byte)" $ do
          boxSize (T.pack "") `shouldBe` 1
          boxSize (T.pack "Hello!") `shouldBe` 7
     describe "boxBuilder of Data.Text.Text" $ do
       it "appends the null termination byte" $
          let expected = [72,101,108,108,111,32,119,111,114,108,100,33,0]
              actual = BL.unpack $ toLazyByteString $ boxBuilder (T.pack "Hello world!")
              in actual `shouldBe` expected
       it "appends the null termination byte" $
          let expected = [72,101,108,108,111,32,119,111,114,108,100,33,0]
              actual = BL.unpack $ toLazyByteString $ boxBuilder (T.pack "Hello world!")
              in actual `shouldBe` expected
       it "replaces embeded NULL characters with a space (0x20)" $
          let expected = [72,101,108,108,111,32,119,111,114,108,100,33,0]
              actual = BL.unpack $ toLazyByteString $ boxBuilder (T.pack "Hello\0world!")
              in actual `shouldBe` expected
     describe "mkLanguage" $
       do it "throws runtime exceptions when the code is too short or too long" $
            do evaluate (mkLanguage "") `shouldThrow` anyException
               evaluate (mkLanguage "a") `shouldThrow` anyException
               evaluate (mkLanguage "aa") `shouldThrow` anyException
               evaluate (mkLanguage "bbbb") `shouldThrow` anyException
               evaluate (mkLanguage "bbbbb") `shouldThrow` anyException
          it "throws runtime exceptions when the code is not in aaa .. zzz" $
            do evaluate (mkLanguage "! 3") `shouldThrow` anyException
               evaluate (mkLanguage "AAA") `shouldThrow` anyException
          it "renders lower case three-letter strings correctly" $
            let actual =
                  BL.unpack (toLazyByteString (boxBuilder (mkLanguage "deu")))
                expected =
                  BL.unpack (toLazyByteString (word16BE (4 * 1024 + 5 * 32 + 21)))
            in actual `shouldBe` expected
     describe "Scalar, Constant, Template and ScalarArry composition" $
       describe "IsBoxContent instances" $
       do describe "example1" $
            do it "boxSize reports the correct size" $ boxSize example1 `shouldBe`
                 (1 + 1 + (3 * 8) + (7 * 8))
               it "crashes during rendering because of the invalid number of array elements for \"baz\"" $
                 evaluate (renderBox example1') `shouldThrow`
                 anyException
          describe "example2" $
            do it "boxSize reports the correct size" $ boxSize example2 `shouldBe`
                 (2 * 4 + 2 + 2 + 2 + 2 + 9 * 4 + 4 + 4)
               it "it renders the expected content" $ renderBox example2 `shouldBe`
                 (BL.pack [0 ,0 ,0 ,0
                          ,0 ,0 ,0 ,0
                          ,0 ,65 ,0 ,66
                          ,1 ,0 ,0 ,0
                          ,0 ,0 ,0 ,67
                          ,0 ,0 ,0 ,68
                          ,0 ,0 ,0 ,69
                          ,0 ,0 ,0 ,70
                          ,0 ,0 ,0 ,71
                          ,0 ,0 ,0 ,72
                          ,0 ,0 ,0 ,73
                          ,0 ,0 ,0 ,74
                          ,0 ,0 ,0 ,75
                          ,0 ,0 ,0 ,76
                          ,0 ,0 ,0 ,77])

renderBox :: IsBoxContent c
          => c -> BL.ByteString
renderBox = toLazyByteString . boxBuilder

type ExampleContent = Scalar Word8 "bla" :+ Constant (Scalar Word8 "blub") 123 :+ Template (ScalarArray "foos" 3 Int64) '[1, 2, 3] :+ ScalarArray "baz" 7 Word64

type ExampleContentShort = U8 "bla" :+ Constant (U8 "blub") 123 :+ Template (I64Arr "foos" 3) '[1, 2, 3] :+ U64Arr "baz" 7

example1 :: ExampleContent
example1 = Scalar 100 :+ Constant :+ Default :+ u64Arr [1,2,3]

example1' :: ExampleContentShort
example1' = example1

type Example2 isAudio = Constant (I32Arr "reserved" 2) '[0, 0] :+ Template (I16 "layer") 0 :+ Template (I16 "alternate_group") 0 :+ Template (I16 "volume") (If isAudio 256 0) :+ Constant (I16 "reserved") 0 :+ Template (I32Arr "matrix" 9) '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824] :+ I32 "width" :+ I32 "height"

example2 :: Example2 'True
example2 =
  Constant :+ Custom 65 :+ Custom 66 :+ Default :+ Constant :+
  Custom (i32Arr [67 .. 75]) :+
  i32 76 :+
  i32 77