Мне нужно настроить тестовый набор, который позволит мне определить, не нарушают ли изменения, которые я делаю в синтаксическом анализаторе, что-либо еще в дальнейшем.
Я использую для этого модульные тесты tasty
, и вот что у меня есть:
simpleLabels :: TestTree
simpleLabels = testGroup "Simple label searches"
[ testCase "List comparison (same length)" $ -- just a test to make sure that the @?= works like it should
[1, 2, 3] `compare` [1,2,2] @?= LT
,
testCase "Phonetic = a " $
parse umeQuery "Source" "Phonetic = a " @?= Right ( LabelInLabelType "Phonetic" ["a"] "=")
]
Теперь этот поток правильно анализируется синтаксическим анализатором, когда я запускаю его в REPL:
> parse umeQuery "something" (pack "Phonetic = a ")
Right (LabelInLabelType "Phonetic" ["a"] "=")
Это похоже на то, что должно быть, и, следовательно, то, что я установил в тесте выше.
Теперь набор тестов вообще не собирается, выдавая ошибку:
TestQueryParser.hs:29:55:
No instance for (Eq ParseError) arising from a use of ‘@?=’
In the second argument of ‘($)’, namely
‘parse umeQuery "Ume Query : " "Phonetic = a "
@?= Right (LabelInLabelType "Phonetic" ["a"] "=")’
In the expression:
testCase "Phonetic = a "
$ parse umeQuery "Ume Query : " "Phonetic = a "
@?= Right (LabelInLabelType "Phonetic" ["a"] "=")
In the second argument of ‘testGroup’, namely
‘[testCase "List comparison (same length)"
$ [1, 2, ....] `compare` [1, 2, ....] @?= LT,
testCase "Phonetic = a "
$ parse umeQuery "Ume Query : " "Phonetic = a "
@?= Right (LabelInLabelType "Phonetic" ["a"] "=")]’
Почему мне это нужно, учитывая тот факт, что успешный/правильный синтаксический анализ должен привести к значению Right a
?
Как лучше всего настроить модульный тест для синтаксического анализатора парсека?
Either e a
, какe
, так иa
должны быть экземплярамиEq
в соответствии с определениемEq
дляEither
:instance (Eq e, Eq a) => Eq (Either e a) where ...
, потому что комплер не может знать, что у вас будет толькоRight
, если типEither
. Как видите, Parsec вообще не предназначен для проверки своих сообщений об ошибках. Если вы хотите работать с сообщениями об ошибках, используйте Megaparsec (отказ от ответственности: я его автор) . Существует такжеhspec-megaparsec
, если он того стоит. - person Mark Karpov   schedule 22.07.2016parse ... @?= Right ...
вы должны сначала проверить, что результат синтаксического анализа не равенLeft
, а затем сравнить значения напрямую (без предварительного переноса вRight
). Простой способ сделать это в этом случаеeither (const $ assertFailure "...") (@?= (LabelInLabelType ...)) (parse ...)
- person user2407038   schedule 22.07.2016