diff --git a/examples/commander.yaml b/examples/commander.yaml index 7eafe51f..b826dae5 100644 --- a/examples/commander.yaml +++ b/examples/commander.yaml @@ -28,5 +28,7 @@ tests: it should match file output: command: printf "line one\nline two" + config: + dir: examples/ stdout: - file: ../../examples/_fixtures/output.txt + file: _fixtures/output.txt diff --git a/pkg/matcher/matcher.go b/pkg/matcher/matcher.go index 15d9f3d0..0cb5ce34 100644 --- a/pkg/matcher/matcher.go +++ b/pkg/matcher/matcher.go @@ -2,12 +2,14 @@ package matcher import ( "fmt" - "github.com/antchfx/xmlquery" - "github.com/pmezard/go-difflib/difflib" - "github.com/tidwall/gjson" "io/ioutil" "log" + "path/filepath" "strings" + + "github.com/antchfx/xmlquery" + "github.com/pmezard/go-difflib/difflib" + "github.com/tidwall/gjson" ) const ( @@ -29,7 +31,7 @@ const ( var ReadFile = ioutil.ReadFile // NewMatcher creates a new matcher by type -func NewMatcher(matcher string) Matcher { +func NewMatcher(matcher string, workdir string) Matcher { switch matcher { case Text: return TextMatcher{} @@ -44,7 +46,9 @@ func NewMatcher(matcher string) Matcher { case XML: return XMLMatcher{} case File: - return FileMatcher{} + return FileMatcher{ + workdir: workdir, + } default: panic(fmt.Sprintf("Validator '%s' does not exist!", matcher)) } @@ -252,10 +256,11 @@ to be equal to // FileMatcher matches output captured from stdout or stderr // against the contents of a file type FileMatcher struct { + workdir string } func (m FileMatcher) Match(got interface{}, expected interface{}) MatcherResult { - expectedText, err := ReadFile(expected.(string)) + expectedText, err := ReadFile(filepath.Join(m.workdir, expected.(string))) if err != nil { panic(err.Error()) } diff --git a/pkg/matcher/matcher_test.go b/pkg/matcher/matcher_test.go index d085c0ec..c2a12659 100644 --- a/pkg/matcher/matcher_test.go +++ b/pkg/matcher/matcher_test.go @@ -1,25 +1,33 @@ package matcher import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) func Test_NewMatcher_Text(t *testing.T) { - got := NewMatcher(Text) + got := NewMatcher(Text, "") assert.IsType(t, TextMatcher{}, got) } func Test_NewMatcher_Contains(t *testing.T) { - got := NewMatcher(Contains) + got := NewMatcher(Contains, "") assert.IsType(t, ContainsMatcher{}, got) } func Test_NewMatcher_Equal(t *testing.T) { - got := NewMatcher(Equal) + got := NewMatcher(Equal, "") assert.IsType(t, EqualMatcher{}, got) } +func Test_NewMatcher_File(t *testing.T) { + workdir := "/foo/bar" + got := NewMatcher(File, workdir) + assert.IsType(t, FileMatcher{}, got) + assert.Equal(t, workdir, got.(FileMatcher).workdir) +} + func TestTextMatcher_Validate(t *testing.T) { m := TextMatcher{} got := m.Match("test", "test") @@ -35,7 +43,7 @@ func TestNewMatcher_Fail(t *testing.T) { assert.NotNil(t, r) }() - _ = NewMatcher("no") + _ = NewMatcher("no", "") } func TestTextMatcher_ValidateFails(t *testing.T) { @@ -73,7 +81,7 @@ func TestContainsMatcher_MatchFail(t *testing.T) { } func TestNewMatcher_NotContains(t *testing.T) { - m := NewMatcher(NotContains) + m := NewMatcher(NotContains, "") assert.IsType(t, NotContainsMatcher{}, m) } @@ -125,7 +133,7 @@ func TestXMLMatcher_DoesNotFindPath(t *testing.T) { } func TestXMLMatcher_MatchArray(t *testing.T) { - m := NewMatcher(XML) + m := NewMatcher(XML, "") html := "test1test2" r := m.Match(html, map[string]string{"/books": "test1test2"}) @@ -169,7 +177,7 @@ func TestJSONMatcher_MatchArray(t *testing.T) { } func TestJSONMatcher_DoesNotMatch(t *testing.T) { - m := NewMatcher(JSON) + m := NewMatcher(JSON, "") r := m.Match(`{"book": "another"}`, map[string]string{"book": "test"}) diff := `Expected json path "book" with result diff --git a/pkg/runtime/validator.go b/pkg/runtime/validator.go index 0c712ded..651e4ef9 100644 --- a/pkg/runtime/validator.go +++ b/pkg/runtime/validator.go @@ -2,9 +2,10 @@ package runtime import ( "fmt" - "github.com/commander-cli/commander/pkg/matcher" "log" "strings" + + "github.com/commander-cli/commander/pkg/matcher" ) // ValidationResult will be returned after the validation was executed @@ -23,10 +24,10 @@ func newValidationResult(m matcher.MatcherResult) ValidationResult { // Validate validates the test results with the expected values // The test should hold the result and expected to validate the result func Validate(test TestCase) TestResult { - equalMatcher := matcher.NewMatcher(matcher.Equal) + equalMatcher := matcher.NewMatcher(matcher.Equal, "") log.Println("title: '"+test.Title+"'", " Stdout-Expected: ", test.Expected.Stdout) - matcherResult := validateExpectedOut(test.Result.Stdout, test.Expected.Stdout) + matcherResult := validateExpectedOut(test.Result.Stdout, test.Expected.Stdout, test.Command.Dir) log.Println("title: '"+test.Title+"'", " Stdout-Result: ", matcherResult.Success) if !matcherResult.Success { return TestResult{ @@ -37,7 +38,7 @@ func Validate(test TestCase) TestResult { } log.Println("title: '"+test.Title+"'", " Stderr-Expected: ", test.Expected.Stderr) - matcherResult = validateExpectedOut(test.Result.Stderr, test.Expected.Stderr) + matcherResult = validateExpectedOut(test.Result.Stderr, test.Expected.Stderr, test.Command.Dir) log.Println("title: '"+test.Title+"'", " Stderr-Result: ", matcherResult.Success) if !matcherResult.Success { return TestResult{ @@ -64,19 +65,19 @@ func Validate(test TestCase) TestResult { } } -func validateExpectedOut(got string, expected ExpectedOut) matcher.MatcherResult { +func validateExpectedOut(got string, expected ExpectedOut, workdir string) matcher.MatcherResult { var m matcher.Matcher var result matcher.MatcherResult result.Success = true if expected.Exactly != "" { - m = matcher.NewMatcher(matcher.Text) + m = matcher.NewMatcher(matcher.Text, "") if result = m.Match(got, expected.Exactly); !result.Success { return result } } - m = matcher.NewMatcher(matcher.Contains) + m = matcher.NewMatcher(matcher.Contains, "") for _, c := range expected.Contains { if result = m.Match(got, c); !result.Success { return result @@ -97,21 +98,21 @@ func validateExpectedOut(got string, expected ExpectedOut) matcher.MatcherResult } } - m = matcher.NewMatcher(matcher.NotContains) + m = matcher.NewMatcher(matcher.NotContains, "") for _, c := range expected.NotContains { if result = m.Match(got, c); !result.Success { return result } } - m = matcher.NewMatcher(matcher.JSON) + m = matcher.NewMatcher(matcher.JSON, "") for i, v := range expected.JSON { if result = m.Match(got, map[string]string{i: v}); !result.Success { return result } } - m = matcher.NewMatcher(matcher.XML) + m = matcher.NewMatcher(matcher.XML, "") for i, v := range expected.XML { if result = m.Match(got, map[string]string{i: v}); !result.Success { return result @@ -119,7 +120,7 @@ func validateExpectedOut(got string, expected ExpectedOut) matcher.MatcherResult } if expected.File != "" { - m = matcher.NewMatcher(matcher.File) + m = matcher.NewMatcher(matcher.File, workdir) if result = m.Match(got, expected.File); !result.Success { return result } @@ -129,7 +130,7 @@ func validateExpectedOut(got string, expected ExpectedOut) matcher.MatcherResult } func validateExpectedLineCount(got string, expected ExpectedOut) matcher.MatcherResult { - m := matcher.NewMatcher(matcher.Equal) + m := matcher.NewMatcher(matcher.Equal, "") count := strings.Count(got, getLineBreak()) + 1 if got == "" { @@ -140,7 +141,7 @@ func validateExpectedLineCount(got string, expected ExpectedOut) matcher.Matcher } func validateExpectedLines(got string, expected ExpectedOut) matcher.MatcherResult { - m := matcher.NewMatcher(matcher.Equal) + m := matcher.NewMatcher(matcher.Equal, "") actualLines := strings.Split(got, getLineBreak()) result := matcher.MatcherResult{Success: true} diff --git a/pkg/runtime/validator_test.go b/pkg/runtime/validator_test.go index fc632812..9926dd32 100644 --- a/pkg/runtime/validator_test.go +++ b/pkg/runtime/validator_test.go @@ -1,10 +1,11 @@ package runtime import ( - "github.com/commander-cli/commander/pkg/matcher" - "github.com/stretchr/testify/assert" "io/ioutil" "testing" + + "github.com/commander-cli/commander/pkg/matcher" + "github.com/stretchr/testify/assert" ) func TestNewValidationResult(t *testing.T) { @@ -67,7 +68,7 @@ func Test_ValidateExitCodeShouldFail(t *testing.T) { func Test_ValidateExpectedOut_Contains_Fails(t *testing.T) { value := `test` - got := validateExpectedOut(value, ExpectedOut{Contains: []string{"not-exists"}}) + got := validateExpectedOut(value, ExpectedOut{Contains: []string{"not-exists"}}, "") diff := ` Expected @@ -89,7 +90,7 @@ multi line output` - got := validateExpectedOut(value, ExpectedOut{Lines: map[int]string{1: "my", 3: "line"}}) + got := validateExpectedOut(value, ExpectedOut{Lines: map[int]string{1: "my", 3: "line"}}, "") assert.True(t, got.Success) assert.Empty(t, got.Diff) @@ -98,7 +99,7 @@ output` func Test_ValidateExpectedOut_MatchLines_ExpectedLineDoesNotExists(t *testing.T) { value := `test` - got := validateExpectedOut(value, ExpectedOut{Lines: map[int]string{2: "my"}}) + got := validateExpectedOut(value, ExpectedOut{Lines: map[int]string{2: "my"}}, "") assert.False(t, got.Success) diff := `Line number 2 does not exists in result: @@ -112,7 +113,7 @@ func Test_ValidateExpectedOut_MatchLines_Fails(t *testing.T) { line 2 line 3` - got := validateExpectedOut(value, ExpectedOut{Lines: map[int]string{2: "line 3"}}) + got := validateExpectedOut(value, ExpectedOut{Lines: map[int]string{2: "line 3"}}, "") assert.False(t, got.Success) diff := `--- Got @@ -127,7 +128,7 @@ line 3` func Test_ValidateExpectedOut_LineCount_Fails(t *testing.T) { value := `` - got := validateExpectedOut(value, ExpectedOut{LineCount: 2}) + got := validateExpectedOut(value, ExpectedOut{LineCount: 2}, "") assert.False(t, got.Success) diff := `--- Got @@ -142,7 +143,7 @@ func Test_ValidateExpectedOut_LineCount_Fails(t *testing.T) { func Test_ValidateExpectedOut_NotContains_Fails(t *testing.T) { value := `my string contains` - got := validateExpectedOut(value, ExpectedOut{NotContains: []string{"contains"}}) + got := validateExpectedOut(value, ExpectedOut{NotContains: []string{"contains"}}, "") diff := ` Expected @@ -167,7 +168,7 @@ func Test_ValidateExpectedOut_PanicIfLineDoesNotExist(t *testing.T) { }() value := `my` - _ = validateExpectedOut(value, ExpectedOut{Lines: map[int]string{0: "my"}}) + _ = validateExpectedOut(value, ExpectedOut{Lines: map[int]string{0: "my"}}, "") } func Test_ValidateExpectedOut_ValidateJSON(t *testing.T) { @@ -178,7 +179,7 @@ func Test_ValidateExpectedOut_ValidateJSON(t *testing.T) { } } ` - r := validateExpectedOut(json, ExpectedOut{JSON: map[string]string{"object.attr": "test"}}) + r := validateExpectedOut(json, ExpectedOut{JSON: map[string]string{"object.attr": "test"}}, "") assert.True(t, r.Success) diff := `Expected json path "object.attr" with result @@ -188,7 +189,7 @@ no to be equal to test` - r = validateExpectedOut(json, ExpectedOut{JSON: map[string]string{"object.attr": "no"}}) + r = validateExpectedOut(json, ExpectedOut{JSON: map[string]string{"object.attr": "no"}}, "") assert.False(t, r.Success) assert.Equal(t, diff, r.Diff) } @@ -198,7 +199,7 @@ func Test_ValidateExpectedOut_ValidateFile(t *testing.T) { matcher.ReadFile = func(filename string) ([]byte, error) { return []byte(content), nil } - r := validateExpectedOut(content, ExpectedOut{File: "fake.txt"}) + r := validateExpectedOut(content, ExpectedOut{File: "fake.txt"}, "") assert.True(t, r.Success) assert.Equal(t, "", r.Diff) @@ -209,7 +210,7 @@ func Test_ValidateExpectedOut_ValidateFile(t *testing.T) { -line two ` - r = validateExpectedOut(content+"\nline two", ExpectedOut{File: "fake.txt"}) + r = validateExpectedOut(content+"\nline two", ExpectedOut{File: "fake.txt"}, "") assert.False(t, r.Success) assert.Equal(t, diff, r.Diff) @@ -221,7 +222,7 @@ func Test_ValidateExpectedOut_ValidateXML(t *testing.T) { J. R. R. Tolkien ` - r := validateExpectedOut(xml, ExpectedOut{XML: map[string]string{"/book//author": "J. R. R. Tolkien"}}) + r := validateExpectedOut(xml, ExpectedOut{XML: map[string]string{"/book//author": "J. R. R. Tolkien"}}, "") assert.True(t, r.Success) assert.Equal(t, "", r.Diff) @@ -232,11 +233,11 @@ Joanne K. Rowling to be equal to J. R. R. Tolkien` - r = validateExpectedOut(xml, ExpectedOut{XML: map[string]string{"/book//author": "Joanne K. Rowling"}}) + r = validateExpectedOut(xml, ExpectedOut{XML: map[string]string{"/book//author": "Joanne K. Rowling"}}, "") assert.False(t, r.Success) assert.Equal(t, diff, r.Diff) - r = validateExpectedOut(xml, ExpectedOut{XML: map[string]string{"/book//title": "J. R. R. Tolkien"}}) + r = validateExpectedOut(xml, ExpectedOut{XML: map[string]string{"/book//title": "J. R. R. Tolkien"}}, "") assert.False(t, r.Success) assert.Equal(t, `Query "/book//title" did not match a path`, r.Diff) }