1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- package matchers
- import (
- "fmt"
- "strings"
- "github.com/onsi/gomega/format"
- "gopkg.in/yaml.v2"
- )
- type MatchYAMLMatcher struct {
- YAMLToMatch interface{}
- firstFailurePath []interface{}
- }
- func (matcher *MatchYAMLMatcher) Match(actual interface{}) (success bool, err error) {
- actualString, expectedString, err := matcher.toStrings(actual)
- if err != nil {
- return false, err
- }
- var aval interface{}
- var eval interface{}
- if err := yaml.Unmarshal([]byte(actualString), &aval); err != nil {
- return false, fmt.Errorf("Actual '%s' should be valid YAML, but it is not.\nUnderlying error:%s", actualString, err)
- }
- if err := yaml.Unmarshal([]byte(expectedString), &eval); err != nil {
- return false, fmt.Errorf("Expected '%s' should be valid YAML, but it is not.\nUnderlying error:%s", expectedString, err)
- }
- var equal bool
- equal, matcher.firstFailurePath = deepEqual(aval, eval)
- return equal, nil
- }
- func (matcher *MatchYAMLMatcher) FailureMessage(actual interface{}) (message string) {
- actualString, expectedString, _ := matcher.toNormalisedStrings(actual)
- return formattedMessage(format.Message(actualString, "to match YAML of", expectedString), matcher.firstFailurePath)
- }
- func (matcher *MatchYAMLMatcher) NegatedFailureMessage(actual interface{}) (message string) {
- actualString, expectedString, _ := matcher.toNormalisedStrings(actual)
- return formattedMessage(format.Message(actualString, "not to match YAML of", expectedString), matcher.firstFailurePath)
- }
- func (matcher *MatchYAMLMatcher) toNormalisedStrings(actual interface{}) (actualFormatted, expectedFormatted string, err error) {
- actualString, expectedString, err := matcher.toStrings(actual)
- return normalise(actualString), normalise(expectedString), err
- }
- func normalise(input string) string {
- var val interface{}
- err := yaml.Unmarshal([]byte(input), &val)
- if err != nil {
- panic(err) // unreachable since Match already calls Unmarshal
- }
- output, err := yaml.Marshal(val)
- if err != nil {
- panic(err) // untested section, unreachable since we Unmarshal above
- }
- return strings.TrimSpace(string(output))
- }
- func (matcher *MatchYAMLMatcher) toStrings(actual interface{}) (actualFormatted, expectedFormatted string, err error) {
- actualString, ok := toString(actual)
- if !ok {
- return "", "", fmt.Errorf("MatchYAMLMatcher matcher requires a string, stringer, or []byte. Got actual:\n%s", format.Object(actual, 1))
- }
- expectedString, ok := toString(matcher.YAMLToMatch)
- if !ok {
- return "", "", fmt.Errorf("MatchYAMLMatcher matcher requires a string, stringer, or []byte. Got expected:\n%s", format.Object(matcher.YAMLToMatch, 1))
- }
- return actualString, expectedString, nil
- }
|