github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/cf/util/testhelpers/matchers/be_in_display_order.go (about)

     1  package matchers
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"code.cloudfoundry.org/cli/cf/terminal"
     8  	"github.com/onsi/gomega"
     9  )
    10  
    11  type OrderMatcher struct {
    12  	expected   [][]string
    13  	failedText string
    14  }
    15  
    16  func BeInDisplayOrder(substrings ...[]string) gomega.OmegaMatcher {
    17  	return &OrderMatcher{
    18  		expected: substrings,
    19  	}
    20  }
    21  
    22  func (matcher *OrderMatcher) Match(actualStr interface{}) (success bool, err error) {
    23  	actual, ok := actualStr.([]string)
    24  	if !ok {
    25  		return false, nil
    26  	}
    27  
    28  	//loop and match, stop at last actual[0] line
    29  	for len(actual) > 1 {
    30  		if matched, msg := matchSingleLine(actual[0], matcher.expected[0]); matched {
    31  			if len(matcher.expected) == 1 {
    32  				return true, nil //no more expected to match, all passed
    33  			}
    34  			matcher.expected = matcher.expected[1:]
    35  		} else if msg != "" {
    36  			matcher.failedText = msg
    37  			return false, nil
    38  		}
    39  		actual = actual[1:]
    40  	}
    41  
    42  	//match the last actual line with the rest of expected
    43  	matched, msg := matchSingleLine(actual[0], matcher.expected[0])
    44  	if matched && len(matcher.expected) == 1 {
    45  		return true, nil
    46  	} else if msg != "" {
    47  		matcher.failedText = msg
    48  		return false, nil
    49  	} else if matched {
    50  		matcher.failedText = matcher.expected[1][0]
    51  		return false, nil
    52  	}
    53  	matcher.failedText = matcher.expected[0][0]
    54  	return false, nil
    55  }
    56  
    57  func matchSingleLine(actual string, expected []string) (bool, string) {
    58  	matched := false
    59  	for i, target := range expected {
    60  		if index := strings.Index(terminal.Decolorize(actual), target); index != -1 {
    61  			if i == len(expected)-1 {
    62  				return true, ""
    63  			}
    64  			matched = true
    65  			actual = actual[index+len(target):]
    66  		} else if matched {
    67  			return false, target
    68  		} else {
    69  			return false, ""
    70  		}
    71  	}
    72  	return false, ""
    73  }
    74  
    75  func (matcher *OrderMatcher) FailureMessage(actual interface{}) string {
    76  	actualStrings, ok := actual.([]string)
    77  	if !ok {
    78  		return fmt.Sprintf("Expected actual to be a slice of strings, but it's actually a %T", actual)
    79  	}
    80  
    81  	return fmt.Sprintf("expected to find \"%s\" in display order in actual:\n'%s'\n", matcher.failedText, strings.Join(actualStrings, "\n"))
    82  }
    83  
    84  func (matcher *OrderMatcher) NegatedFailureMessage(actual interface{}) string {
    85  	actualStrings, ok := actual.([]string)
    86  	if !ok {
    87  		return fmt.Sprintf("Expected actual to be a slice of strings, but it's actually a %T", actual)
    88  	}
    89  	return fmt.Sprintf("expected to not find strings in display order in actual:\n'%s'\n", strings.Join(actualStrings, "\n"))
    90  }