1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2015-2018 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package testutil
import (
"fmt"
"regexp"
"strings"
"gopkg.in/check.v1"
)
type paddedChecker struct {
*check.CheckerInfo
isRegexp bool
isPartial bool
isLine bool
}
// EqualsPadded is a Checker that looks for an expected string to
// be equal to another except that the other might have been padded
// out to align with something else (so arbitrary amounts of
// horizontal whitespace is ok at the ends, and between non-whitespace
// bits).
var EqualsPadded = &paddedChecker{
CheckerInfo: &check.CheckerInfo{Name: "EqualsPadded", Params: []string{"padded", "expected"}},
isLine: true,
}
// MatchesPadded is a Checker that looks for an expected regexp in
// a string that might have been padded out to align with something
// else (so whitespace in the regexp is changed to [ \t]+, and ^[ \t]*
// is added to the beginning, and [ \t]*$ to the end of it).
var MatchesPadded = &paddedChecker{
CheckerInfo: &check.CheckerInfo{Name: "MatchesPadded", Params: []string{"padded", "expected"}},
isRegexp: true,
isLine: true,
}
// ContainsPadded is a Checker that looks for an expected string
// in another that might have been padded out to align with something
// else (so arbitrary amounts of horizontal whitespace is ok between
// non-whitespace bits).
var ContainsPadded = &paddedChecker{
CheckerInfo: &check.CheckerInfo{Name: "ContainsPadded", Params: []string{"padded", "expected"}},
isPartial: true,
isLine: true,
}
// EqualsWrapped is a Checker that looks for an expected string to be
// equal to another except that the other might have been padded out
// and wrapped (so arbitrary amounts of whitespace is ok at the ends,
// and between non-whitespace bits).
var EqualsWrapped = &paddedChecker{
CheckerInfo: &check.CheckerInfo{Name: "EqualsWrapped", Params: []string{"wrapped", "expected"}},
}
// MatchesWrapped is a Checker that looks for an expected regexp in a
// string that might have been padded and wrapped (so whitespace in
// the regexp is changed to \s+, and (?s)^\s* is added to the
// beginning, and \s*$ to the end of it).
var MatchesWrapped = &paddedChecker{
CheckerInfo: &check.CheckerInfo{Name: "MatchesWrapped", Params: []string{"wrapped", "expected"}},
isRegexp: true,
}
// ContainsWrapped is a Checker that looks for an expected string in
// another that might have been padded out and wrapped (so arbitrary
// amounts of whitespace is ok between non-whitespace bits).
var ContainsWrapped = &paddedChecker{
CheckerInfo: &check.CheckerInfo{Name: "EqualsWrapped", Params: []string{"wrapped", "expected"}},
isRegexp: false,
isPartial: true,
}
var spaceinator = regexp.MustCompile(`\s+`).ReplaceAllLiteralString
func (c *paddedChecker) Check(params []any, names []string) (result bool, errstr string) {
var other string
switch v := params[0].(type) {
case string:
other = v
case []byte:
other = string(v)
case error:
if v != nil {
other = v.Error()
}
default:
return false, "left-hand value must be a string or []byte or error"
}
expected, ok := params[1].(string)
if !ok {
ebuf, ok := params[1].([]byte)
if !ok {
return false, "right-hand value must be a string or []byte"
}
expected = string(ebuf)
}
ws := `\s`
if c.isLine {
ws = `[\t ]`
}
if c.isRegexp {
_, err := regexp.Compile(expected)
if err != nil {
return false, fmt.Sprintf("right-hand value must be a valid regexp: %v", err)
}
expected = spaceinator(expected, ws+"+")
} else {
fields := strings.Fields(expected)
for i := range fields {
fields[i] = regexp.QuoteMeta(fields[i])
}
expected = strings.Join(fields, ws+"+")
}
if !c.isPartial {
expected = "^" + ws + "*" + expected + ws + "*$"
}
if !c.isLine {
expected = "(?s)" + expected
}
matches, err := regexp.MatchString(expected, other)
if err != nil {
// can't happen (really)
panic(err)
}
return matches, ""
}
|