1package imapserver
2
3import (
4 "testing"
5
6 "github.com/mjl-/mox/store"
7)
8
9func TestNumSetContains(t *testing.T) {
10 num := func(v uint32) *setNumber {
11 return &setNumber{v, false}
12 }
13 star := &setNumber{star: true}
14
15 check := func(v bool) {
16 t.Helper()
17 if !v {
18 t.Fatalf("bad")
19 }
20 }
21
22 ss0 := numSet{true, nil} // "$"
23 check(ss0.containsSeq(1, []store.UID{2}, []store.UID{2}))
24 check(!ss0.containsSeq(1, []store.UID{2}, []store.UID{}))
25
26 check(ss0.containsUID(1, []store.UID{1}, []store.UID{1}))
27 check(ss0.containsUID(2, []store.UID{1, 2, 3}, []store.UID{2}))
28 check(!ss0.containsUID(2, []store.UID{1, 2, 3}, []store.UID{}))
29 check(!ss0.containsUID(2, []store.UID{}, []store.UID{2}))
30
31 ss1 := numSet{false, []numRange{{*num(1), nil}}} // Single number 1.
32 check(ss1.containsSeq(1, []store.UID{2}, nil))
33 check(!ss1.containsSeq(2, []store.UID{1, 2}, nil))
34
35 check(ss1.containsUID(1, []store.UID{1}, nil))
36 check(ss1.containsSeq(1, []store.UID{2}, nil))
37 check(!ss1.containsSeq(2, []store.UID{1, 2}, nil))
38
39 // 2:*
40 ss2 := numSet{false, []numRange{{*num(2), star}}}
41 check(ss2.containsSeq(1, []store.UID{2}, nil))
42 check(!ss2.containsSeq(2, []store.UID{2}, nil))
43 check(ss2.containsSeq(2, []store.UID{4, 5}, nil))
44 check(ss2.containsSeq(3, []store.UID{4, 5, 6}, nil))
45 check(!ss2.containsSeq(4, []store.UID{4, 5, 6}, nil))
46
47 check(ss2.containsUID(2, []store.UID{2}, nil))
48 check(!ss2.containsUID(1, []store.UID{1, 2, 3}, nil))
49 check(ss2.containsUID(3, []store.UID{1, 2, 3}, nil))
50 check(!ss2.containsUID(2, []store.UID{4, 5}, nil))
51 check(!ss2.containsUID(2, []store.UID{1}, nil))
52
53 check(ss2.containsUID(2, []store.UID{2, 6}, nil))
54 check(ss2.containsUID(6, []store.UID{2, 6}, nil))
55
56 // *:2, same as 2:*
57 ss3 := numSet{false, []numRange{{*star, num(2)}}}
58 check(ss3.containsSeq(1, []store.UID{2}, nil))
59 check(!ss3.containsSeq(2, []store.UID{2}, nil))
60 check(ss3.containsSeq(2, []store.UID{4, 5}, nil))
61 check(ss3.containsSeq(3, []store.UID{4, 5, 6}, nil))
62 check(!ss3.containsSeq(4, []store.UID{4, 5, 6}, nil))
63
64 check(ss3.containsUID(2, []store.UID{2}, nil))
65 check(!ss3.containsUID(1, []store.UID{1, 2, 3}, nil))
66 check(ss3.containsUID(3, []store.UID{1, 2, 3}, nil))
67 check(!ss3.containsUID(2, []store.UID{4, 5}, nil))
68 check(!ss3.containsUID(2, []store.UID{1}, nil))
69
70 check(ss3.containsUID(2, []store.UID{2, 6}, nil))
71 check(ss3.containsUID(6, []store.UID{2, 6}, nil))
72}
73
74func TestNumSetInterpret(t *testing.T) {
75 parseNumSet := func(s string) numSet {
76 p := parser{upper: s}
77 return p.xnumSet0(true, false)
78 }
79
80 checkEqual := func(uids []store.UID, a, s string) {
81 t.Helper()
82 n := parseNumSet(a).interpretStar(uids)
83 ns := n.String()
84 if ns != s {
85 t.Fatalf("%s != %s", ns, s)
86 }
87 }
88
89 checkEqual([]store.UID{}, "1:*", "")
90 checkEqual([]store.UID{1}, "1:*", "1")
91 checkEqual([]store.UID{1, 3}, "1:*", "1:3")
92 checkEqual([]store.UID{1, 3}, "4:*", "3")
93 checkEqual([]store.UID{1, 3}, "*:4", "3")
94 checkEqual([]store.UID{2, 3}, "*:4", "3")
95 checkEqual([]store.UID{2, 3}, "*:1", "1:3")
96 checkEqual([]store.UID{2, 3}, "1:*", "1:3")
97 checkEqual([]store.UID{1, 2, 3}, "1,2,3", "1,2,3")
98 checkEqual([]store.UID{}, "1,2,3", "")
99 checkEqual([]store.UID{}, "1:3", "")
100 checkEqual([]store.UID{}, "3:1", "")
101
102 iter := parseNumSet("1:3").interpretStar([]store.UID{}).newIter()
103 if _, ok := iter.Next(); ok {
104 t.Fatalf("expected immediate end for empty iter")
105 }
106
107 iter = parseNumSet("3:1").interpretStar([]store.UID{1, 2}).newIter()
108 v0, _ := iter.Next()
109 v1, _ := iter.Next()
110 _, ok := iter.Next()
111 if v0 != 1 || v1 != 2 || ok {
112 t.Fatalf("got %v %v %v, expected 1, 2, false", v0, v1, ok)
113 }
114}
115