blob: 9ed14f526499a15b606e6d4aa4d7d509cf3bbb64 [file] [log] [blame]
package query_test
import (
"fmt"
"testing"
"dawn.googlesource.com/dawn/tools/src/cts/query"
"github.com/google/go-cmp/cmp"
)
var (
abort = "Abort"
crash = "Crash"
failure = "Failure"
pass = "Pass"
skip = "Skip"
)
func NewTree[Data any](t *testing.T, entries ...query.QueryData[Data]) (query.Tree[Data], error) {
return query.NewTree(entries...)
}
func TestNewSingle(t *testing.T) {
type Tree = query.Tree[string]
type Node = query.TreeNode[string]
type QueryData = query.QueryData[string]
type Children = query.TreeNodeChildren[string]
type Test struct {
in QueryData
expect Tree
}
for _, test := range []Test{
{ /////////////////////////////////////////////////////////////////////
in: QueryData{
Query: Q(`suite:*`),
Data: pass,
},
expect: Tree{
TreeNode: Node{
Children: Children{
query.TreeNodeChildKey{`suite`, query.Suite}: {
Query: Q(`suite`),
Children: Children{
query.TreeNodeChildKey{`*`, query.Files}: {
Query: Q(`suite:*`),
Data: &pass,
},
},
},
},
},
},
},
{ /////////////////////////////////////////////////////////////////////
in: QueryData{
Query: Q(`suite:a,*`),
Data: pass,
},
expect: Tree{
TreeNode: Node{
Children: Children{
query.TreeNodeChildKey{`suite`, query.Suite}: {
Query: Q(`suite`),
Children: Children{
query.TreeNodeChildKey{`a`, query.Files}: {
Query: Q(`suite:a`),
Children: Children{
query.TreeNodeChildKey{`*`, query.Files}: {
Query: Q(`suite:a,*`),
Data: &pass,
},
},
},
},
},
},
},
},
},
{ /////////////////////////////////////////////////////////////////////
in: QueryData{
Query: Q(`suite:a,b:*`),
Data: pass,
},
expect: Tree{
TreeNode: Node{
Children: Children{
query.TreeNodeChildKey{`suite`, query.Suite}: {
Query: Q(`suite`),
Children: Children{
query.TreeNodeChildKey{`a`, query.Files}: {
Query: Q(`suite:a`),
Children: Children{
query.TreeNodeChildKey{`b`, query.Files}: {
Query: Q(`suite:a,b`),
Children: Children{
query.TreeNodeChildKey{`*`, query.Tests}: {
Query: Q(`suite:a,b:*`),
Data: &pass,
},
},
},
},
},
},
},
},
},
},
},
{ /////////////////////////////////////////////////////////////////////
in: QueryData{
Query: Q(`suite:a,b:c:*`),
Data: pass,
},
expect: Tree{
TreeNode: Node{
Children: Children{
query.TreeNodeChildKey{`suite`, query.Suite}: {
Query: Q(`suite`),
Children: Children{
query.TreeNodeChildKey{`a`, query.Files}: {
Query: Q(`suite:a`),
Children: Children{
query.TreeNodeChildKey{`b`, query.Files}: {
Query: Q(`suite:a,b`),
Children: Children{
query.TreeNodeChildKey{`c`, query.Tests}: {
Query: Q(`suite:a,b:c`),
Children: Children{
query.TreeNodeChildKey{`*`, query.Cases}: {
Query: Q(`suite:a,b:c:*`),
Data: &pass,
},
},
},
},
},
},
},
},
},
},
},
},
},
{ /////////////////////////////////////////////////////////////////////
in: QueryData{
Query: Q(`suite:a,b,c:d,e:f="g";h=[1,2,3];i=4;*`),
Data: pass,
},
expect: Tree{
TreeNode: Node{
Children: Children{
query.TreeNodeChildKey{`suite`, query.Suite}: {
Query: Q(`suite`),
Children: Children{
query.TreeNodeChildKey{`a`, query.Files}: {
Query: Q(`suite:a`),
Children: Children{
query.TreeNodeChildKey{`b`, query.Files}: {
Query: Q(`suite:a,b`),
Children: Children{
query.TreeNodeChildKey{`c`, query.Files}: {
Query: Q(`suite:a,b,c`),
Children: Children{
query.TreeNodeChildKey{`d`, query.Tests}: {
Query: Q(`suite:a,b,c:d`),
Children: Children{
query.TreeNodeChildKey{`e`, query.Tests}: {
Query: Q(`suite:a,b,c:d,e`),
Children: Children{
query.TreeNodeChildKey{`f="g";h=[1,2,3];i=4;*`, query.Cases}: {
Query: Q(`suite:a,b,c:d,e:f="g";h=[1,2,3];i=4;*`),
Data: &pass,
},
},
},
},
},
},
},
},
},
},
},
},
},
},
},
},
},
{ /////////////////////////////////////////////////////////////////////
in: QueryData{
Query: Q(`suite:a,b:c:d="e";*`), Data: pass,
},
expect: Tree{
TreeNode: Node{
Children: Children{
query.TreeNodeChildKey{`suite`, query.Suite}: {
Query: Q(`suite`),
Children: Children{
query.TreeNodeChildKey{`a`, query.Files}: {
Query: Q(`suite:a`),
Children: Children{
query.TreeNodeChildKey{`b`, query.Files}: {
Query: Q(`suite:a,b`),
Children: Children{
query.TreeNodeChildKey{`c`, query.Tests}: {
Query: Q(`suite:a,b:c`),
Children: Children{
query.TreeNodeChildKey{`d="e";*`, query.Cases}: {
Query: Q(`suite:a,b:c:d="e";*`),
Data: &pass,
},
},
},
},
},
},
},
},
},
},
},
},
},
} {
got, err := NewTree(t, test.in)
if err != nil {
t.Errorf("NewTree(%v): %v", test.in, err)
continue
}
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("NewTree(%v) tree was not as expected:\n%v", test.in, diff)
}
}
}
func TestNewMultiple(t *testing.T) {
type Tree = query.Tree[string]
type Node = query.TreeNode[string]
type QueryData = query.QueryData[string]
type Children = query.TreeNodeChildren[string]
got, err := NewTree(t,
QueryData{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
QueryData{Query: Q(`suite:h,b:c:f="g";*`), Data: abort},
QueryData{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
)
if err != nil {
t.Fatalf("NewTree() returned %v", err)
}
expect := Tree{
TreeNode: Node{
Children: Children{
query.TreeNodeChildKey{`suite`, query.Suite}: {
Query: Q(`suite`),
Children: Children{
query.TreeNodeChildKey{`a`, query.Files}: {
Query: Q(`suite:a`),
Children: Children{
query.TreeNodeChildKey{`b`, query.Files}: {
Query: Q(`suite:a,b`),
Children: Children{
query.TreeNodeChildKey{`c`, query.Tests}: {
Query: Q(`suite:a,b:c`),
Children: Children{
query.TreeNodeChildKey{`d="e";*`, query.Cases}: {
Query: Q(`suite:a,b:c:d="e";*`),
Data: &failure,
},
query.TreeNodeChildKey{`f="g";*`, query.Cases}: {
Query: Q(`suite:a,b:c:f="g";*`),
Data: &skip,
},
},
},
},
},
},
},
query.TreeNodeChildKey{`h`, query.Files}: {
Query: query.Query{
Suite: `suite`,
Files: `h`,
},
Children: Children{
query.TreeNodeChildKey{`b`, query.Files}: {
Query: query.Query{
Suite: `suite`,
Files: `h,b`,
},
Children: Children{
query.TreeNodeChildKey{`c`, query.Tests}: {
Query: query.Query{
Suite: `suite`,
Files: `h,b`,
Tests: `c`,
},
Children: Children{
query.TreeNodeChildKey{`f="g";*`, query.Cases}: {
Query: query.Query{
Suite: `suite`,
Files: `h,b`,
Tests: `c`,
Cases: `f="g";*`,
},
Data: &abort,
},
},
},
},
},
},
},
},
},
},
},
}
if diff := cmp.Diff(got, expect); diff != "" {
t.Errorf("NewTree() was not as expected:\n%v", diff)
t.Errorf("got:\n%v", got)
t.Errorf("expect:\n%v", expect)
}
}
func TestNewWithCollision(t *testing.T) {
type Tree = query.Tree[string]
type QueryData = query.QueryData[string]
got, err := NewTree(t,
QueryData{Query: Q(`suite:a,b:c:*`), Data: failure},
QueryData{Query: Q(`suite:a,b:c:*`), Data: skip},
)
expect := Tree{}
expectErr := query.ErrDuplicateData{
Query: Q(`suite:a,b:c:*`),
}
if diff := cmp.Diff(err, expectErr); diff != "" {
t.Errorf("NewTree() error was not as expected:\n%v", diff)
}
if diff := cmp.Diff(got, expect); diff != "" {
t.Errorf("NewTree() was not as expected:\n%v", diff)
}
}
func TestGlob(t *testing.T) {
type QueryData = query.QueryData[string]
tree, err := NewTree(t,
QueryData{Query: Q(`suite:*`), Data: skip},
QueryData{Query: Q(`suite:a,*`), Data: failure},
QueryData{Query: Q(`suite:a,b,*`), Data: failure},
QueryData{Query: Q(`suite:a,b:c:d;*`), Data: failure},
QueryData{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
QueryData{Query: Q(`suite:h,b:c:f="g";*`), Data: abort},
QueryData{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
QueryData{Query: Q(`suite:a,b:d:*`), Data: failure},
)
if err != nil {
t.Fatalf("NewTree() returned %v", err)
}
type Test struct {
query query.Query
expect []QueryData
expectErr error
}
for _, test := range []Test{
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite`),
expect: []QueryData{
{Query: Q(`suite:*`), Data: skip},
{Query: Q(`suite:a,*`), Data: failure},
{Query: Q(`suite:a,b,*`), Data: failure},
{Query: Q(`suite:a,b:c:d;*`), Data: failure},
{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
{Query: Q(`suite:a,b:d:*`), Data: failure},
{Query: Q(`suite:h,b:c:f="g";*`), Data: abort},
},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:*`),
expect: []QueryData{
{Query: Q(`suite:*`), Data: skip},
{Query: Q(`suite:a,*`), Data: failure},
{Query: Q(`suite:a,b,*`), Data: failure},
{Query: Q(`suite:a,b:c:d;*`), Data: failure},
{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
{Query: Q(`suite:a,b:d:*`), Data: failure},
{Query: Q(`suite:h,b:c:f="g";*`), Data: abort},
},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:a`),
expect: []QueryData{
{Query: Q(`suite:a,*`), Data: failure},
{Query: Q(`suite:a,b,*`), Data: failure},
{Query: Q(`suite:a,b:c:d;*`), Data: failure},
{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
{Query: Q(`suite:a,b:d:*`), Data: failure},
},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:a,*`),
expect: []QueryData{
{Query: Q(`suite:a,*`), Data: failure},
{Query: Q(`suite:a,b,*`), Data: failure},
{Query: Q(`suite:a,b:c:d;*`), Data: failure},
{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
{Query: Q(`suite:a,b:d:*`), Data: failure},
},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:a,b`),
expect: []QueryData{
{Query: Q(`suite:a,b,*`), Data: failure},
{Query: Q(`suite:a,b:c:d;*`), Data: failure},
{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
{Query: Q(`suite:a,b:d:*`), Data: failure},
},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:a,b,*`),
expect: []QueryData{
{Query: Q(`suite:a,b,*`), Data: failure},
},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:a,b:c:*`),
expect: []QueryData{
{Query: Q(`suite:a,b:c:d;*`), Data: failure},
{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:a,b:c`),
expect: []QueryData{
{Query: Q(`suite:a,b:c:d;*`), Data: failure},
{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:a,b:c:d="e";*`),
expect: []QueryData{
{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:a,b:c:d;*`),
expect: []QueryData{
{Query: Q(`suite:a,b:c:d;*`), Data: failure},
{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:a,b:c:f="g";*`),
expect: []QueryData{
{Query: Q(`suite:a,b:c:d;*`), Data: failure},
{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:x,y`),
expectErr: query.ErrNoDataForQuery{Q(`suite:x`)},
},
{ //////////////////////////////////////////////////////////////////////
query: Q(`suite:a,b:x`),
expectErr: query.ErrNoDataForQuery{Q(`suite:a,b:x`)},
},
} {
got, err := tree.Glob(test.query)
if diff := cmp.Diff(err, test.expectErr); diff != "" {
t.Errorf("Glob('%v') error: %v", test.query, err)
continue
}
if diff := cmp.Diff(got, test.expect); diff != "" {
t.Errorf("Glob('%v'):\n%v", test.query, diff)
}
}
}
func TestFormat(t *testing.T) {
type QueryData = query.QueryData[string]
tree, err := NewTree(t,
QueryData{Query: Q(`suite:*`), Data: skip},
QueryData{Query: Q(`suite:a,*`), Data: failure},
QueryData{Query: Q(`suite:a,b,*`), Data: failure},
QueryData{Query: Q(`suite:a,b:c:d;*`), Data: failure},
QueryData{Query: Q(`suite:a,b:c:d="e";*`), Data: failure},
QueryData{Query: Q(`suite:h,b:c:f="g";*`), Data: abort},
QueryData{Query: Q(`suite:a,b:c:f="g";*`), Data: skip},
QueryData{Query: Q(`suite:a,b:d:*`), Data: failure},
)
if err != nil {
t.Fatalf("NewTree() returned %v", err)
}
callA := fmt.Sprint(tree)
callB := fmt.Sprint(tree)
if diff := cmp.Diff(callA, callB); diff != "" {
t.Errorf("Format():\n%v", diff)
}
}