github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/fly/integration/print_table_matcher_test.go (about) 1 package integration_test 2 3 import ( 4 "bytes" 5 "fmt" 6 "os/exec" 7 "strings" 8 9 "github.com/pf-qiu/concourse/v6/fly/ui" 10 "github.com/onsi/gomega/format" 11 "github.com/onsi/gomega/gbytes" 12 ) 13 14 type PrintTableMatcher struct { 15 table ui.Table 16 printHeaders bool 17 18 actual string 19 expected string 20 } 21 22 func PrintTable(table ui.Table) *PrintTableMatcher { 23 return &PrintTableMatcher{table: table} 24 } 25 26 func PrintTableWithHeaders(table ui.Table) *PrintTableMatcher { 27 return &PrintTableMatcher{table: table, printHeaders: true} 28 } 29 30 func (matcher *PrintTableMatcher) Match(actual interface{}) (bool, error) { 31 buf := new(bytes.Buffer) 32 33 switch v := actual.(type) { 34 case *exec.Cmd: 35 actualBuf := new(bytes.Buffer) 36 37 v.Stdout = actualBuf 38 v.Stderr = actualBuf 39 40 err := v.Run() 41 if err != nil { 42 return false, err 43 } 44 45 matcher.actual = actualBuf.String() 46 case *gbytes.Buffer: 47 matcher.actual = string(v.Contents()) 48 default: 49 return false, fmt.Errorf("unknown type: %T", actual) 50 } 51 52 err := matcher.compareDurations() 53 if err != nil { 54 return false, err 55 } 56 57 err = matcher.table.Render(buf, matcher.printHeaders) 58 if err != nil { 59 return false, err 60 } 61 62 matcher.expected = buf.String() 63 64 return strings.Contains(matcher.actual, matcher.expected), nil 65 } 66 67 func (matcher *PrintTableMatcher) compareDurations() error { 68 actualRows := strings.Split(matcher.actual, "\n") 69 if len(actualRows)-1 != len(matcher.table.Data) { 70 return nil 71 } 72 73 for lineIdx, row := range matcher.table.Data { 74 actualRow := actualRows[lineIdx] 75 actualCells := strings.Fields(actualRow) 76 if len(actualCells) != len(row) { 77 continue 78 } 79 80 for cellIdx, cell := range row { 81 tableDuration, parsed := ParseTableDuration(cell.Contents) 82 if !parsed { 83 continue 84 } 85 86 actualCell := actualCells[cellIdx] 87 err := tableDuration.MatchString(actualCell) 88 if err != nil { 89 return err 90 } 91 92 matcher.table.Data[lineIdx][cellIdx].Contents = actualCell 93 } 94 } 95 96 return nil 97 } 98 99 func (matcher *PrintTableMatcher) FailureMessage(actual interface{}) string { 100 return fmt.Sprintf("Expected\n%s\n(%q)\nTo contain the table\n%s\n(%q)\n", format.IndentString(matcher.actual, 1), matcher.actual, format.IndentString(matcher.expected, 1), matcher.expected) 101 } 102 103 func (matcher *PrintTableMatcher) NegatedFailureMessage(actual interface{}) string { 104 return fmt.Sprintf("Expected\n%s\n(%q)\nTo not contain the table\n%s\n(%q)\n", format.IndentString(matcher.actual, 1), matcher.actual, format.IndentString(matcher.expected, 1), matcher.expected) 105 }