This is the v1 version, had the v2 before.
This commit is contained in:
724
seqset_test.go
Normal file
724
seqset_test.go
Normal file
@@ -0,0 +1,724 @@
|
||||
package imap
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const max = ^uint32(0)
|
||||
|
||||
func TestSeqParser(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
out Seq
|
||||
ok bool
|
||||
}{
|
||||
// Invalid number
|
||||
{"", Seq{}, false},
|
||||
{" ", Seq{}, false},
|
||||
{"A", Seq{}, false},
|
||||
{"0", Seq{}, false},
|
||||
{" 1", Seq{}, false},
|
||||
{"1 ", Seq{}, false},
|
||||
{"*1", Seq{}, false},
|
||||
{"1*", Seq{}, false},
|
||||
{"-1", Seq{}, false},
|
||||
{"01", Seq{}, false},
|
||||
{"0x1", Seq{}, false},
|
||||
{"1 2", Seq{}, false},
|
||||
{"1,2", Seq{}, false},
|
||||
{"1.2", Seq{}, false},
|
||||
{"4294967296", Seq{}, false},
|
||||
|
||||
// Valid number
|
||||
{"*", Seq{0, 0}, true},
|
||||
{"1", Seq{1, 1}, true},
|
||||
{"42", Seq{42, 42}, true},
|
||||
{"1000", Seq{1000, 1000}, true},
|
||||
{"4294967295", Seq{max, max}, true},
|
||||
|
||||
// Invalid range
|
||||
{":", Seq{}, false},
|
||||
{"*:", Seq{}, false},
|
||||
{":*", Seq{}, false},
|
||||
{"1:", Seq{}, false},
|
||||
{":1", Seq{}, false},
|
||||
{"0:0", Seq{}, false},
|
||||
{"0:*", Seq{}, false},
|
||||
{"0:1", Seq{}, false},
|
||||
{"1:0", Seq{}, false},
|
||||
{"1:2 ", Seq{}, false},
|
||||
{"1: 2", Seq{}, false},
|
||||
{"1:2:", Seq{}, false},
|
||||
{"1:2,", Seq{}, false},
|
||||
{"1:2:3", Seq{}, false},
|
||||
{"1:2,3", Seq{}, false},
|
||||
{"*:4294967296", Seq{}, false},
|
||||
{"0:4294967295", Seq{}, false},
|
||||
{"1:4294967296", Seq{}, false},
|
||||
{"4294967296:*", Seq{}, false},
|
||||
{"4294967295:0", Seq{}, false},
|
||||
{"4294967296:1", Seq{}, false},
|
||||
{"4294967295:4294967296", Seq{}, false},
|
||||
|
||||
// Valid range
|
||||
{"*:*", Seq{0, 0}, true},
|
||||
{"1:*", Seq{1, 0}, true},
|
||||
{"*:1", Seq{1, 0}, true},
|
||||
{"2:2", Seq{2, 2}, true},
|
||||
{"2:42", Seq{2, 42}, true},
|
||||
{"42:2", Seq{2, 42}, true},
|
||||
{"*:4294967294", Seq{max - 1, 0}, true},
|
||||
{"*:4294967295", Seq{max, 0}, true},
|
||||
{"4294967294:*", Seq{max - 1, 0}, true},
|
||||
{"4294967295:*", Seq{max, 0}, true},
|
||||
{"1:4294967294", Seq{1, max - 1}, true},
|
||||
{"1:4294967295", Seq{1, max}, true},
|
||||
{"4294967295:1000", Seq{1000, max}, true},
|
||||
{"4294967294:4294967295", Seq{max - 1, max}, true},
|
||||
{"4294967295:4294967295", Seq{max, max}, true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
out, err := parseSeq(test.in)
|
||||
if !test.ok {
|
||||
if err == nil {
|
||||
t.Errorf("parseSeq(%q) expected error; got %q", test.in, out)
|
||||
}
|
||||
} else if err != nil {
|
||||
t.Errorf("parseSeq(%q) expected %q; got %v", test.in, test.out, err)
|
||||
} else if out != test.out {
|
||||
t.Errorf("parseSeq(%q) expected %q; got %q", test.in, test.out, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeqContainsLess(t *testing.T) {
|
||||
tests := []struct {
|
||||
s string
|
||||
q uint32
|
||||
contains bool
|
||||
less bool
|
||||
}{
|
||||
{"2", 0, false, true},
|
||||
{"2", 1, false, false},
|
||||
{"2", 2, true, false},
|
||||
{"2", 3, false, true},
|
||||
{"2", max, false, true},
|
||||
|
||||
{"*", 0, true, false},
|
||||
{"*", 1, false, false},
|
||||
{"*", 2, false, false},
|
||||
{"*", 3, false, false},
|
||||
{"*", max, false, false},
|
||||
|
||||
{"2:3", 0, false, true},
|
||||
{"2:3", 1, false, false},
|
||||
{"2:3", 2, true, false},
|
||||
{"2:3", 3, true, false},
|
||||
{"2:3", 4, false, true},
|
||||
{"2:3", 5, false, true},
|
||||
|
||||
{"2:4", 0, false, true},
|
||||
{"2:4", 1, false, false},
|
||||
{"2:4", 2, true, false},
|
||||
{"2:4", 3, true, false},
|
||||
{"2:4", 4, true, false},
|
||||
{"2:4", 5, false, true},
|
||||
|
||||
{"4:4294967295", 0, false, true},
|
||||
{"4:4294967295", 1, false, false},
|
||||
{"4:4294967295", 2, false, false},
|
||||
{"4:4294967295", 3, false, false},
|
||||
{"4:4294967295", 4, true, false},
|
||||
{"4:4294967295", 5, true, false},
|
||||
{"4:4294967295", max, true, false},
|
||||
|
||||
{"4:*", 0, true, false},
|
||||
{"4:*", 1, false, false},
|
||||
{"4:*", 2, false, false},
|
||||
{"4:*", 3, false, false},
|
||||
{"4:*", 4, true, false},
|
||||
{"4:*", 5, true, false},
|
||||
{"4:*", max, true, false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
s, err := parseSeq(test.s)
|
||||
if err != nil {
|
||||
t.Errorf("parseSeq(%q) unexpected error; %v", test.s, err)
|
||||
continue
|
||||
}
|
||||
if s.Contains(test.q) != test.contains {
|
||||
t.Errorf("%q.Contains(%d) expected %v", test.s, test.q, test.contains)
|
||||
}
|
||||
if s.Less(test.q) != test.less {
|
||||
t.Errorf("%q.Less(%d) expected %v", test.s, test.q, test.less)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeqMerge(T *testing.T) {
|
||||
tests := []struct {
|
||||
s, t, out string
|
||||
}{
|
||||
// Number with number
|
||||
{"1", "1", "1"},
|
||||
{"1", "2", "1:2"},
|
||||
{"1", "3", ""},
|
||||
{"1", "4294967295", ""},
|
||||
{"1", "*", ""},
|
||||
|
||||
{"4", "1", ""},
|
||||
{"4", "2", ""},
|
||||
{"4", "3", "3:4"},
|
||||
{"4", "4", "4"},
|
||||
{"4", "5", "4:5"},
|
||||
{"4", "6", ""},
|
||||
|
||||
{"4294967295", "4294967293", ""},
|
||||
{"4294967295", "4294967294", "4294967294:4294967295"},
|
||||
{"4294967295", "4294967295", "4294967295"},
|
||||
{"4294967295", "*", ""},
|
||||
|
||||
{"*", "1", ""},
|
||||
{"*", "2", ""},
|
||||
{"*", "4294967294", ""},
|
||||
{"*", "4294967295", ""},
|
||||
{"*", "*", "*"},
|
||||
|
||||
// Range with number
|
||||
{"1:3", "1", "1:3"},
|
||||
{"1:3", "2", "1:3"},
|
||||
{"1:3", "3", "1:3"},
|
||||
{"1:3", "4", "1:4"},
|
||||
{"1:3", "5", ""},
|
||||
{"1:3", "*", ""},
|
||||
|
||||
{"3:4", "1", ""},
|
||||
{"3:4", "2", "2:4"},
|
||||
{"3:4", "3", "3:4"},
|
||||
{"3:4", "4", "3:4"},
|
||||
{"3:4", "5", "3:5"},
|
||||
{"3:4", "6", ""},
|
||||
{"3:4", "*", ""},
|
||||
|
||||
{"2:3", "5", ""},
|
||||
{"2:4", "5", "2:5"},
|
||||
{"2:5", "5", "2:5"},
|
||||
{"2:6", "5", "2:6"},
|
||||
{"2:7", "5", "2:7"},
|
||||
{"2:*", "5", "2:*"},
|
||||
{"3:4", "5", "3:5"},
|
||||
{"3:5", "5", "3:5"},
|
||||
{"3:6", "5", "3:6"},
|
||||
{"3:7", "5", "3:7"},
|
||||
{"3:*", "5", "3:*"},
|
||||
{"4:5", "5", "4:5"},
|
||||
{"4:6", "5", "4:6"},
|
||||
{"4:7", "5", "4:7"},
|
||||
{"4:*", "5", "4:*"},
|
||||
{"5:6", "5", "5:6"},
|
||||
{"5:7", "5", "5:7"},
|
||||
{"5:*", "5", "5:*"},
|
||||
{"6:7", "5", "5:7"},
|
||||
{"6:*", "5", "5:*"},
|
||||
{"7:8", "5", ""},
|
||||
{"7:*", "5", ""},
|
||||
|
||||
{"3:4294967294", "1", ""},
|
||||
{"3:4294967294", "2", "2:4294967294"},
|
||||
{"3:4294967294", "3", "3:4294967294"},
|
||||
{"3:4294967294", "4", "3:4294967294"},
|
||||
{"3:4294967294", "4294967293", "3:4294967294"},
|
||||
{"3:4294967294", "4294967294", "3:4294967294"},
|
||||
{"3:4294967294", "4294967295", "3:4294967295"},
|
||||
{"3:4294967294", "*", ""},
|
||||
|
||||
{"3:4294967295", "1", ""},
|
||||
{"3:4294967295", "2", "2:4294967295"},
|
||||
{"3:4294967295", "3", "3:4294967295"},
|
||||
{"3:4294967295", "4", "3:4294967295"},
|
||||
{"3:4294967295", "4294967294", "3:4294967295"},
|
||||
{"3:4294967295", "4294967295", "3:4294967295"},
|
||||
{"3:4294967295", "*", ""},
|
||||
|
||||
{"1:4294967295", "1", "1:4294967295"},
|
||||
{"1:4294967295", "4294967295", "1:4294967295"},
|
||||
{"1:4294967295", "*", ""},
|
||||
|
||||
{"1:*", "1", "1:*"},
|
||||
{"1:*", "2", "1:*"},
|
||||
{"1:*", "4294967294", "1:*"},
|
||||
{"1:*", "4294967295", "1:*"},
|
||||
{"1:*", "*", "1:*"},
|
||||
|
||||
// Range with range
|
||||
{"5:8", "1:2", ""},
|
||||
{"5:8", "1:3", ""},
|
||||
{"5:8", "1:4", "1:8"},
|
||||
{"5:8", "1:5", "1:8"},
|
||||
{"5:8", "1:6", "1:8"},
|
||||
{"5:8", "1:7", "1:8"},
|
||||
{"5:8", "1:8", "1:8"},
|
||||
{"5:8", "1:9", "1:9"},
|
||||
{"5:8", "1:10", "1:10"},
|
||||
{"5:8", "1:11", "1:11"},
|
||||
{"5:8", "1:*", "1:*"},
|
||||
|
||||
{"5:8", "2:3", ""},
|
||||
{"5:8", "2:4", "2:8"},
|
||||
{"5:8", "2:5", "2:8"},
|
||||
{"5:8", "2:6", "2:8"},
|
||||
{"5:8", "2:7", "2:8"},
|
||||
{"5:8", "2:8", "2:8"},
|
||||
{"5:8", "2:9", "2:9"},
|
||||
{"5:8", "2:10", "2:10"},
|
||||
{"5:8", "2:11", "2:11"},
|
||||
{"5:8", "2:*", "2:*"},
|
||||
|
||||
{"5:8", "3:4", "3:8"},
|
||||
{"5:8", "3:5", "3:8"},
|
||||
{"5:8", "3:6", "3:8"},
|
||||
{"5:8", "3:7", "3:8"},
|
||||
{"5:8", "3:8", "3:8"},
|
||||
{"5:8", "3:9", "3:9"},
|
||||
{"5:8", "3:10", "3:10"},
|
||||
{"5:8", "3:11", "3:11"},
|
||||
{"5:8", "3:*", "3:*"},
|
||||
|
||||
{"5:8", "4:5", "4:8"},
|
||||
{"5:8", "4:6", "4:8"},
|
||||
{"5:8", "4:7", "4:8"},
|
||||
{"5:8", "4:8", "4:8"},
|
||||
{"5:8", "4:9", "4:9"},
|
||||
{"5:8", "4:10", "4:10"},
|
||||
{"5:8", "4:11", "4:11"},
|
||||
{"5:8", "4:*", "4:*"},
|
||||
|
||||
{"5:8", "5:6", "5:8"},
|
||||
{"5:8", "5:7", "5:8"},
|
||||
{"5:8", "5:8", "5:8"},
|
||||
{"5:8", "5:9", "5:9"},
|
||||
{"5:8", "5:10", "5:10"},
|
||||
{"5:8", "5:11", "5:11"},
|
||||
{"5:8", "5:*", "5:*"},
|
||||
|
||||
{"5:8", "6:7", "5:8"},
|
||||
{"5:8", "6:8", "5:8"},
|
||||
{"5:8", "6:9", "5:9"},
|
||||
{"5:8", "6:10", "5:10"},
|
||||
{"5:8", "6:11", "5:11"},
|
||||
{"5:8", "6:*", "5:*"},
|
||||
|
||||
{"5:8", "7:8", "5:8"},
|
||||
{"5:8", "7:9", "5:9"},
|
||||
{"5:8", "7:10", "5:10"},
|
||||
{"5:8", "7:11", "5:11"},
|
||||
{"5:8", "7:*", "5:*"},
|
||||
|
||||
{"5:8", "8:9", "5:9"},
|
||||
{"5:8", "8:10", "5:10"},
|
||||
{"5:8", "8:11", "5:11"},
|
||||
{"5:8", "8:*", "5:*"},
|
||||
|
||||
{"5:8", "9:10", "5:10"},
|
||||
{"5:8", "9:11", "5:11"},
|
||||
{"5:8", "9:*", "5:*"},
|
||||
|
||||
{"5:8", "10:11", ""},
|
||||
{"5:8", "10:*", ""},
|
||||
|
||||
{"1:*", "1:*", "1:*"},
|
||||
{"1:*", "2:*", "1:*"},
|
||||
{"1:*", "1:4294967294", "1:*"},
|
||||
{"1:*", "1:4294967295", "1:*"},
|
||||
{"1:*", "2:4294967295", "1:*"},
|
||||
|
||||
{"1:4294967295", "1:4294967294", "1:4294967295"},
|
||||
{"1:4294967295", "1:4294967295", "1:4294967295"},
|
||||
{"1:4294967295", "2:4294967295", "1:4294967295"},
|
||||
{"1:4294967295", "2:*", "1:*"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
s, err := parseSeq(test.s)
|
||||
if err != nil {
|
||||
T.Errorf("parseSeq(%q) unexpected error; %v", test.s, err)
|
||||
continue
|
||||
}
|
||||
t, err := parseSeq(test.t)
|
||||
if err != nil {
|
||||
T.Errorf("parseSeq(%q) unexpected error; %v", test.t, err)
|
||||
continue
|
||||
}
|
||||
test_ok := test.out != ""
|
||||
for i := 0; i < 2; i++ {
|
||||
if !test_ok {
|
||||
test.out = test.s
|
||||
}
|
||||
out, ok := s.Merge(t)
|
||||
if out.String() != test.out || ok != test_ok {
|
||||
T.Errorf("%q.Merge(%q) expected %q; got %q", test.s, test.t, test.out, out)
|
||||
}
|
||||
// Swap s & t, result should be identical
|
||||
test.s, test.t = test.t, test.s
|
||||
s, t = t, s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkSeqSet(s *SeqSet, t *testing.T) {
|
||||
n := len(s.Set)
|
||||
for i, v := range s.Set {
|
||||
if v.Start == 0 {
|
||||
if v.Stop != 0 {
|
||||
t.Errorf(`SeqSet(%q) index %d: "*:n" range`, s, i)
|
||||
} else if i != n-1 {
|
||||
t.Errorf(`SeqSet(%q) index %d: "*" not at the end`, s, i)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if i > 0 && s.Set[i-1].Stop >= v.Start-1 {
|
||||
t.Errorf(`SeqSet(%q) index %d: overlap`, s, i)
|
||||
}
|
||||
if v.Stop < v.Start {
|
||||
if v.Stop != 0 {
|
||||
t.Errorf(`SeqSet(%q) index %d: reversed range`, s, i)
|
||||
} else if i != n-1 {
|
||||
t.Errorf(`SeqSet(%q) index %d: "n:*" not at the end`, s, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeqSetInfo(t *testing.T) {
|
||||
tests := []struct {
|
||||
s string
|
||||
q uint32
|
||||
contains bool
|
||||
}{
|
||||
{"", 0, false},
|
||||
{"", 1, false},
|
||||
{"", 2, false},
|
||||
{"", 3, false},
|
||||
{"", max, false},
|
||||
|
||||
{"2", 0, false},
|
||||
{"2", 1, false},
|
||||
{"2", 2, true},
|
||||
{"2", 3, false},
|
||||
{"2", max, false},
|
||||
|
||||
{"*", 0, false}, // Contains("*") is always false, use Dynamic() instead
|
||||
{"*", 1, false},
|
||||
{"*", 2, false},
|
||||
{"*", 3, false},
|
||||
{"*", max, false},
|
||||
|
||||
{"1:*", 0, false},
|
||||
{"1:*", 1, true},
|
||||
{"1:*", max, true},
|
||||
|
||||
{"2:4", 0, false},
|
||||
{"2:4", 1, false},
|
||||
{"2:4", 2, true},
|
||||
{"2:4", 3, true},
|
||||
{"2:4", 4, true},
|
||||
{"2:4", 5, false},
|
||||
{"2:4", max, false},
|
||||
|
||||
{"2,4", 0, false},
|
||||
{"2,4", 1, false},
|
||||
{"2,4", 2, true},
|
||||
{"2,4", 3, false},
|
||||
{"2,4", 4, true},
|
||||
{"2,4", 5, false},
|
||||
{"2,4", max, false},
|
||||
|
||||
{"2:4,6", 0, false},
|
||||
{"2:4,6", 1, false},
|
||||
{"2:4,6", 2, true},
|
||||
{"2:4,6", 3, true},
|
||||
{"2:4,6", 4, true},
|
||||
{"2:4,6", 5, false},
|
||||
{"2:4,6", 6, true},
|
||||
{"2:4,6", 7, false},
|
||||
|
||||
{"2,4:6", 0, false},
|
||||
{"2,4:6", 1, false},
|
||||
{"2,4:6", 2, true},
|
||||
{"2,4:6", 3, false},
|
||||
{"2,4:6", 4, true},
|
||||
{"2,4:6", 5, true},
|
||||
{"2,4:6", 6, true},
|
||||
{"2,4:6", 7, false},
|
||||
|
||||
{"2,4,6", 0, false},
|
||||
{"2,4,6", 1, false},
|
||||
{"2,4,6", 2, true},
|
||||
{"2,4,6", 3, false},
|
||||
{"2,4,6", 4, true},
|
||||
{"2,4,6", 5, false},
|
||||
{"2,4,6", 6, true},
|
||||
{"2,4,6", 7, false},
|
||||
|
||||
{"1,3:5,7,9:*", 0, false},
|
||||
{"1,3:5,7,9:*", 1, true},
|
||||
{"1,3:5,7,9:*", 2, false},
|
||||
{"1,3:5,7,9:*", 3, true},
|
||||
{"1,3:5,7,9:*", 4, true},
|
||||
{"1,3:5,7,9:*", 5, true},
|
||||
{"1,3:5,7,9:*", 6, false},
|
||||
{"1,3:5,7,9:*", 7, true},
|
||||
{"1,3:5,7,9:*", 8, false},
|
||||
{"1,3:5,7,9:*", 9, true},
|
||||
{"1,3:5,7,9:*", 10, true},
|
||||
{"1,3:5,7,9:*", max, true},
|
||||
|
||||
{"1,3:5,7,9,42", 0, false},
|
||||
{"1,3:5,7,9,42", 1, true},
|
||||
{"1,3:5,7,9,42", 2, false},
|
||||
{"1,3:5,7,9,42", 3, true},
|
||||
{"1,3:5,7,9,42", 4, true},
|
||||
{"1,3:5,7,9,42", 5, true},
|
||||
{"1,3:5,7,9,42", 6, false},
|
||||
{"1,3:5,7,9,42", 7, true},
|
||||
{"1,3:5,7,9,42", 8, false},
|
||||
{"1,3:5,7,9,42", 9, true},
|
||||
{"1,3:5,7,9,42", 10, false},
|
||||
{"1,3:5,7,9,42", 41, false},
|
||||
{"1,3:5,7,9,42", 42, true},
|
||||
{"1,3:5,7,9,42", 43, false},
|
||||
{"1,3:5,7,9,42", max, false},
|
||||
|
||||
{"1,3:5,7,9,42,*", 0, false},
|
||||
{"1,3:5,7,9,42,*", 1, true},
|
||||
{"1,3:5,7,9,42,*", 2, false},
|
||||
{"1,3:5,7,9,42,*", 3, true},
|
||||
{"1,3:5,7,9,42,*", 4, true},
|
||||
{"1,3:5,7,9,42,*", 5, true},
|
||||
{"1,3:5,7,9,42,*", 6, false},
|
||||
{"1,3:5,7,9,42,*", 7, true},
|
||||
{"1,3:5,7,9,42,*", 8, false},
|
||||
{"1,3:5,7,9,42,*", 9, true},
|
||||
{"1,3:5,7,9,42,*", 10, false},
|
||||
{"1,3:5,7,9,42,*", 41, false},
|
||||
{"1,3:5,7,9,42,*", 42, true},
|
||||
{"1,3:5,7,9,42,*", 43, false},
|
||||
{"1,3:5,7,9,42,*", max, false},
|
||||
|
||||
{"1,3:5,7,9,42,60:70,100:*", 0, false},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 1, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 2, false},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 3, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 4, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 5, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 6, false},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 7, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 8, false},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 9, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 10, false},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 41, false},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 42, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 43, false},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 59, false},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 60, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 65, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 70, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 71, false},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 99, false},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 100, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", 1000, true},
|
||||
{"1,3:5,7,9,42,60:70,100:*", max, true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
s, _ := ParseSeqSet(test.s)
|
||||
checkSeqSet(s, t)
|
||||
if s.Contains(test.q) != test.contains {
|
||||
t.Errorf("%q.Contains(%v) expected %v", test.s, test.q, test.contains)
|
||||
}
|
||||
if str := s.String(); str != test.s {
|
||||
t.Errorf("%q.String() expected %q; got %q", test.s, test.s, str)
|
||||
}
|
||||
test_empty := len(test.s) == 0
|
||||
if s.Empty() != test_empty {
|
||||
t.Errorf("%q.Empty() expected %v", test.s, test_empty)
|
||||
}
|
||||
test_dynamic := !test_empty && test.s[len(test.s)-1] == '*'
|
||||
if s.Dynamic() != test_dynamic {
|
||||
t.Errorf("%q.Dynamic() expected %v", test.s, test_dynamic)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeqSetAdd(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
out string
|
||||
}{
|
||||
{"1,1", "1"},
|
||||
{"1,2", "1:2"},
|
||||
{"1,3", "1,3"},
|
||||
{"1,*", "1,*"},
|
||||
|
||||
{"1,1,1", "1"},
|
||||
{"1,1,2", "1:2"},
|
||||
{"1,1:2", "1:2"},
|
||||
{"1,1,3", "1,3"},
|
||||
{"1,1:3", "1:3"},
|
||||
{"1,2,2", "1:2"},
|
||||
{"1,2,3", "1:3"},
|
||||
{"1,2:3", "1:3"},
|
||||
{"1,2,4", "1:2,4"},
|
||||
{"1,3,3", "1,3"},
|
||||
{"1,3,4", "1,3:4"},
|
||||
{"1,3:4", "1,3:4"},
|
||||
{"1,3,5", "1,3,5"},
|
||||
{"1,3:5", "1,3:5"},
|
||||
{"1:3,5", "1:3,5"},
|
||||
{"1:5,3", "1:5"},
|
||||
|
||||
{"1,2,3,4", "1:4"},
|
||||
{"1,2,4,5", "1:2,4:5"},
|
||||
{"1,2,4:5", "1:2,4:5"},
|
||||
{"1:2,4:5", "1:2,4:5"},
|
||||
|
||||
{"1,2,3,4,5", "1:5"},
|
||||
{"1,2:3,4:5", "1:5"},
|
||||
|
||||
{"1,2,4,5,7,9", "1:2,4:5,7,9"},
|
||||
{"1,2,4,5,7:9", "1:2,4:5,7:9"},
|
||||
{"1:2,4:5,7:9", "1:2,4:5,7:9"},
|
||||
{"1,2,4,5,7,8,9", "1:2,4:5,7:9"},
|
||||
{"1:2,4:5,7,8,9", "1:2,4:5,7:9"},
|
||||
|
||||
{"3,5:10,15:20", "3,5:10,15:20"},
|
||||
{"4,5:10,15:20", "4:10,15:20"},
|
||||
{"5,5:10,15:20", "5:10,15:20"},
|
||||
{"7,5:10,15:20", "5:10,15:20"},
|
||||
{"10,5:10,15:20", "5:10,15:20"},
|
||||
{"11,5:10,15:20", "5:11,15:20"},
|
||||
{"12,5:10,15:20", "5:10,12,15:20"},
|
||||
{"14,5:10,15:20", "5:10,14:20"},
|
||||
{"17,5:10,15:20", "5:10,15:20"},
|
||||
{"21,5:10,15:20", "5:10,15:21"},
|
||||
{"22,5:10,15:20", "5:10,15:20,22"},
|
||||
{"*,5:10,15:20", "5:10,15:20,*"},
|
||||
|
||||
{"1:3,5:10,15:20", "1:3,5:10,15:20"},
|
||||
{"1:4,5:10,15:20", "1:10,15:20"},
|
||||
{"1:8,5:10,15:20", "1:10,15:20"},
|
||||
{"1:13,5:10,15:20", "1:13,15:20"},
|
||||
{"1:14,5:10,15:20", "1:20"},
|
||||
{"7:17,5:10,15:20", "5:20"},
|
||||
{"11:14,5:10,15:20", "5:20"},
|
||||
{"12,13,5:10,15:20", "5:10,12:13,15:20"},
|
||||
{"12:13,5:10,15:20", "5:10,12:13,15:20"},
|
||||
{"12:14,5:10,15:20", "5:10,12:20"},
|
||||
{"11:13,5:10,15:20", "5:13,15:20"},
|
||||
{"11,12,13,14,5:10,15:20", "5:20"},
|
||||
|
||||
{"1:*,5:10,15:20", "1:*"},
|
||||
{"4:*,5:10,15:20", "4:*"},
|
||||
{"6:*,5:10,15:20", "5:*"},
|
||||
{"12:*,5:10,15:20", "5:10,12:*"},
|
||||
{"19:*,5:10,15:20", "5:10,15:*"},
|
||||
|
||||
{"5:8,6,7:10,15,16,17,18:20,19,21:*", "5:10,15:*"},
|
||||
|
||||
{"4:13,1,5,10,15,20", "1,4:13,15,20"},
|
||||
{"4:14,1,5,10,15,20", "1,4:15,20"},
|
||||
{"4:15,1,5,10,15,20", "1,4:15,20"},
|
||||
{"4:16,1,5,10,15,20", "1,4:16,20"},
|
||||
{"4:17,1,5,10,15,20", "1,4:17,20"},
|
||||
{"4:18,1,5,10,15,20", "1,4:18,20"},
|
||||
{"4:19,1,5,10,15,20", "1,4:20"},
|
||||
{"4:20,1,5,10,15,20", "1,4:20"},
|
||||
{"4:21,1,5,10,15,20", "1,4:21"},
|
||||
{"4:*,1,5,10,15,20", "1,4:*"},
|
||||
|
||||
{"1,3,5,7,9,11,13,15,17,19", "1,3,5,7,9,11,13,15,17,19"},
|
||||
{"1,3,5,7,9,11:13,15,17,19", "1,3,5,7,9,11:13,15,17,19"},
|
||||
{"1,3,5,7,9:11,13:15,17,19", "1,3,5,7,9:11,13:15,17,19"},
|
||||
{"1,3,5,7:9,11:13,15:17,19", "1,3,5,7:9,11:13,15:17,19"},
|
||||
{"1,3,5,7,9,11,13,15,17,19,*", "1,3,5,7,9,11,13,15,17,19,*"},
|
||||
{"1,3,5,7,9,11,13,15,17,19:*", "1,3,5,7,9,11,13,15,17,19:*"},
|
||||
{"1:20,3,5,7,9,11,13,15,17,19,*", "1:20,*"},
|
||||
{"1:20,3,5,7,9,11,13,15,17,19:*", "1:*"},
|
||||
|
||||
{"4294967295,*", "4294967295,*"},
|
||||
{"1,4294967295,*", "1,4294967295,*"},
|
||||
{"1:4294967295,*", "1:4294967295,*"},
|
||||
{"1,4294967295:*", "1,4294967295:*"},
|
||||
{"1:*,4294967295", "1:*"},
|
||||
{"1:*,4294967295:*", "1:*"},
|
||||
{"1:4294967295,4294967295:*", "1:*"},
|
||||
}
|
||||
prng := rand.New(rand.NewSource(19860201))
|
||||
done := make(map[string]bool)
|
||||
permute := func(in string) string {
|
||||
v := strings.Split(in, ",")
|
||||
r := make([]string, len(v))
|
||||
|
||||
// Try to find a permutation that hasn't been checked already
|
||||
for i := 0; i < 50; i++ {
|
||||
for i, j := range prng.Perm(len(v)) {
|
||||
r[i] = v[j]
|
||||
}
|
||||
if s := strings.Join(r, ","); !done[s] {
|
||||
done[s] = true
|
||||
return s
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
for _, test := range tests {
|
||||
for i := 0; i < 100 && test.in != ""; i++ {
|
||||
s := &SeqSet{}
|
||||
if err := s.Add(test.in); err != nil {
|
||||
t.Errorf("Add(%q) unexpected error; %v", test.in, err)
|
||||
i = 100
|
||||
}
|
||||
checkSeqSet(s, t)
|
||||
if out := s.String(); out != test.out {
|
||||
t.Errorf("%q.String() expected %q; got %q", test.in, test.out, out)
|
||||
i = 100
|
||||
}
|
||||
test.in = permute(test.in)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSeqSetAddNumRangeSet(t *testing.T) {
|
||||
type num []uint32
|
||||
tests := []struct {
|
||||
num num
|
||||
rng Seq
|
||||
set string
|
||||
out string
|
||||
}{
|
||||
{num{5}, Seq{1, 3}, "1:2,5,7:13,15,17:*", "1:3,5,7:13,15,17:*"},
|
||||
{num{5}, Seq{3, 1}, "2:3,7:13,15,17:*", "1:3,5,7:13,15,17:*"},
|
||||
|
||||
{num{15}, Seq{17, 0}, "1:3,5,7:13", "1:3,5,7:13,15,17:*"},
|
||||
{num{15}, Seq{0, 17}, "1:3,5,7:13", "1:3,5,7:13,15,17:*"},
|
||||
|
||||
{num{1, 3, 5, 7, 9, 11, 0}, Seq{8, 13}, "2,15,17:*", "1:3,5,7:13,15,17:*"},
|
||||
{num{5, 1, 7, 3, 9, 0, 11}, Seq{8, 13}, "2,15,17:*", "1:3,5,7:13,15,17:*"},
|
||||
{num{5, 1, 7, 3, 9, 0, 11}, Seq{13, 8}, "2,15,17:*", "1:3,5,7:13,15,17:*"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
other, _ := ParseSeqSet(test.set)
|
||||
|
||||
s := &SeqSet{}
|
||||
s.AddNum(test.num...)
|
||||
checkSeqSet(s, t)
|
||||
s.AddRange(test.rng.Start, test.rng.Stop)
|
||||
checkSeqSet(s, t)
|
||||
s.AddSet(other)
|
||||
checkSeqSet(s, t)
|
||||
|
||||
if out := s.String(); out != test.out {
|
||||
t.Errorf("(%v + %v + %q).String() expected %q; got %q", test.num, test.rng, test.set, test.out, out)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user