github.com/coreos/mantle@v0.13.0/harness/match_test.go (about)

     1  // Copyright 2017 CoreOS, Inc.
     2  // Copyright 2015 The Go Authors.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  
    16  package harness
    17  
    18  import (
    19  	"reflect"
    20  	"regexp"
    21  	"testing"
    22  )
    23  
    24  func TestSplitRegexp(t *testing.T) {
    25  	res := func(s ...string) []string { return s }
    26  	testCases := []struct {
    27  		pattern string
    28  		result  []string
    29  	}{
    30  		// Correct patterns
    31  		// If a regexp pattern is correct, all split regexps need to be correct
    32  		// as well.
    33  		{"", res("")},
    34  		{"/", res("", "")},
    35  		{"//", res("", "", "")},
    36  		{"A", res("A")},
    37  		{"A/B", res("A", "B")},
    38  		{"A/B/", res("A", "B", "")},
    39  		{"/A/B/", res("", "A", "B", "")},
    40  		{"[A]/(B)", res("[A]", "(B)")},
    41  		{"[/]/[/]", res("[/]", "[/]")},
    42  		{"[/]/[:/]", res("[/]", "[:/]")},
    43  		{"/]", res("", "]")},
    44  		{"]/", res("]", "")},
    45  		{"]/[/]", res("]", "[/]")},
    46  		{`([)/][(])`, res(`([)/][(])`)},
    47  		{"[(]/[)]", res("[(]", "[)]")},
    48  
    49  		// Faulty patterns
    50  		// Errors in original should produce at least one faulty regexp in results.
    51  		{")/", res(")/")},
    52  		{")/(/)", res(")/(", ")")},
    53  		{"a[/)b", res("a[/)b")},
    54  		{"(/]", res("(/]")},
    55  		{"(/", res("(/")},
    56  		{"[/]/[/", res("[/]", "[/")},
    57  		{`\p{/}`, res(`\p{`, "}")},
    58  		{`\p/`, res(`\p`, "")},
    59  		{`[[:/:]]`, res(`[[:/:]]`)},
    60  	}
    61  	for _, tc := range testCases {
    62  		a := splitRegexp(tc.pattern)
    63  		if !reflect.DeepEqual(a, tc.result) {
    64  			t.Errorf("splitRegexp(%q) = %#v; want %#v", tc.pattern, a, tc.result)
    65  		}
    66  
    67  		// If there is any error in the pattern, one of the returned subpatterns
    68  		// needs to have an error as well.
    69  		if _, err := regexp.Compile(tc.pattern); err != nil {
    70  			ok := true
    71  			for _, re := range a {
    72  				if _, err := regexp.Compile(re); err != nil {
    73  					ok = false
    74  				}
    75  			}
    76  			if ok {
    77  				t.Errorf("%s: expected error in any of %q", tc.pattern, a)
    78  			}
    79  		}
    80  	}
    81  }
    82  
    83  func TestMatcher(t *testing.T) {
    84  	testCases := []struct {
    85  		pattern     string
    86  		parent, sub string
    87  		ok          bool
    88  	}{
    89  		// Behavior without subtests.
    90  		{"", "", "TestFoo", true},
    91  		{"TestFoo", "", "TestFoo", true},
    92  		{"TestFoo/", "", "TestFoo", true},
    93  		{"TestFoo/bar/baz", "", "TestFoo", true},
    94  		{"TestFoo", "", "TestBar", false},
    95  		{"TestFoo/", "", "TestBar", false},
    96  		{"TestFoo/bar/baz", "", "TestBar/bar/baz", false},
    97  
    98  		// with subtests
    99  		{"", "TestFoo", "x", true},
   100  		{"TestFoo", "TestFoo", "x", true},
   101  		{"TestFoo/", "TestFoo", "x", true},
   102  		{"TestFoo/bar/baz", "TestFoo", "bar", true},
   103  		// Subtest with a '/' in its name still allows for copy and pasted names
   104  		// to match.
   105  		{"TestFoo/bar/baz", "TestFoo", "bar/baz", true},
   106  		{"TestFoo/bar/baz", "TestFoo/bar", "baz", true},
   107  		{"TestFoo/bar/baz", "TestFoo", "x", false},
   108  		{"TestFoo", "TestBar", "x", false},
   109  		{"TestFoo/", "TestBar", "x", false},
   110  		{"TestFoo/bar/baz", "TestBar", "x/bar/baz", false},
   111  
   112  		// subtests only
   113  		{"", "TestFoo", "x", true},
   114  		{"/", "TestFoo", "x", true},
   115  		{"./", "TestFoo", "x", true},
   116  		{"./.", "TestFoo", "x", true},
   117  		{"/bar/baz", "TestFoo", "bar", true},
   118  		{"/bar/baz", "TestFoo", "bar/baz", true},
   119  		{"//baz", "TestFoo", "bar/baz", true},
   120  		{"//", "TestFoo", "bar/baz", true},
   121  		{"/bar/baz", "TestFoo/bar", "baz", true},
   122  		{"//foo", "TestFoo", "bar/baz", false},
   123  		{"/bar/baz", "TestFoo", "x", false},
   124  		{"/bar/baz", "TestBar", "x/bar/baz", false},
   125  	}
   126  
   127  	for _, tc := range testCases {
   128  		m := newMatcher(tc.pattern, "-harness.run")
   129  
   130  		parent := &H{name: tc.parent}
   131  		if tc.parent != "" {
   132  			parent.level = 1
   133  		}
   134  		if n, ok := m.fullName(parent, tc.sub); ok != tc.ok {
   135  			t.Errorf("for pattern %q, fullName(parent=%q, sub=%q) = %q, ok %v; want ok %v",
   136  				tc.pattern, tc.parent, tc.sub, n, ok, tc.ok)
   137  		}
   138  	}
   139  }
   140  
   141  func TestNaming(t *testing.T) {
   142  	m := newMatcher("", "")
   143  
   144  	parent := &H{name: "x", level: 1} // top-level test.
   145  
   146  	// Rig the matcher with some preloaded values.
   147  	m.subNames["x/b"] = 1000
   148  
   149  	testCases := []struct {
   150  		name, want string
   151  	}{
   152  		// Uniqueness
   153  		{"", "x/#00"},
   154  		{"", "x/#01"},
   155  
   156  		{"t", "x/t"},
   157  		{"t", "x/t#01"},
   158  		{"t", "x/t#02"},
   159  
   160  		{"a#01", "x/a#01"}, // user has subtest with this name.
   161  		{"a", "x/a"},       // doesn't conflict with this name.
   162  		{"a", "x/a#01#01"}, // conflict, add disambiguating string.
   163  		{"a", "x/a#02"},    // This string is claimed now, so resume
   164  		{"a", "x/a#03"},    // with counting.
   165  		{"a#02", "x/a#02#01"},
   166  
   167  		{"b", "x/b#1000"}, // rigged, see above
   168  		{"b", "x/b#1001"},
   169  
   170  		// // Sanitizing
   171  		{"A:1 B:2", "x/A:1_B:2"},
   172  		{"s\t\r\u00a0", "x/s___"},
   173  		{"\x01", `x/\x01`},
   174  		{"\U0010ffff", `x/\U0010ffff`},
   175  	}
   176  
   177  	for i, tc := range testCases {
   178  		if got, _ := m.fullName(parent, tc.name); got != tc.want {
   179  			t.Errorf("%d:%s: got %q; want %q", i, tc.name, got, tc.want)
   180  		}
   181  	}
   182  }