#directive #testing #regex #output #text-file #variables #pattern

filecheck

用于编写读取文本文件并产生文本输出的实用程序测试的库

7个版本 (破坏性)

0.5.0 2020年3月17日
0.4.0 2018年9月28日
0.3.0 2018年3月20日
0.2.1 2018年3月15日
0.0.1 2016年10月18日

#317 in 文本处理

Download history 1353/week @ 2024-03-14 1686/week @ 2024-03-21 2302/week @ 2024-03-28 2610/week @ 2024-04-04 4204/week @ 2024-04-11 4648/week @ 2024-04-18 3951/week @ 2024-04-25 5368/week @ 2024-05-02 5587/week @ 2024-05-09 11282/week @ 2024-05-16 7196/week @ 2024-05-23 10142/week @ 2024-05-30 9491/week @ 2024-06-06 13118/week @ 2024-06-13 12026/week @ 2024-06-20 11493/week @ 2024-06-27

48,035 每月下载量
用于 21 个crates (4 直接)

Apache-2.0 WITH LLVM-exception

58KB
1K SLoC

这是一个用于编写读取文本文件并产生文本输出的实用程序测试的库。

Build Status

它受LLVM Filecheck的启发,但并不直接兼容。


lib.rs:

此crate提供了一个与LLVM项目FileCheck命令功能相似的文本模式匹配库。

指令列表通常是从包含测试用例的文件中提取的。然后,将测试用例运行在测试程序上,并将输出与指令进行匹配。

有关主要库API,请参阅CheckerBuilderChecker类型。

指令

以下是filecheck识别的指令

 check: <pattern>
 sameln: <pattern>
 nextln: <pattern>
 unordered: <pattern>
 not: <pattern>
 regex: <variable>=<regex>
 

以下将详细介绍每个指令。

示例

下面的Rust程序打印出小于100的素数。它包含了嵌入在注释中的filecheck指令

fn is_prime(x: u32) -> bool {
    (2..x).all(|d| x % d != 0)
}

// Check that we get the primes and nothing else:
//   regex: NUM=\d+
//   not: $NUM
//   check: 2
//   nextln: 3
//   check: 89
//   nextln: 97
//   not: $NUM
fn main() {
    for p in (2..10).filter(|&x| is_prime(x)) {
        println!("{}", p);
    }
}

测试驱动程序编译并运行程序,然后将输出通过filecheck

$ rustc primes.rs
$ ./primes | clif-util filecheck -v
#0 regex: NUM=\d+
#1 not: $NUM
#2 check: 2
#3 nextln: 3
#4 check: 89
#5 nextln: 97
#6 not: $NUM
no match #1: \d+
> 2
  ~
match #2: \b2\b
> 3
  ~
match #3: \b3\b
> 5
> 7
...
> 79
> 83
> 89
  ~~
match #4: \b89\b
> 97
  ~~
match #5: \b97\b
no match #6: \d+
OK

check:指令

匹配非重叠且有序的模式

#0 check: one
#1 check: two

这些指令将匹配字符串"one two",但不匹配"two one"。第二个指令必须在第一个指令之后匹配,并且不能重叠。

sameln:指令

在上一匹配的同一行匹配模式

#0 check: one
#1 sameln: two

这些指令将匹配字符串 "one two",但不匹配 "one\ntwo"。第二个匹配必须在第一个匹配的同一行。类似于 check: 指令,匹配也必须跟在第一个匹配之后,所以 "two one" 不会被匹配。

如果没有前面的匹配,sameln: 将匹配输入的第一行。

nextln: 指令

在前面匹配的下一行匹配一个模式。

#0 check: one
#1 nextln: two

这些指令将匹配字符串 "one\ntwo",但不匹配 "one two""one\n\ntwo"

如果没有前面的匹配,nextln: 将匹配输入的第二行,就像在第一行有一个前面的匹配一样。

unordered: 指令

按任意顺序匹配模式,并且可能相互重叠。

#0 unordered: one
#1 unordered: two

这些指令将匹配字符串 "one two" 和字符串 "two one"

当在 unordered: 指令序列中插入正常顺序匹配时,它作为一个障碍

#0 unordered: one
#1 unordered: two
#2 check: three
#3 unordered: four
#4 unordered: five

这些指令将匹配 "two one three four five",但不匹配 "two three one four five"。不允许 unordered: 匹配跨越有序的 check: 指令。

unordered: 匹配定义和使用变量时,强制执行拓扑顺序。这意味着引用变量的匹配必须跟在定义变量的匹配之后

#0 regex: V=\bv\d+\b
#1 unordered: $(va=$V) = load
#2 unordered: $(vb=$V) = iadd $va
#3 unordered: $(vc=$V) = load
#4 unordered: iadd $va, $vc

在上面的指令中,#2 必须在 #1 之后匹配,#4 必须在 #1 和 #3 之后匹配,但否则它们可以按任何顺序匹配。

not: 指令

检查一个模式 在匹配之间出现。

#0 check: one
#1 not: two
#2 check: three

上述指令将匹配 "one five three",但不匹配 "one two three"

not: 指令中的模式不能定义任何变量。因为它从不匹配任何内容,变量不会获得值。

regex: 指令

为正则表达式定义一个缩写名称。

#0 regex: ID=\b[_a-zA-Z][_0-9a-zA-Z]*\b
#1 check: $ID + $ID

regex: 指令为一个正则表达式命名,然后可以将其用作模式的一部分进行匹配。否则,模式只是用于匹配的普通文本字符串,所以这不是简单的宏展开。

请参阅Rust正则表达式库的语法

模式和变量

模式是在输入文件中要匹配的纯文本字符串。美元符号用作转义字符来展开变量。以下为认可的转义序列:

 $$                Match single dollar sign.
 $()               Match the empty string.
 $(=<regex>)       Match regular expression <regex>.
 $<var>            Match contents of variable <var>.
 $(<var>)          Match contents of variable <var>.
 $(<var>=<regex>)  Match <regex>, then
                   define <var> as the matched text.
 $(<var>=$<rxvar>) Match regex in <rxvar>, then
                   define <var> as the matched text.
 

变量可以包含纯文本或正则表达式。使用前一个指令中的$(var=...)语法定义纯文本变量。它们会再次匹配相同的文本。在同一个模式内不允许使用回溯引用。当在模式中定义了变量,就不能在同一个模式中再次引用它。

正则表达式变量使用regex:指令定义。每次使用时都会匹配正则表达式,因此匹配不必完全相同。

单词边界

如果模式以(纯文本)字母或数字开始或结束,它将只在单词边界上匹配。使用$()空字符串匹配来防止这种情况。

check: one$()

这将匹配"one""onetwo",但不能匹配"zeroone"

空匹配语法也可以用来要求前导或尾随空格。

check: one, $()

这将匹配"one, two",但不能匹配"one,two"。如果没有$(),模式末尾的空格将被移除。

依赖关系

~2.4–4MB
~71K SLoC