Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for regular expression matching with the matches: operator. #79

Merged
merged 10 commits into from
Nov 18, 2022
6 changes: 6 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ jobs:
run: "choco install --yes --no-progress haskell-stack"
- name: Install Haskell
run: "stack --no-terminal setup"
- name: Update MSYS2
run: "stack --no-terminal exec -- pacman --noconfirm -Syuu"
- name: Install pkgconfig
run: "stack --no-terminal exec -- pacman --noconfirm -S mingw-w64-x86_64-pkg-config"
- name: Install ICU
run: "stack --no-terminal exec -- pacman --noconfirm -S mingw-w64-x86_64-icu"
- name: Build for release
run: 'stack --no-terminal install --local-bin-path=.\out\build\release'
- id: asset
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,18 @@ jobs:
run: "choco install --yes --no-progress haskell-stack"
- name: Install Haskell
run: "stack --no-terminal setup"
- name: Update MSYS2
run: "stack --no-terminal exec -- pacman --noconfirm -Syuu"
- name: Install pkgconfig
run: "stack --no-terminal exec -- pacman --noconfirm -S mingw-w64-x86_64-pkg-config"
- name: Install ICU
run: "stack --no-terminal exec -- pacman --noconfirm -S mingw-w64-x86_64-icu"
- name: Build
run: 'stack --no-terminal install --fast --test --no-run-tests --local-bin-path=.\out\build\debug'
- name: Test
run: "stack --no-terminal test"
- name: Spec
run: '.\out\build\debug\smoke.exe --command=.\out\build\debug\smoke.exe spec'
run: 'stack --no-terminal exec -- .\out\build\debug\smoke.exe --command=.\out\build\debug\smoke.exe spec'

lint:
name: Lint
Expand Down
30 changes: 30 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ tests:
-2
```

### Matchers

We don't always want to check the full output; sometimes checking that it contains a given substring is more useful. We can use the `contains:` operator to specify this:

```yaml
Expand All @@ -134,6 +136,34 @@ tests:

Note that we don't use `|` here, as we don't want to capture the trailing newline, which would make this test fail. Instead we use quotes around the value to ensure that the YAML parser treats it as a string, not a number.

Or we can use a regular expression with the `matches:` operator:

```yaml
tests:
- name: lorem ipsum
stdout:
matches: |-
^Lorem ipsum .* dolore magna aliqua\.$
```

Here we're using `|-` to similar effect; the `-` means "don't add a trailing newline". Unlike quotes, it doesn't interpret escape sequences (such as `\n`), so we can use `\` without trouble.

You may want to provide options to the regular expression. The currently-supported options are `case-insensitive` (`i`), `comments` (`x`), and `dot-all` (`s`). You can add them as follows:

```yaml
tests:
- name: lorem ipsum
stdout:
matches:
regex: |-
Lorem ipsum .* fugiat nulla pariatur\.
options:
- case-insensitive
- dot-all
```

The variant of regular expressions supported is from the ICU library; see [the ICU documentation on Regular Expressions](https://unicode-org.github.io/icu/userguide/strings/regexp.html) for syntax and functionality, including how the options work.

You can also use `equals:` to explicitly specify that we're checking equality, though this is the default.

We can use files to specify the STDIN, STDOUT or STDERR values:
Expand Down
18 changes: 18 additions & 0 deletions fixtures/bottles/smoke.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,21 @@ tests:
contents:
contains: |
9 bottles of beer on the wall, 9 bottles of beer.

- name: "10-matches"
args:
- "10"
stdout:
matches: 5 bottles .* 5 bottles

- name: "10000-matches"
args:
- "10000"
stdout:
matches: 6543 bottles .* 6543 bottles

- name: "10-does-not-match-multiple-lines"
args:
- "10"
stdout:
matches: 4 bottles .* 2 bottles
4 changes: 4 additions & 0 deletions fixtures/encrypter/io/lorem-ipsum.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
66 changes: 66 additions & 0 deletions fixtures/encrypter/regex.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
command:
- ruby
- fixtures/encrypter.rb

tests:
- name: simple
stdin:
file: io/lorem-ipsum.in
stdout:
matches: |-
dhvf abfgehq rkrepvgngvba hyynzpb ynobevf

- name: case-sensitive
stdin:
file: io/lorem-ipsum.in
stdout:
matches: |-
yberz vcfhz

- name: case-insensitive
stdin:
file: io/lorem-ipsum.in
stdout:
matches:
regex: |-
yberz vcfhz
options:
- case-insensitive

- name: erroneous-comments
stdin:
file: io/lorem-ipsum.in
stdout:
matches:
regex: |
Yberz # Lorem
\ vcfhz # ipsum
options: []

- name: comments
stdin:
file: io/lorem-ipsum.in
stdout:
matches:
regex: |-
Yberz # Lorem
\ vcfhz # ipsum
options:
- comments

- name: dot-without-dot-all
stdin:
file: io/lorem-ipsum.in
stdout:
matches: |-
Yberz vcfhz qbybe fvg nzrg, .* fhag va phycn dhv bssvpvn qrfrehag zbyyvg navz vq rfg ynobehz\.

- name: dot-with-dot-all
stdin:
file: io/lorem-ipsum.in
stdout:
matches:
regex: |-
Yberz vcfhz qbybe fvg nzrg, .* fhag va phycn dhv bssvpvn qrfrehag zbyyvg navz vq rfg ynobehz\.
options:
- dot-all
File renamed without changes.
2 changes: 0 additions & 2 deletions hie.yaml

This file was deleted.

1 change: 1 addition & 0 deletions nix/libs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ let
in
[
gmp6
pkgs.icu
libiconv
openssl
zlib
Expand Down
1 change: 1 addition & 0 deletions package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ dependencies:
- tar
- temporary
- text
- text-icu
- transformers
- vector
- yaml
Expand Down
16 changes: 13 additions & 3 deletions spec/bless.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
tests:
- name: encrypter
- name: encrypter-simple
args:
- --bless
- fixtures/encrypter
- fixtures/encrypter/simple.yaml
exit-status: 0
stdout:
file: io/encrypter-bless-success.out
file: io/encrypter-simple-bless-success.out
revert:
- ../fixtures/encrypter

- name: encrypter-regex
args:
- --bless
- fixtures/encrypter/regex.yaml
exit-status: 1
stdout:
file: io/encrypter-regex-bless-failure.out
revert:
- ../fixtures/encrypter

Expand Down
31 changes: 30 additions & 1 deletion spec/io/bottles-bless-failure.out
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,34 @@ broken
Go to the store and buy some more, 10 bottles of beer on the wall.
10-contents-contains
succeeded
10-matches
succeeded
10000-matches
succeeded
10-does-not-match-multiple-lines
The fixture "stdout" is matching a pattern, so the result cannot be blessed.
Actual value:
10 bottles of beer on the wall, 10 bottles of beer.
Take one down and pass it around, 9 bottles of beer on the wall.
9 bottles of beer on the wall, 9 bottles of beer.
Take one down and pass it around, 8 bottles of beer on the wall.
8 bottles of beer on the wall, 8 bottles of beer.
Take one down and pass it around, 7 bottles of beer on the wall.
7 bottles of beer on the wall, 7 bottles of beer.
Take one down and pass it around, 6 bottles of beer on the wall.
6 bottles of beer on the wall, 6 bottles of beer.
Take one down and pass it around, 5 bottles of beer on the wall.
5 bottles of beer on the wall, 5 bottles of beer.
Take one down and pass it around, 4 bottles of beer on the wall.
4 bottles of beer on the wall, 4 bottles of beer.
Take one down and pass it around, 3 bottles of beer on the wall.
3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.
2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.
1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 10 bottles of beer on the wall.

7 tests, 1 failure
10 tests, 2 failures
31 changes: 31 additions & 0 deletions spec/io/encrypter-regex-bless-failure.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
simple
succeeded
case-sensitive
The fixture "stdout" is matching a pattern, so the result cannot be blessed.
Actual value:
Yberz vcfhz qbybe fvg nzrg, pbafrpgrghe nqvcvfpvat ryvg, frq qb rvhfzbq grzcbe vapvqvqhag hg ynober rg qbyber zntan nyvdhn.
Hg ravz nq zvavz iravnz, dhvf abfgehq rkrepvgngvba hyynzpb ynobevf avfv hg nyvdhvc rk rn pbzzbqb pbafrdhng.
Qhvf nhgr veher qbybe va erceruraqrevg va ibyhcgngr iryvg rffr pvyyhz qbyber rh shtvng ahyyn cnevnghe.
Rkprcgrhe fvag bppnrpng phcvqngng aba cebvqrag, fhag va phycn dhv bssvpvn qrfrehag zbyyvg navz vq rfg ynobehz.
case-insensitive
succeeded
erroneous-comments
The fixture "stdout" is matching a pattern, so the result cannot be blessed.
Actual value:
Yberz vcfhz qbybe fvg nzrg, pbafrpgrghe nqvcvfpvat ryvg, frq qb rvhfzbq grzcbe vapvqvqhag hg ynober rg qbyber zntan nyvdhn.
Hg ravz nq zvavz iravnz, dhvf abfgehq rkrepvgngvba hyynzpb ynobevf avfv hg nyvdhvc rk rn pbzzbqb pbafrdhng.
Qhvf nhgr veher qbybe va erceruraqrevg va ibyhcgngr iryvg rffr pvyyhz qbyber rh shtvng ahyyn cnevnghe.
Rkprcgrhe fvag bppnrpng phcvqngng aba cebvqrag, fhag va phycn dhv bssvpvn qrfrehag zbyyvg navz vq rfg ynobehz.
comments
succeeded
dot-without-dot-all
The fixture "stdout" is matching a pattern, so the result cannot be blessed.
Actual value:
Yberz vcfhz qbybe fvg nzrg, pbafrpgrghe nqvcvfpvat ryvg, frq qb rvhfzbq grzcbe vapvqvqhag hg ynober rg qbyber zntan nyvdhn.
Hg ravz nq zvavz iravnz, dhvf abfgehq rkrepvgngvba hyynzpb ynobevf avfv hg nyvdhvc rk rn pbzzbqb pbafrdhng.
Qhvf nhgr veher qbybe va erceruraqrevg va ibyhcgngr iryvg rffr pvyyhz qbyber rh shtvng ahyyn cnevnghe.
Rkprcgrhe fvag bppnrpng phcvqngng aba cebvqrag, fhag va phycn dhv bssvpvn qrfrehag zbyyvg navz vq rfg ynobehz.
dot-with-dot-all
succeeded

7 tests, 3 failures
53 changes: 49 additions & 4 deletions spec/io/encrypter.out
Original file line number Diff line number Diff line change
@@ -1,9 +1,54 @@
word
regex/simple
succeeded
regex/case-sensitive
stdin: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
stdout:
expected to match:
yberz vcfhz
actual: Yberz vcfhz qbybe fvg nzrg, pbafrpgrghe nqvcvfpvat ryvg, frq qb rvhfzbq grzcbe vapvqvqhag hg ynober rg qbyber zntan nyvdhn.
Hg ravz nq zvavz iravnz, dhvf abfgehq rkrepvgngvba hyynzpb ynobevf avfv hg nyvdhvc rk rn pbzzbqb pbafrdhng.
Qhvf nhgr veher qbybe va erceruraqrevg va ibyhcgngr iryvg rffr pvyyhz qbyber rh shtvng ahyyn cnevnghe.
Rkprcgrhe fvag bppnrpng phcvqngng aba cebvqrag, fhag va phycn dhv bssvpvn qrfrehag zbyyvg navz vq rfg ynobehz.
regex/case-insensitive
succeeded
regex/erroneous-comments
stdin: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
stdout:
expected to match:
Yberz # Lorem
\ vcfhz # ipsum
actual: Yberz vcfhz qbybe fvg nzrg, pbafrpgrghe nqvcvfpvat ryvg, frq qb rvhfzbq grzcbe vapvqvqhag hg ynober rg qbyber zntan nyvdhn.
Hg ravz nq zvavz iravnz, dhvf abfgehq rkrepvgngvba hyynzpb ynobevf avfv hg nyvdhvc rk rn pbzzbqb pbafrdhng.
Qhvf nhgr veher qbybe va erceruraqrevg va ibyhcgngr iryvg rffr pvyyhz qbyber rh shtvng ahyyn cnevnghe.
Rkprcgrhe fvag bppnrpng phcvqngng aba cebvqrag, fhag va phycn dhv bssvpvn qrfrehag zbyyvg navz vq rfg ynobehz.
regex/comments
succeeded
regex/dot-without-dot-all
stdin: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
stdout:
expected to match:
Yberz vcfhz qbybe fvg nzrg, .* fhag va phycn dhv bssvpvn qrfrehag zbyyvg navz vq rfg ynobehz\.
actual: Yberz vcfhz qbybe fvg nzrg, pbafrpgrghe nqvcvfpvat ryvg, frq qb rvhfzbq grzcbe vapvqvqhag hg ynober rg qbyber zntan nyvdhn.
Hg ravz nq zvavz iravnz, dhvf abfgehq rkrepvgngvba hyynzpb ynobevf avfv hg nyvdhvc rk rn pbzzbqb pbafrdhng.
Qhvf nhgr veher qbybe va erceruraqrevg va ibyhcgngr iryvg rffr pvyyhz qbyber rh shtvng ahyyn cnevnghe.
Rkprcgrhe fvag bppnrpng phcvqngng aba cebvqrag, fhag va phycn dhv bssvpvn qrfrehag zbyyvg navz vq rfg ynobehz.
regex/dot-with-dot-all
succeeded
simple/word
stdin: word
stdout: @@ -1 +1 @@
-xpse
+jbeq
lines
simple/lines
stdin: one
two
three
Expand All @@ -17,10 +62,10 @@ lines
+gjb
+guerr
+sbhe
color
simple/color
stdin: this is a green word
stdout: @@ -1 +1 @@
-uijt jt b hsffo xpse
+guvf vf n terra jbeq

3 tests, 3 failures
10 tests, 6 failures
33 changes: 32 additions & 1 deletion spec/io/long-output.out
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,36 @@ broken
Go to the store and buy some more, 10 bottles of beer on the wall.
10-contents-contains
succeeded
10-matches
succeeded
10000-matches
succeeded
10-does-not-match-multiple-lines
args: 10
stdout:
expected to match:
4 bottles .* 2 bottles
actual: 10 bottles of beer on the wall, 10 bottles of beer.
Take one down and pass it around, 9 bottles of beer on the wall.
9 bottles of beer on the wall, 9 bottles of beer.
Take one down and pass it around, 8 bottles of beer on the wall.
8 bottles of beer on the wall, 8 bottles of beer.
Take one down and pass it around, 7 bottles of beer on the wall.
7 bottles of beer on the wall, 7 bottles of beer.
Take one down and pass it around, 6 bottles of beer on the wall.
6 bottles of beer on the wall, 6 bottles of beer.
Take one down and pass it around, 5 bottles of beer on the wall.
5 bottles of beer on the wall, 5 bottles of beer.
Take one down and pass it around, 4 bottles of beer on the wall.
4 bottles of beer on the wall, 4 bottles of beer.
Take one down and pass it around, 3 bottles of beer on the wall.
3 bottles of beer on the wall, 3 bottles of beer.
Take one down and pass it around, 2 bottles of beer on the wall.
2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.
1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 10 bottles of beer on the wall.

7 tests, 2 failures
10 tests, 3 failures
Loading