3

我正在为我的解析器编写测试,使用的方法可能不是最好的,但到目前为止一直在为我工作。测试假设每个代码块都完美定义了 AST 表示,如下所示:

(parse "x = 5") `shouldBe` (Block [Assignment [LVar "x"] [Number 5.0]])

然而,当我转向更复杂的案例时,需要进行更“模糊”的验证:

(parse "t.x = 5") `shouldBe` (Block [Assignment [LFieldRef (Var "t") (StringLiteral undefined "x")] [Number 5.0]])

undefined在这个示例中放入了我不想与解析结果进行比较的字段(它是字符串文字的源位置)。现在我看到的唯一修复方法是重写代码以使用shouldSatisfy而不是shouldBe,如果我找不到任何其他解决方案,我将不得不这样做。

4

2 回答 2

1

您可以编写一个normalizePosition函数,用某个固定值替换 AST 中的所有位置数据dummyPosition,然后shouldBe针对从相同虚拟值构建的模式使用。

如果 AST 非常复杂,请考虑使用 Scrap-Your-Boilerplate 编写此规范化。

于 2014-09-17T12:19:38.917 回答
0

解决此问题的一种方法是对源位置的 AST 进行参数化:

{-# LANGUAGE DeriveFunctor #-}

data AST a = ...
  deriving (Eq, Show, Functor)

然后,您的parse函数将返回ASTwith SourceLocations

parse :: String -> AST SourceLocation

当我们在上面导出一个Functor实例时,我们可以很容易地用其他东西替换源位置,例如()

import Data.Functor ((<$))

parseTest :: String -> AST ()
parseTest input = () <$ parse input

现在,只需在您的规格中使用parseTest而不是。parse

于 2014-11-01T05:09:14.180 回答