Skip to content

Commit 10db468

Browse files
authored
Merge pull request #147 from glesica/add-file-assertion
Add file assertion
2 parents 75391aa + 571c5e4 commit 10db468

File tree

15 files changed

+150
-8
lines changed

15 files changed

+150
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
- Add ability to test suite from a url
44
- Add ability to test suite from stdin
5+
- Add `file` assertion to `stdout` and `stderr`
56

67
# v2.3.0
78

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ For more information take a look at the [quick start](#quick-start), the [exampl
4040
* [line-count](#line-count)
4141
* [not-contains](#not-contains)
4242
* [xml](#xml)
43+
* [file](#file)
4344
- [stderr](#stderr)
4445
- [skip](#skip)
4546
+ [Config](#user-content-config-config)
@@ -167,6 +168,7 @@ tests:
167168
object.attr: hello # Make assertions on json objects
168169
xml:
169170
"//book//auhtor": Steven King # Make assertions on xml documents
171+
file: correct-output.txt
170172
exit-code: 127
171173
skip: false
172174

@@ -529,6 +531,21 @@ cat some.xml:
529531
</book>
530532
```
531533

534+
##### file
535+
536+
`file` is a file path, relative to the working directory that will have
537+
its entire contents matched against the command output. Other than
538+
reading from a file this works the same as [exactly](#exactly).
539+
540+
The example below will always pass.
541+
542+
```yaml
543+
output should match file:
544+
command: cat output.txt
545+
stdout:
546+
file: output.txt
547+
```
548+
532549
#### stderr
533550

534551
See [stdout](#stdout) for more information.

commander_unix.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,18 @@ tests:
1616
contains:
1717
- ✓ [local] it should exit with error code
1818
- "- [local] it should skip, was skipped"
19-
line-count: 17
19+
line-count: 19
2020
exit-code: 0
2121

2222
it should assert that commander will fail:
2323
command: ./commander test ./integration/unix/failing_suite.yaml
2424
stdout:
2525
contains:
26+
- ✗ [local] 'file matcher should fail when file and output are different', on property 'Stdout'
2627
- ✗ [local] 'it will fail', on property 'ExitCode'
2728
- ✗ [local] 'test timeout' could not be executed with error message
2829
- Command timed out after 10ms
29-
- "Count: 2, Failed: 2"
30+
- "Count: 3, Failed: 3"
3031
exit-code: 1
3132

3233
it should validate a big output:

examples/_fixtures/output.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
line one
2+
line two

examples/commander.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,9 @@ tests:
2424
it should skip:
2525
command: echo "I should be skipped"
2626
stdout: I should be skipped
27-
skip: true
27+
skip: true
28+
29+
it should match file output:
30+
command: printf "line one\nline two"
31+
stdout:
32+
file: ../../examples/_fixtures/output.txt
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
first line
2+
second line
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
first line
2+
second line
3+
third line

integration/unix/commander_test.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ tests:
5959
/books/0/author: J. R. R. Tokien
6060
/books/1/author: Joanne K. Rowling
6161

62+
it should assert file contents on stdout:
63+
command: cat ./integration/unix/_fixtures/big_out.txt
64+
stdout:
65+
file: ./integration/unix/_fixtures/big_out.txt
66+
67+
it should assert file contents on stderr:
68+
command: cat ./integration/unix/_fixtures/big_out.txt >&2
69+
stderr:
70+
file: ./integration/unix/_fixtures/big_out.txt
71+
6272
it should inherit from parent env:
6373
config:
6474
inherit-env: true

integration/unix/failing_suite.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,9 @@ tests:
77
command: sleep 1
88
config:
99
timeout: 10ms
10-
exit-code: 0
10+
exit-code: 0
11+
12+
file matcher should fail when file and output are different:
13+
command: cat ./integration/unix/_fixtures/file_output_1.txt
14+
stdout:
15+
file: ./integration/unix/_fixtures/file_output_0.txt

pkg/matcher/matcher.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"github.com/antchfx/xmlquery"
66
"github.com/pmezard/go-difflib/difflib"
77
"github.com/tidwall/gjson"
8+
"io/ioutil"
89
"log"
910
"strings"
1011
)
@@ -20,8 +21,13 @@ const (
2021
NotContains = "notcontains"
2122
JSON = "json"
2223
XML = "xml"
24+
File = "file"
2325
)
2426

27+
// The function used to open files when necessary for matching
28+
// Allows the file IO to be overridden during tests
29+
var ReadFile = ioutil.ReadFile
30+
2531
// NewMatcher creates a new matcher by type
2632
func NewMatcher(matcher string) Matcher {
2733
switch matcher {
@@ -37,6 +43,8 @@ func NewMatcher(matcher string) Matcher {
3743
return JSONMatcher{}
3844
case XML:
3945
return XMLMatcher{}
46+
case File:
47+
return FileMatcher{}
4048
default:
4149
panic(fmt.Sprintf("Validator '%s' does not exist!", matcher))
4250
}
@@ -240,3 +248,32 @@ to be equal to
240248

241249
return result
242250
}
251+
252+
// FileMatcher matches output captured from stdout or stderr
253+
// against the contents of a file
254+
type FileMatcher struct {
255+
}
256+
257+
func (m FileMatcher) Match(got interface{}, expected interface{}) MatcherResult {
258+
expectedText, err := ReadFile(expected.(string))
259+
if err != nil {
260+
panic(err.Error())
261+
}
262+
expectedString := string(expectedText)
263+
264+
result := got == expectedString
265+
266+
diff := difflib.UnifiedDiff{
267+
A: difflib.SplitLines(got.(string)),
268+
B: difflib.SplitLines(expectedString),
269+
FromFile: "Got",
270+
ToFile: "Expected",
271+
Context: 3,
272+
}
273+
diffText, _ := difflib.GetUnifiedDiffString(diff)
274+
275+
return MatcherResult{
276+
Diff: diffText,
277+
Success: result,
278+
}
279+
}

0 commit comments

Comments
 (0)