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
|
package query_test
import (
"errors"
"slices"
"testing"
"github.com/jpappel/atlas/pkg/query"
)
const (
CAT_UNKNOWN = query.CAT_UNKNOWN
CAT_TITLE = query.CAT_TITLE
CAT_AUTHOR = query.CAT_AUTHOR
CAT_DATE = query.CAT_DATE
CAT_FILETIME = query.CAT_FILETIME
CAT_TAGS = query.CAT_TAGS
CAT_LINKS = query.CAT_LINKS
CAT_META = query.CAT_META
OP_UNKNOWN = query.OP_UNKNOWN
OP_EQ = query.OP_EQ
OP_AP = query.OP_AP
OP_NE = query.OP_NE
OP_LT = query.OP_LT
OP_LE = query.OP_LE
OP_GE = query.OP_GE
OP_GT = query.OP_GT
)
func TestParse(t *testing.T) {
tests := []struct {
name string
tokens []query.Token
want *query.Clause
wantErr error
}{{
"empty clause",
[]query.Token{
{Type: TOK_CLAUSE_START}, {Type: TOK_CLAUSE_AND}, {Type: TOK_CLAUSE_END},
},
&query.Clause{Operator: query.COP_AND},
nil,
}, {
"simple clause",
[]query.Token{
{Type: TOK_CLAUSE_START}, {Type: TOK_CLAUSE_AND},
{TOK_CAT_AUTHOR, "a"}, {TOK_OP_AP, ":"}, {TOK_VAL_STR, "ken thompson"},
{Type: TOK_CLAUSE_END},
},
&query.Clause{
Operator: query.COP_AND,
Statements: []query.Statement{
{Category: CAT_AUTHOR, Operator: OP_AP, Value: query.StringValue{"ken thompson"}},
},
},
nil,
}, {
"nested clause",
[]query.Token{
{Type: TOK_CLAUSE_START}, {Type: TOK_CLAUSE_AND},
{TOK_CAT_AUTHOR, "a"}, {TOK_OP_AP, ":"}, {TOK_VAL_STR, "Alonzo Church"},
{Type: TOK_CLAUSE_START}, {Type: TOK_CLAUSE_OR},
{TOK_CAT_AUTHOR, "a"}, {TOK_OP_EQ, "="}, {TOK_VAL_STR, "Alan Turing"},
{Type: TOK_CLAUSE_END},
{Type: TOK_CLAUSE_END},
},
&query.Clause{
Operator: query.COP_AND,
Statements: []query.Statement{
{Category: CAT_AUTHOR, Operator: OP_AP, Value: query.StringValue{"Alonzo Church"}},
},
Clauses: []*query.Clause{
{
Operator: query.COP_OR,
Statements: []query.Statement{
{Category: CAT_AUTHOR, Operator: OP_EQ, Value: query.StringValue{"Alan Turing"}},
},
},
},
},
nil,
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotC, gotErr := query.Parse(tt.tokens)
if !errors.Is(gotErr, tt.wantErr) {
t.Fatalf("Different parse error than expected: got %v, want %v", gotErr, tt.wantErr)
} else if gotErr != nil {
return
}
got := slices.Collect(gotC.DFS())
want := slices.Collect(tt.want.DFS())
gotL, wantL := len(got), len(want)
if gotL != wantL {
t.Errorf("Different number of clauses than expected: got %d, want %d", gotL, wantL)
}
for i := range min(gotL, wantL) {
gotC, wantC := got[i], want[i]
if gotC.Operator != wantC.Operator {
t.Error("Different clause operator than expected")
} else if !slices.EqualFunc(gotC.Statements, wantC.Statements,
func(s1, s2 query.Statement) bool {
return s1.Negated == s2.Negated && s1.Category == s2.Category && s1.Operator == s2.Operator && s1.Value.Compare(s2.Value) == 0
}) {
t.Error("Different statements than expected")
} else if len(gotC.Clauses) != len(wantC.Clauses) {
t.Error("Different number of child clauses than expected")
}
if t.Failed() {
t.Log("Got\n", gotC)
t.Log("Want\n", wantC)
break
}
}
})
}
}
|