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