| // Copyright 2022 The Dawn & Tint Authors |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are met: |
| // |
| // 1. Redistributions of source code must retain the above copyright notice, this |
| // list of conditions and the following disclaimer. |
| // |
| // 2. Redistributions in binary form must reproduce the above copyright notice, |
| // this list of conditions and the following disclaimer in the documentation |
| // and/or other materials provided with the distribution. |
| // |
| // 3. Neither the name of the copyright holder nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
| // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| package query_test |
| |
| import ( |
| "fmt" |
| "strings" |
| "testing" |
| |
| "dawn.googlesource.com/dawn/tools/src/cts/query" |
| "github.com/google/go-cmp/cmp" |
| "github.com/stretchr/testify/assert" |
| ) |
| |
| var Q = query.Parse |
| |
| func TestTargetFormat(t *testing.T) { |
| type Test struct { |
| target query.Target |
| expect string |
| } |
| |
| for _, test := range []Test{ |
| {query.Suite, "suite"}, |
| {query.Files, "files"}, |
| {query.Tests, "tests"}, |
| {query.Cases, "cases"}, |
| {query.Target(-1), "<invalid>"}, |
| } { |
| s := strings.Builder{} |
| _, err := fmt.Fprint(&s, test.target) |
| if err != nil { |
| t.Errorf("Fprint() returned %v", err) |
| continue |
| } |
| if diff := cmp.Diff(s.String(), test.expect); diff != "" { |
| t.Errorf("Fprint('%v')\n%v", test.target, diff) |
| } |
| } |
| } |
| |
| func TestAppendFiles(t *testing.T) { |
| type Test struct { |
| base query.Query |
| files []string |
| expect query.Query |
| } |
| |
| for _, test := range []Test{ |
| {Q("suite"), []string{}, Q("suite")}, |
| {Q("suite"), []string{"x"}, Q("suite:x")}, |
| {Q("suite"), []string{"x", "y"}, Q("suite:x,y")}, |
| {Q("suite:a"), []string{}, Q("suite:a")}, |
| {Q("suite:a"), []string{"x"}, Q("suite:a,x")}, |
| {Q("suite:a"), []string{"x", "y"}, Q("suite:a,x,y")}, |
| {Q("suite:a,b"), []string{}, Q("suite:a,b")}, |
| {Q("suite:a,b"), []string{"x"}, Q("suite:a,b,x")}, |
| {Q("suite:a,b"), []string{"x", "y"}, Q("suite:a,b,x,y")}, |
| {Q("suite:a,b:c"), []string{}, Q("suite:a,b:c")}, |
| {Q("suite:a,b:c"), []string{"x"}, Q("suite:a,b,x:c")}, |
| {Q("suite:a,b:c"), []string{"x", "y"}, Q("suite:a,b,x,y:c")}, |
| {Q("suite:a,b:c,d"), []string{}, Q("suite:a,b:c,d")}, |
| {Q("suite:a,b:c,d"), []string{"x"}, Q("suite:a,b,x:c,d")}, |
| {Q("suite:a,b:c,d"), []string{"x", "y"}, Q("suite:a,b,x,y:c,d")}, |
| {Q("suite:a,b:c,d:e"), []string{}, Q("suite:a,b:c,d:e")}, |
| {Q("suite:a,b:c,d:e"), []string{"x"}, Q("suite:a,b,x:c,d:e")}, |
| {Q("suite:a,b:c,d:e"), []string{"x", "y"}, Q("suite:a,b,x,y:c,d:e")}, |
| {Q("suite:a,b:c,d:e;f"), []string{}, Q("suite:a,b:c,d:e;f")}, |
| {Q("suite:a,b:c,d:e;f"), []string{"x"}, Q("suite:a,b,x:c,d:e;f")}, |
| {Q("suite:a,b:c,d:e;f"), []string{"x", "y"}, Q("suite:a,b,x,y:c,d:e;f")}, |
| } { |
| got := test.base.AppendFiles(test.files...) |
| if diff := cmp.Diff(got, test.expect); diff != "" { |
| t.Errorf("'%v'.AppendFiles(%v)\n%v", test.base, test.files, diff) |
| } |
| } |
| } |
| |
| func TestSplitFiles(t *testing.T) { |
| type Test struct { |
| query query.Query |
| expect []string |
| } |
| |
| for _, test := range []Test{ |
| {Q("suite"), nil}, |
| {Q("suite:a"), []string{"a"}}, |
| {Q("suite:a,b"), []string{"a", "b"}}, |
| {Q("suite:a,b:c"), []string{"a", "b"}}, |
| {Q("suite:a,b:c,d"), []string{"a", "b"}}, |
| {Q("suite:a,b:c,d:e"), []string{"a", "b"}}, |
| {Q("suite:a,b:c,d:e;f"), []string{"a", "b"}}, |
| } { |
| got := test.query.SplitFiles() |
| if diff := cmp.Diff(got, test.expect); diff != "" { |
| t.Errorf("'%v'.SplitFiles()\n%v", test.query, diff) |
| } |
| } |
| } |
| |
| func TestAppendTests(t *testing.T) { |
| type Test struct { |
| base query.Query |
| files []string |
| expect query.Query |
| } |
| |
| for _, test := range []Test{ |
| {Q("suite"), []string{}, Q("suite")}, |
| {Q("suite"), []string{"x"}, Q("suite::x")}, |
| {Q("suite"), []string{"x", "y"}, Q("suite::x,y")}, |
| {Q("suite:a"), []string{}, Q("suite:a")}, |
| {Q("suite:a"), []string{"x"}, Q("suite:a:x")}, |
| {Q("suite:a"), []string{"x", "y"}, Q("suite:a:x,y")}, |
| {Q("suite:a,b"), []string{}, Q("suite:a,b")}, |
| {Q("suite:a,b"), []string{"x"}, Q("suite:a,b:x")}, |
| {Q("suite:a,b"), []string{"x", "y"}, Q("suite:a,b:x,y")}, |
| {Q("suite:a,b:c"), []string{}, Q("suite:a,b:c")}, |
| {Q("suite:a,b:c"), []string{"x"}, Q("suite:a,b:c,x")}, |
| {Q("suite:a,b:c"), []string{"x", "y"}, Q("suite:a,b:c,x,y")}, |
| {Q("suite:a,b:c,d"), []string{}, Q("suite:a,b:c,d")}, |
| {Q("suite:a,b:c,d"), []string{"x"}, Q("suite:a,b:c,d,x")}, |
| {Q("suite:a,b:c,d"), []string{"x", "y"}, Q("suite:a,b:c,d,x,y")}, |
| {Q("suite:a,b:c,d:e"), []string{}, Q("suite:a,b:c,d:e")}, |
| {Q("suite:a,b:c,d:e"), []string{"x"}, Q("suite:a,b:c,d,x:e")}, |
| {Q("suite:a,b:c,d:e"), []string{"x", "y"}, Q("suite:a,b:c,d,x,y:e")}, |
| {Q("suite:a,b:c,d:e;f"), []string{}, Q("suite:a,b:c,d:e;f")}, |
| {Q("suite:a,b:c,d:e;f"), []string{"x"}, Q("suite:a,b:c,d,x:e;f")}, |
| {Q("suite:a,b:c,d:e;f"), []string{"x", "y"}, Q("suite:a,b:c,d,x,y:e;f")}, |
| } { |
| got := test.base.AppendTests(test.files...) |
| if diff := cmp.Diff(got, test.expect); diff != "" { |
| t.Errorf("'%v'.AppendTests(%v)\n%v", test.base, test.files, diff) |
| } |
| } |
| } |
| |
| func TestSplitTests(t *testing.T) { |
| type Test struct { |
| query query.Query |
| tests []string |
| } |
| |
| for _, test := range []Test{ |
| {Q("suite"), nil}, |
| {Q("suite:a"), nil}, |
| {Q("suite:a,b"), nil}, |
| {Q("suite:a,b:c"), []string{"c"}}, |
| {Q("suite:a,b:c,d"), []string{"c", "d"}}, |
| {Q("suite:a,b:c,d:e"), []string{"c", "d"}}, |
| {Q("suite:a,b:c,d:e;f"), []string{"c", "d"}}, |
| } { |
| got := test.query.SplitTests() |
| if diff := cmp.Diff(got, test.tests); diff != "" { |
| t.Errorf("'%v'.SplitTests()\n%v", test.query, diff) |
| } |
| } |
| } |
| |
| func TestAppendCases(t *testing.T) { |
| type Test struct { |
| base query.Query |
| cases []string |
| expect query.Query |
| } |
| |
| for _, test := range []Test{ |
| {Q("suite"), []string{}, Q("suite")}, |
| {Q("suite"), []string{"x"}, Q("suite:::x")}, |
| {Q("suite"), []string{"x", "y"}, Q("suite:::x;y")}, |
| {Q("suite:a"), []string{}, Q("suite:a")}, |
| {Q("suite:a"), []string{"x"}, Q("suite:a::x")}, |
| {Q("suite:a"), []string{"x", "y"}, Q("suite:a::x;y")}, |
| {Q("suite:a,b"), []string{}, Q("suite:a,b")}, |
| {Q("suite:a,b"), []string{"x"}, Q("suite:a,b::x")}, |
| {Q("suite:a,b"), []string{"x", "y"}, Q("suite:a,b::x;y")}, |
| {Q("suite:a,b:c"), []string{}, Q("suite:a,b:c")}, |
| {Q("suite:a,b:c"), []string{"x"}, Q("suite:a,b:c:x")}, |
| {Q("suite:a,b:c"), []string{"x", "y"}, Q("suite:a,b:c:x;y")}, |
| {Q("suite:a,b:c,d"), []string{}, Q("suite:a,b:c,d")}, |
| {Q("suite:a,b:c,d"), []string{"x"}, Q("suite:a,b:c,d:x")}, |
| {Q("suite:a,b:c,d"), []string{"x", "y"}, Q("suite:a,b:c,d:x;y")}, |
| {Q("suite:a,b:c,d:e"), []string{}, Q("suite:a,b:c,d:e")}, |
| {Q("suite:a,b:c,d:e"), []string{"x"}, Q("suite:a,b:c,d:e;x")}, |
| {Q("suite:a,b:c,d:e"), []string{"x", "y"}, Q("suite:a,b:c,d:e;x;y")}, |
| {Q("suite:a,b:c,d:e;f"), []string{}, Q("suite:a,b:c,d:e;f")}, |
| {Q("suite:a,b:c,d:e;f"), []string{"x"}, Q("suite:a,b:c,d:e;f;x")}, |
| {Q("suite:a,b:c,d:e;f"), []string{"x", "y"}, Q("suite:a,b:c,d:e;f;x;y")}, |
| } { |
| got := test.base.AppendCases(test.cases...) |
| if diff := cmp.Diff(got, test.expect); diff != "" { |
| t.Errorf("'%v'.AppendCases(%v)\n%v", test.base, test.cases, diff) |
| } |
| } |
| } |
| |
| func TestAppend(t *testing.T) { |
| type Subtest struct { |
| target query.Target |
| expect query.Query |
| } |
| type Test struct { |
| base query.Query |
| strings []string |
| subtest []Subtest |
| } |
| for _, test := range []Test{ |
| { |
| Q("suite"), []string{}, []Subtest{ |
| {query.Files, Q("suite")}, |
| {query.Tests, Q("suite")}, |
| {query.Cases, Q("suite")}, |
| }, |
| }, { |
| Q("suite"), []string{"x"}, []Subtest{ |
| {query.Files, Q("suite:x")}, |
| {query.Tests, Q("suite::x")}, |
| {query.Cases, Q("suite:::x")}, |
| }, |
| }, { |
| Q("suite"), []string{"x", "y"}, []Subtest{ |
| {query.Files, Q("suite:x,y")}, |
| {query.Tests, Q("suite::x,y")}, |
| {query.Cases, Q("suite:::x;y")}, |
| }, |
| }, { |
| Q("suite:a"), []string{}, []Subtest{ |
| {query.Files, Q("suite:a")}, |
| {query.Tests, Q("suite:a")}, |
| {query.Cases, Q("suite:a")}, |
| }, |
| }, { |
| Q("suite:a"), []string{"x"}, []Subtest{ |
| {query.Files, Q("suite:a,x")}, |
| {query.Tests, Q("suite:a:x")}, |
| {query.Cases, Q("suite:a::x")}, |
| }, |
| }, { |
| Q("suite:a"), []string{"x", "y"}, []Subtest{ |
| {query.Files, Q("suite:a,x,y")}, |
| {query.Tests, Q("suite:a:x,y")}, |
| {query.Cases, Q("suite:a::x;y")}, |
| }, |
| }, { |
| Q("suite:a,b"), []string{}, []Subtest{ |
| {query.Files, Q("suite:a,b")}, |
| {query.Tests, Q("suite:a,b")}, |
| {query.Cases, Q("suite:a,b")}, |
| }, |
| }, { |
| Q("suite:a,b"), []string{"x"}, []Subtest{ |
| {query.Files, Q("suite:a,b,x")}, |
| {query.Tests, Q("suite:a,b:x")}, |
| {query.Cases, Q("suite:a,b::x")}, |
| }, |
| }, { |
| Q("suite:a,b"), []string{"x", "y"}, []Subtest{ |
| {query.Files, Q("suite:a,b,x,y")}, |
| {query.Tests, Q("suite:a,b:x,y")}, |
| {query.Cases, Q("suite:a,b::x;y")}, |
| }, |
| }, { |
| Q("suite:a,b:c"), []string{}, []Subtest{ |
| {query.Files, Q("suite:a,b:c")}, |
| {query.Tests, Q("suite:a,b:c")}, |
| {query.Cases, Q("suite:a,b:c")}, |
| }, |
| }, { |
| Q("suite:a,b:c"), []string{"x"}, []Subtest{ |
| {query.Files, Q("suite:a,b,x:c")}, |
| {query.Tests, Q("suite:a,b:c,x")}, |
| {query.Cases, Q("suite:a,b:c:x")}, |
| }, |
| }, { |
| Q("suite:a,b:c"), []string{"x", "y"}, []Subtest{ |
| {query.Files, Q("suite:a,b,x,y:c")}, |
| {query.Tests, Q("suite:a,b:c,x,y")}, |
| {query.Cases, Q("suite:a,b:c:x;y")}, |
| }, |
| }, { |
| Q("suite:a,b:c,d"), []string{}, []Subtest{ |
| {query.Files, Q("suite:a,b:c,d")}, |
| {query.Tests, Q("suite:a,b:c,d")}, |
| {query.Cases, Q("suite:a,b:c,d")}, |
| }, |
| }, { |
| Q("suite:a,b:c,d"), []string{"x"}, []Subtest{ |
| {query.Files, Q("suite:a,b,x:c,d")}, |
| {query.Tests, Q("suite:a,b:c,d,x")}, |
| {query.Cases, Q("suite:a,b:c,d:x")}, |
| }, |
| }, { |
| Q("suite:a,b:c,d"), []string{"x", "y"}, []Subtest{ |
| {query.Files, Q("suite:a,b,x,y:c,d")}, |
| {query.Tests, Q("suite:a,b:c,d,x,y")}, |
| {query.Cases, Q("suite:a,b:c,d:x;y")}, |
| }, |
| }, { |
| Q("suite:a,b:c,d:e"), []string{}, []Subtest{ |
| {query.Files, Q("suite:a,b:c,d:e")}, |
| {query.Tests, Q("suite:a,b:c,d:e")}, |
| {query.Cases, Q("suite:a,b:c,d:e")}, |
| }, |
| }, { |
| Q("suite:a,b:c,d:e"), []string{"x"}, []Subtest{ |
| {query.Files, Q("suite:a,b,x:c,d:e")}, |
| {query.Tests, Q("suite:a,b:c,d,x:e")}, |
| {query.Cases, Q("suite:a,b:c,d:e;x")}, |
| }, |
| }, { |
| Q("suite:a,b:c,d:e"), []string{"x", "y"}, []Subtest{ |
| {query.Files, Q("suite:a,b,x,y:c,d:e")}, |
| {query.Tests, Q("suite:a,b:c,d,x,y:e")}, |
| {query.Cases, Q("suite:a,b:c,d:e;x;y")}, |
| }, |
| }, { |
| Q("suite:a,b:c,d:e;f"), []string{}, []Subtest{ |
| {query.Files, Q("suite:a,b:c,d:e;f")}, |
| {query.Tests, Q("suite:a,b:c,d:e;f")}, |
| {query.Cases, Q("suite:a,b:c,d:e;f")}, |
| }, |
| }, { |
| Q("suite:a,b:c,d:e;f"), []string{"x"}, []Subtest{ |
| {query.Files, Q("suite:a,b,x:c,d:e;f")}, |
| {query.Tests, Q("suite:a,b:c,d,x:e;f")}, |
| {query.Cases, Q("suite:a,b:c,d:e;f;x")}, |
| }, |
| }, { |
| Q("suite:a,b:c,d:e;f"), []string{"x", "y"}, []Subtest{ |
| {query.Files, Q("suite:a,b,x,y:c,d:e;f")}, |
| {query.Tests, Q("suite:a,b:c,d,x,y:e;f")}, |
| {query.Cases, Q("suite:a,b:c,d:e;f;x;y")}, |
| }, |
| }, |
| } { |
| for _, subtest := range test.subtest { |
| got := test.base.Append(subtest.target, test.strings...) |
| if diff := cmp.Diff(got, subtest.expect); diff != "" { |
| t.Errorf("'%v'.Append(%v, %v)\n%v", test.base, subtest.target, test.base.Files, diff) |
| } |
| } |
| } |
| } |
| |
| func TestSplitCases(t *testing.T) { |
| type Test struct { |
| query query.Query |
| expect []string |
| } |
| |
| for _, test := range []Test{ |
| {Q("suite"), nil}, |
| {Q("suite:a"), nil}, |
| {Q("suite:a,b"), nil}, |
| {Q("suite:a,b:c"), nil}, |
| {Q("suite:a,b:c,d"), nil}, |
| {Q("suite:a,b:c,d:e"), []string{"e"}}, |
| {Q("suite:a,b:c,d:e;f"), []string{"e", "f"}}, |
| } { |
| got := test.query.SplitCases() |
| if diff := cmp.Diff(got, test.expect); diff != "" { |
| t.Errorf("'%v'.SplitCases()\n%v", test.query, diff) |
| } |
| } |
| } |
| |
| func TestCaseParameters(t *testing.T) { |
| type Test struct { |
| query query.Query |
| expect query.CaseParameters |
| } |
| |
| for _, test := range []Test{ |
| {Q("suite"), nil}, |
| {Q("suite:a"), nil}, |
| {Q("suite:a,b"), nil}, |
| {Q("suite:a,b:c"), nil}, |
| {Q("suite:a,b:c,d"), nil}, |
| {Q("suite:a,b:c,d:e"), query.CaseParameters{"e": ""}}, |
| {Q("suite:a,b:c,d:e;f"), query.CaseParameters{"e": "", "f": ""}}, |
| {Q("suite:a,b:c,d:e=f;g=h"), query.CaseParameters{"e": "f", "g": "h"}}, |
| } { |
| got := test.query.CaseParameters() |
| if diff := cmp.Diff(got, test.expect); diff != "" { |
| t.Errorf("'%v'.CaseParameters()\n%v", test.query, diff) |
| } |
| } |
| } |
| |
| func TestTarget(t *testing.T) { |
| type Test struct { |
| query query.Query |
| expect query.Target |
| } |
| |
| for _, test := range []Test{ |
| {Q("suite"), query.Suite}, |
| {Q("suite:*"), query.Files}, |
| {Q("suite:a"), query.Files}, |
| {Q("suite:a,*"), query.Files}, |
| {Q("suite:a,b"), query.Files}, |
| {Q("suite:a,b:*"), query.Tests}, |
| {Q("suite:a,b:c"), query.Tests}, |
| {Q("suite:a,b:c,*"), query.Tests}, |
| {Q("suite:a,b:c,d"), query.Tests}, |
| {Q("suite:a,b:c,d:*"), query.Cases}, |
| {Q("suite:a,b:c,d:e"), query.Cases}, |
| {Q("suite:a,b:c,d:e;*"), query.Cases}, |
| {Q("suite:a,b:c,d:e;f"), query.Cases}, |
| {Q("suite:a,b:c,d:e;f;*"), query.Cases}, |
| } { |
| got := test.query.Target() |
| if diff := cmp.Diff(got, test.expect); diff != "" { |
| t.Errorf("'%v'.Target()\n%v", test.query, diff) |
| } |
| } |
| } |
| |
| func TestIsWildcard(t *testing.T) { |
| type Test struct { |
| query query.Query |
| expect bool |
| } |
| |
| for _, test := range []Test{ |
| {Q("suite"), false}, |
| {Q("suite:*"), true}, |
| {Q("suite:a"), false}, |
| {Q("suite:a,*"), true}, |
| {Q("suite:a,b"), false}, |
| {Q("suite:a,b:*"), true}, |
| {Q("suite:a,b:c"), false}, |
| {Q("suite:a,b:c,*"), true}, |
| {Q("suite:a,b:c,d"), false}, |
| {Q("suite:a,b:c,d:*"), true}, |
| {Q("suite:a,b:c,d:e"), false}, |
| {Q("suite:a,b:c,d:e;*"), true}, |
| {Q("suite:a,b:c,d:e;f"), false}, |
| {Q("suite:a,b:c,d:e;f;*"), true}, |
| } { |
| got := test.query.IsWildcard() |
| if diff := cmp.Diff(got, test.expect); diff != "" { |
| t.Errorf("'%v'.IsWildcard()\n%v", test.query, diff) |
| } |
| } |
| } |
| |
| func TestParsePrint(t *testing.T) { |
| type Test struct { |
| in string |
| expect query.Query |
| } |
| |
| for _, test := range []Test{ |
| { |
| "a", |
| query.Query{ |
| Suite: "a", |
| }, |
| }, { |
| "a:*", |
| query.Query{ |
| Suite: "a", |
| Files: "*", |
| }, |
| }, { |
| "a:b", |
| query.Query{ |
| Suite: "a", |
| Files: "b", |
| }, |
| }, { |
| "a:b,*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,*", |
| }, |
| }, { |
| "a:b:*", |
| query.Query{ |
| Suite: "a", |
| Files: "b", |
| Tests: "*", |
| }, |
| }, { |
| "a:b,c", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| }, |
| }, { |
| "a:b,c:*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "*", |
| }, |
| }, { |
| "a:b,c:d", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d", |
| }, |
| }, { |
| "a:b,c:d,*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,*", |
| }, |
| }, { |
| "a:b,c:d,e", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| }, |
| }, { |
| "a:b,c:d,e,*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e,*", |
| }, |
| }, { |
| "a:b,c:d,e:*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: "*", |
| }, |
| }, { |
| "a:b,c:d,e:f=g", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: "f=g", |
| }, |
| }, { |
| "a:b,c:d,e:f=g;*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: "f=g;*", |
| }, |
| }, { |
| "a:b,c:d,e:f=g;h=i", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: "f=g;h=i", |
| }, |
| }, { |
| "a:b,c:d,e:f=g;h=i;*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: "f=g;h=i;*", |
| }, |
| }, { |
| `a:b,c:d,e:f={"x": 1, "y": 2}`, |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: `f={"x": 1, "y": 2}`, |
| }, |
| }, { |
| `a:b,c,d:e,f:g="h";i=[10,20,30];j=40`, |
| query.Query{ |
| Suite: "a", |
| Files: "b,c,d", |
| Tests: "e,f", |
| Cases: `g="h";i=[10,20,30];j=40`, |
| }, |
| }, |
| } { |
| parsed := query.Parse(test.in) |
| if diff := cmp.Diff(test.expect, parsed); diff != "" { |
| t.Errorf("query.Parse('%v')\n%v", test.in, diff) |
| } |
| str := test.expect.String() |
| if diff := cmp.Diff(test.in, str); diff != "" { |
| t.Errorf("query.String('%v')\n%v", test.in, diff) |
| } |
| } |
| } |
| |
| // Essentially the same as TestParsePrint(), but calling ExpectationFileString() |
| // instead of String(). |
| func TestParsePrintExpectationFileString(t *testing.T) { |
| type Test struct { |
| input string |
| expected query.Query |
| } |
| |
| for _, test := range []Test{ |
| { |
| "a", |
| query.Query{ |
| Suite: "a", |
| }, |
| }, { |
| "a:*", |
| query.Query{ |
| Suite: "a", |
| Files: "*", |
| }, |
| }, { |
| "a:b", |
| query.Query{ |
| Suite: "a", |
| Files: "b", |
| }, |
| }, { |
| "a:b,*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,*", |
| }, |
| }, { |
| "a:b:*", |
| query.Query{ |
| Suite: "a", |
| Files: "b", |
| Tests: "*", |
| }, |
| }, { |
| "a:b,c", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| }, |
| }, { |
| "a:b,c:*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "*", |
| }, |
| }, { |
| "a:b,c:d:", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d", |
| }, |
| }, { |
| "a:b,c:d,*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,*", |
| }, |
| }, { |
| "a:b,c:d,e:", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| }, |
| }, { |
| "a:b,c:d,e,*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e,*", |
| }, |
| }, { |
| "a:b,c:d,e:*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: "*", |
| }, |
| }, { |
| "a:b,c:d,e:f=g", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: "f=g", |
| }, |
| }, { |
| "a:b,c:d,e:f=g;*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: "f=g;*", |
| }, |
| }, { |
| "a:b,c:d,e:f=g;h=i", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: "f=g;h=i", |
| }, |
| }, { |
| "a:b,c:d,e:f=g;h=i;*", |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: "f=g;h=i;*", |
| }, |
| }, { |
| `a:b,c:d,e:f={"x": 1, "y": 2}`, |
| query.Query{ |
| Suite: "a", |
| Files: "b,c", |
| Tests: "d,e", |
| Cases: `f={"x": 1, "y": 2}`, |
| }, |
| }, { |
| `a:b,c,d:e,f:g="h";i=[10,20,30];j=40`, |
| query.Query{ |
| Suite: "a", |
| Files: "b,c,d", |
| Tests: "e,f", |
| Cases: `g="h";i=[10,20,30];j=40`, |
| }, |
| }, |
| } { |
| parsed := query.Parse(test.input) |
| assert.Equal(t, test.expected, parsed) |
| expectationFileString := test.expected.ExpectationFileString() |
| assert.Equal(t, test.input, expectationFileString) |
| } |
| } |
| |
| func TestCompare(t *testing.T) { |
| type Test struct { |
| a, b query.Query |
| expect int |
| } |
| |
| for _, test := range []Test{ |
| {Q("a"), Q("a"), 0}, |
| {Q("a:*"), Q("a"), 1}, |
| {Q("a:*"), Q("a:*"), 0}, |
| {Q("a:*"), Q("b:*"), -1}, |
| {Q("a:*"), Q("a:b,*"), -1}, |
| {Q("a:b,*"), Q("a:b"), 1}, |
| {Q("a:b,*"), Q("a:b,*"), 0}, |
| {Q("a:b,*"), Q("a:c,*"), -1}, |
| {Q("a:b,c,*"), Q("a:b,*"), 1}, |
| {Q("a:b,c,*"), Q("a:b,c,*"), 0}, |
| {Q("a:b,c,d,*"), Q("a:b,c,*"), 1}, |
| {Q("a:b,c,*"), Q("a:b,c:d,*"), 1}, |
| {Q("a:b,c:*"), Q("a:b,c,d,*"), -1}, |
| {Q("a:b,c:d,*"), Q("a:b,c:d,*"), 0}, |
| {Q("a:b,c:d,e,*"), Q("a:b,c:d,*"), 1}, |
| {Q("a:b,c:d,e,*"), Q("a:b,c:d,e,*"), 0}, |
| {Q("a:b,c:d,e,*"), Q("a:b,c:e,f,*"), -1}, |
| {Q("a:b:c:d;*"), Q("a:b:c:d;*"), 0}, |
| {Q("a:b:c:d;e=1;*"), Q("a:b:c:d;*"), 1}, |
| {Q("a:b:c:d;e=2;*"), Q("a:b:c:d;e=1;*"), 1}, |
| {Q("a:b:c:d;e=1;f=2;*"), Q("a:b:c:d;*"), 1}, |
| } { |
| if got, expect := test.a.Compare(test.b), test.expect; got != expect { |
| t.Errorf("('%v').Compare('%v')\nexpect: %+v\ngot: %+v", test.a, test.b, expect, got) |
| } |
| // Check opposite order |
| if got, expect := test.b.Compare(test.a), -test.expect; got != expect { |
| t.Errorf("('%v').Compare('%v')\nexpect: %+v\ngot: %+v", test.b, test.a, expect, got) |
| } |
| } |
| } |
| |
| func TestContains(t *testing.T) { |
| type Test struct { |
| a, b query.Query |
| expect bool |
| } |
| |
| for _, test := range []Test{ |
| {Q("a"), Q("a"), true}, |
| {Q("a"), Q("b"), false}, |
| {Q("a:*"), Q("a:*"), true}, |
| {Q("a:*"), Q("a:b"), true}, |
| {Q("a:*"), Q("b"), false}, |
| {Q("a:*"), Q("b:c"), false}, |
| {Q("a:*"), Q("b:*"), false}, |
| {Q("a:*"), Q("a:b,*"), true}, |
| {Q("a:b,*"), Q("a:*"), false}, |
| {Q("a:b,*"), Q("a:b"), true}, |
| {Q("a:b,*"), Q("a:c"), false}, |
| {Q("a:b,*"), Q("a:b,*"), true}, |
| {Q("a:b,*"), Q("a:c,*"), false}, |
| {Q("a:b,c"), Q("a:b,c,d"), false}, |
| {Q("a:b,c"), Q("a:b,c:d"), false}, |
| {Q("a:b,c,*"), Q("a:b,*"), false}, |
| {Q("a:b,c,*"), Q("a:b,c"), true}, |
| {Q("a:b,c,*"), Q("a:b,d"), false}, |
| {Q("a:b,c,*"), Q("a:b,c,*"), true}, |
| {Q("a:b,c,*"), Q("a:b,c,d,*"), true}, |
| {Q("a:b,c,*"), Q("a:b,c:d,*"), true}, |
| {Q("a:b,c:*"), Q("a:b,c,d,*"), false}, |
| {Q("a:b,c:d"), Q("a:b,c:d,e"), false}, |
| {Q("a:b,c:d,*"), Q("a:b,c:d"), true}, |
| {Q("a:b,c:d,*"), Q("a:b,c:e"), false}, |
| {Q("a:b,c:d,*"), Q("a:b,c:d,*"), true}, |
| {Q("a:b,c:d,*"), Q("a:b,c:d,e,*"), true}, |
| {Q("a:b,c:d,e,*"), Q("a:b,c:d,e"), true}, |
| {Q("a:b,c:d,e,*"), Q("a:b,c:e,e"), false}, |
| {Q("a:b,c:d,e,*"), Q("a:b,c:d,f"), false}, |
| {Q("a:b,c:d,e,*"), Q("a:b,c:d,e,*"), true}, |
| {Q("a:b,c:d,e,*"), Q("a:b,c:e,f,*"), false}, |
| {Q("a:b,c:d,e,*"), Q("a:b,c:d,*"), false}, |
| {Q("a:b:c:d;*"), Q("a:b:c:d;*"), true}, |
| {Q("a:b:c:d;*"), Q("a:b:c:d,e;*"), true}, |
| {Q("a:b:c:d;*"), Q("a:b:c:d;e=1;*"), true}, |
| {Q("a:b:c:d;*"), Q("a:b:c:d;e=1;*"), true}, |
| {Q("a:b:c:d;*"), Q("a:b:c:d;e=1;f=2;*"), true}, |
| {Q("a:b:c:d;e=1;*"), Q("a:b:c:d;*"), true}, |
| {Q("a:b:c:d;e=1;f=2;*"), Q("a:b:c:d;*"), true}, |
| {Q("a:b:c:d;e=1;*"), Q("a:b:c:d;e=2;*"), false}, |
| {Q("a:b:c:d;e=2;*"), Q("a:b:c:d;e=1;*"), false}, |
| {Q("a:b:c:d;e;*"), Q("a:b:c:d;e=1;*"), false}, |
| } { |
| if got := test.a.Contains(test.b); got != test.expect { |
| t.Errorf("('%v').Contains('%v')\nexpect: %+v\ngot: %+v", test.a, test.b, test.expect, got) |
| } |
| } |
| } |
| |
| func TestWalk(t *testing.T) { |
| type Segment struct { |
| Query query.Query |
| Target query.Target |
| Name string |
| } |
| type Test struct { |
| query query.Query |
| expect []Segment |
| } |
| |
| for _, test := range []Test{ |
| { |
| Q("suite"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| }}, |
| { |
| Q("suite:*"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:*"), query.Files, "*"}, |
| }}, |
| { |
| Q("suite:a"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| }}, |
| { |
| Q("suite:a,*"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| {Q("suite:a,*"), query.Files, "*"}, |
| }}, |
| { |
| Q("suite:a,b"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| {Q("suite:a,b"), query.Files, "b"}, |
| }}, |
| { |
| Q("suite:a,b:*"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| {Q("suite:a,b"), query.Files, "b"}, |
| {Q("suite:a,b:*"), query.Tests, "*"}, |
| }}, |
| { |
| Q("suite:a,b:c"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| {Q("suite:a,b"), query.Files, "b"}, |
| {Q("suite:a,b:c"), query.Tests, "c"}, |
| }}, |
| { |
| Q("suite:a,b:c,*"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| {Q("suite:a,b"), query.Files, "b"}, |
| {Q("suite:a,b:c"), query.Tests, "c"}, |
| {Q("suite:a,b:c,*"), query.Tests, "*"}, |
| }}, |
| { |
| Q("suite:a,b:c,d"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| {Q("suite:a,b"), query.Files, "b"}, |
| {Q("suite:a,b:c"), query.Tests, "c"}, |
| {Q("suite:a,b:c,d"), query.Tests, "d"}, |
| }}, |
| { |
| Q("suite:a,b:c,d:*"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| {Q("suite:a,b"), query.Files, "b"}, |
| {Q("suite:a,b:c"), query.Tests, "c"}, |
| {Q("suite:a,b:c,d"), query.Tests, "d"}, |
| {Q("suite:a,b:c,d:*"), query.Cases, "*"}, |
| }}, |
| { |
| Q("suite:a,b:c,d:e"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| {Q("suite:a,b"), query.Files, "b"}, |
| {Q("suite:a,b:c"), query.Tests, "c"}, |
| {Q("suite:a,b:c,d"), query.Tests, "d"}, |
| {Q("suite:a,b:c,d:e"), query.Cases, "e"}, |
| }}, |
| { |
| Q("suite:a,b:c,d:e;*"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| {Q("suite:a,b"), query.Files, "b"}, |
| {Q("suite:a,b:c"), query.Tests, "c"}, |
| {Q("suite:a,b:c,d"), query.Tests, "d"}, |
| {Q("suite:a,b:c,d:e;*"), query.Cases, "e;*"}, |
| }}, |
| { |
| Q("suite:a,b:c,d:e;f"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| {Q("suite:a,b"), query.Files, "b"}, |
| {Q("suite:a,b:c"), query.Tests, "c"}, |
| {Q("suite:a,b:c,d"), query.Tests, "d"}, |
| {Q("suite:a,b:c,d:e;f"), query.Cases, "e;f"}, |
| }}, |
| { |
| Q("suite:a,b:c,d:e;f;*"), []Segment{ |
| {Q("suite"), query.Suite, "suite"}, |
| {Q("suite:a"), query.Files, "a"}, |
| {Q("suite:a,b"), query.Files, "b"}, |
| {Q("suite:a,b:c"), query.Tests, "c"}, |
| {Q("suite:a,b:c,d"), query.Tests, "d"}, |
| {Q("suite:a,b:c,d:e;f;*"), query.Cases, "e;f;*"}, |
| }}, |
| } { |
| got := []Segment{} |
| err := test.query.Walk(func(q query.Query, t query.Target, n string) error { |
| got = append(got, Segment{q, t, n}) |
| return nil |
| }) |
| if err != nil { |
| t.Errorf("'%v'.Walk() returned %v", test.query, err) |
| continue |
| } |
| if diff := cmp.Diff(got, test.expect); diff != "" { |
| t.Errorf("'%v'.Walk()\n%v", test.query, diff) |
| } |
| } |
| } |
| |
| type TestError struct{} |
| |
| func (TestError) Error() string { return "test error" } |
| |
| func TestWalkErrors(t *testing.T) { |
| for _, fq := range []query.Query{ |
| Q("suite"), |
| Q("suite:*"), |
| Q("suite:a"), |
| Q("suite:a,*"), |
| Q("suite:a,b"), |
| Q("suite:a,b:*"), |
| Q("suite:a,b:c"), |
| Q("suite:a,b:c,*"), |
| Q("suite:a,b:c,d"), |
| Q("suite:a,b:c,d:*"), |
| Q("suite:a,b:c,d:e"), |
| Q("suite:a,b:c,d:e;*"), |
| Q("suite:a,b:c,d:e;f"), |
| Q("suite:a,b:c,d:e;f;*"), |
| } { |
| expect := TestError{} |
| got := fq.Walk(func(q query.Query, t query.Target, n string) error { |
| if q == fq { |
| return expect |
| } |
| return nil |
| }) |
| if diff := cmp.Diff(got, expect); diff != "" { |
| t.Errorf("'%v'.Walk()\n%v", fq, diff) |
| } |
| } |
| } |