{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE BinaryLiterals #-} module ABNF where import Test.Tasty import Test.Tasty.HUnit import Text.Megaparsec import Text.Megaparsec.Text import qualified Data.Text as T import Text.ABNF.Parser import Text.ABNF.Parser.Types import Util testParser :: (Eq a, Show a) => Parser a -> T.Text -> a -> Assertion testParser parser input expected = case parse parser "" input of Left msg -> assertFailure (show msg) Right a -> assertEqual "" expected a abnfTests :: TestTree abnfTests = testGroup "ABNF Parser" [ let testLit = testParser literal in testGroup "Literals" $ [ testCase "CharLit" $ testLit "\"a\"" (CharLit "a") , testCase "Long CharLit" $ testLit "\"asdfghjkl\"" (CharLit "asdfghjkl") , testCase "IntLit" $ testLit "%x20" (NumLit $ IntLit [0x20]) , testCase "IntLit.conat" $ testLit "%x20.20" (NumLit $ IntLit [0x20,0x20]) , testCase "IntLit decimal" $ testLit "%d32" (NumLit $ IntLit [32]) , testCase "IntLit binary" $ testLit "%b00100000" (NumLit $ IntLit [0b00100000]) , testCase "RangeLit" $ testLit "%x41-5A" (NumLit $ RangeLit 0x41 0x5A) ] , let testRep = testParser repetition in testGroup "Repetition" $ [ testCase "single" $ testRep "%x20" (single wsElement) , testCase "1-2 times" $ testRep "1*2%x20" (Repetition (Repeat 1 (Just 2)) wsElement) , testCase "1-* times" $ testRep "1*%x20" (Repetition (Repeat 1 Nothing) wsElement) , testCase "* times" $ testRep "*%x20" (Repetition (Repeat 0 Nothing) wsElement) ] , let testProd = testParser concatenation in testGroup "Concatenation" $ [ testCase "simple" $ testProd "%x20 %x20" (ProductSpec [single wsElement, single wsElement]) , testCase "group" $ testProd "%x20 (%x20 %x20)" (ProductSpec [ single wsElement , single $ GroupElement (Group (SumSpec [ ProductSpec [ single wsElement , single wsElement ] ])) ]) ] , let testSum = testParser elements in testGroup "Elements" $ [ testCase "simple" $ testSum "%x20" (SumSpec [simpleProd wsElement]) , testCase "sum" $ testSum "%x20 / %x09" (SumSpec [ simpleProd wsElement , simpleProd (LiteralElement . NumLit $ IntLit [0x09])]) , testCase "complex" $ testSum "%x20 / %x20 (%x20 / %x20)" (SumSpec [ simpleProd wsElement , ProductSpec [ single wsElement , single $ GroupElement (Group (SumSpec [simpleProd wsElement, simpleProd wsElement])) ] ]) ] , let testRule = testParser rule in testGroup "Rule" $ [ testCase "equals" $ testRule "a = %x20\r\n" (Rule "a" Equals (simpleSum wsElement)) , testCase "adds" $ testRule "a =/ %x20\r\n" (Rule "a" Adds (simpleSum wsElement)) ] ]