summaryrefslogtreecommitdiffstats
path: root/selector_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'selector_test.go')
-rw-r--r--selector_test.go305
1 files changed, 305 insertions, 0 deletions
diff --git a/selector_test.go b/selector_test.go
new file mode 100644
index 0000000..0c714dc
--- /dev/null
+++ b/selector_test.go
@@ -0,0 +1,305 @@
+package cnm
+
+import (
+ "bytes"
+ "strings"
+ "testing"
+)
+
+var (
+ sec11 = &SectionBlock{ContentBlock{
+ name: "section",
+ args: []string{"foo/bar"},
+ children: []Block{
+ &TextBlock{
+ Format: "pre",
+ Contents: TextPreContents{"qwe"},
+ },
+ },
+ }}
+ sec1 = &SectionBlock{ContentBlock{
+ name: "section",
+ args: []string{"bar"},
+ children: []Block{
+ sec11,
+ &TextBlock{
+ Format: "pre",
+ Contents: TextPreContents{"..."},
+ },
+ },
+ }}
+ sec31 = &SectionBlock{ContentBlock{
+ name: "section",
+ args: []string{"baz"},
+ children: []Block{
+ &TextBlock{
+ Format: "pre",
+ Contents: TextPreContents{"zxc"},
+ },
+ },
+ }}
+ sec322 = &SectionBlock{ContentBlock{
+ name: "section",
+ args: []string{"baz"},
+ children: []Block{
+ &TextBlock{
+ Format: "pre",
+ Contents: TextPreContents{"xyz"},
+ },
+ },
+ }}
+ sec32 = &SectionBlock{ContentBlock{
+ name: "section",
+ args: []string{"quux"},
+ children: []Block{
+ &TextBlock{
+ Format: "pre",
+ Contents: TextPreContents{"123"},
+ },
+ sec322,
+ },
+ }}
+ sec4 = &SectionBlock{ContentBlock{
+ name: "section",
+ args: []string{"foo/bar"},
+ children: []Block{
+ &TextBlock{
+ Format: "pre",
+ Contents: TextPreContents{"abc"},
+ },
+ },
+ }}
+ doc1 = &Document{
+ Title: "test title",
+ Content: &ContentBlock{
+ name: "content",
+ children: []Block{
+ sec1,
+ &TextBlock{
+ Format: "pre",
+ Contents: TextPreContents{"asd"},
+ },
+ &ListBlock{ContentBlock{
+ name: "list",
+ children: []Block{
+ sec31,
+ sec32,
+ &TextBlock{
+ Format: "pre",
+ Contents: TextPreContents{"rty"},
+ },
+ },
+ }},
+ sec4,
+ },
+ },
+ }
+
+ doc1Shallow = &Document{
+ Title: doc1.Title,
+ Content: &ContentBlock{
+ name: "content",
+ children: []Block{
+ &SectionBlock{ContentBlock{
+ name: "section",
+ args: sec1.Args(),
+ }},
+ doc1.Content.Children()[1],
+ &ListBlock{ContentBlock{
+ name: "list",
+ children: []Block{
+ &SectionBlock{ContentBlock{
+ name: "section",
+ args: sec31.Args(),
+ }},
+ &SectionBlock{ContentBlock{
+ name: "section",
+ args: sec32.Args(),
+ }},
+ doc1.Content.Children()[2].(ContainerBlock).Children()[2],
+ },
+ }},
+ &SectionBlock{ContentBlock{
+ name: "section",
+ args: sec4.Args(),
+ }},
+ },
+ },
+ }
+
+ sec1Shallow = &Document{Content: &ContentBlock{
+ name: "content",
+ children: []Block{
+ &SectionBlock{ContentBlock{
+ name: sec1.Name(),
+ args: sec1.Args(),
+ children: []Block{
+ &SectionBlock{ContentBlock{
+ name: "section",
+ args: sec11.Args(),
+ }},
+ sec1.Children()[1],
+ },
+ }},
+ },
+ }}
+)
+
+var selectTests = []struct {
+ sel string
+ doc *Document
+ res *Document
+}{
+ {"", doc1, doc1},
+ {"/", doc1, &Document{Content: doc1.Content}},
+ {"$", doc1, &Document{Content: doc1.Content}},
+ {"#", doc1, &Document{Content: doc1.Content}},
+
+ {"!", doc1, doc1Shallow},
+ {"!/", doc1, &Document{Content: doc1Shallow.Content}},
+ {"!$", doc1, &Document{Content: doc1Shallow.Content}},
+ {"!#", doc1, &Document{Content: doc1Shallow.Content}},
+
+ {"/bar", doc1, &Document{Content: &ContentBlock{
+ name: "content",
+ children: []Block{
+ sec1,
+ },
+ }}},
+ {"!/bar", doc1, sec1Shallow},
+ {"#bar", doc1, &Document{Content: &ContentBlock{
+ name: "content",
+ children: []Block{sec1},
+ }}},
+ {"!#bar", doc1, sec1Shallow},
+ {"$1", doc1, &Document{Content: &ContentBlock{
+ name: "content",
+ children: []Block{sec1},
+ }}},
+ {"!$1", doc1, sec1Shallow},
+}
+
+func TestSelect(t *testing.T) {
+ for _, v := range selectTests {
+ t.Run(strings.Replace(v.sel, "/", "_", -1), func(t *testing.T) {
+ res, err := v.doc.Select(v.sel)
+ if err != nil {
+ printTestDoc(t, v.doc)
+ t.Fatalf("Select(%q) on %#v:\nerror: %v", v.sel, v.doc, err)
+ }
+ if !documentEqual(t, res, v.res) {
+ t.Log("=============== doc")
+ printTestDoc(t, v.doc)
+ t.Log("=============== expect")
+ printTestDoc(t, v.res)
+ t.Log("=============== got")
+ printTestDoc(t, res)
+ t.Fatalf("Select(%q) on %#v:\nexpected: %#v\n got: %#v", v.sel, v.doc, v.res, res)
+ }
+ })
+ }
+}
+
+var selectBlockTests = []struct {
+ sel string
+ doc *Document
+ res Block
+ ind []int
+}{
+ {"", doc1, doc1, []int{}},
+
+ {"/", doc1, doc1.Content, []int{}},
+ {"/qwe", doc1, nil, nil},
+ {"/bar/qwe", doc1, nil, nil},
+ {"/bar/", doc1, nil, nil},
+ {"//", doc1, nil, nil},
+ {"/./", doc1, nil, nil},
+ {"/../", doc1, nil, nil},
+ {"/.", doc1, nil, nil},
+ {"/..", doc1, nil, nil},
+ {"/foo%2fbar", doc1, sec4, []int{3}},
+ {"/bar/foo%2fbar", doc1, sec11, []int{0, 0}},
+ {"/baz", doc1, sec31, []int{2, 0}},
+ {"/quux", doc1, sec32, []int{2, 1}},
+ {"/quux/baz", doc1, sec322, []int{2, 1, 1}},
+ {"/bar/baz", doc1, nil, nil},
+
+ {"$", doc1, doc1.Content, []int{}},
+ {"$0", doc1, nil, nil},
+ {"$1", doc1, sec1, []int{0}},
+ {"$1.1", doc1, sec11, []int{0, 0}},
+ {"$2", doc1, sec31, []int{2, 0}},
+ {"$3", doc1, sec32, []int{2, 1}},
+ {"$4", doc1, sec4, []int{3}},
+ {"$5", doc1, nil, nil},
+ {"$2.1", doc1, nil, nil},
+ {"$3.1", doc1, sec322, []int{2, 1, 1}},
+ {"$3.0", doc1, nil, nil},
+ {"$3.2", doc1, nil, nil},
+
+ {"#", doc1, doc1.Content, []int{}},
+ {"#qwe", doc1, nil, nil},
+ {"#bar", doc1, sec1, []int{0}},
+ {"#foo%2fbar", doc1, sec11, []int{0, 0}},
+ {"#baz", doc1, sec31, []int{2, 0}},
+ {"#quux", doc1, sec32, []int{2, 1}},
+}
+
+func TestSelectBlock(t *testing.T) {
+ for _, v := range selectBlockTests {
+ t.Run(strings.Replace(v.sel, "/", "_", -1), func(t *testing.T) {
+ ind, res, err := v.doc.SelectBlock(v.sel)
+ if err != nil {
+ printTestDoc(t, v.doc)
+ t.Fatalf("SelectBlock(%q) on %#v:\nerror: %v", v.sel, v.doc, err)
+ }
+ if !indicesEqual(t, ind, v.ind) {
+ printTestDoc(t, v.doc)
+ t.Fatalf("SelectBlock(%q) on %#v:\nexpected indices %#v, got %#v", v.sel, v.doc, v.ind, ind)
+ }
+ if !blockEqual(t, res, v.res) {
+ printTestDoc(t, v.doc)
+ t.Fatalf("SelectBlock(%q) on %#v:\nexpected: %#v\n got: %#v", v.sel, v.doc, v.res, res)
+ }
+ if doc, ok := res.(*Document); ok {
+ res = doc.Content
+ }
+ b := v.doc.SelectIndex(ind...)
+ if !blockEqual(t, b, res) {
+ printTestDoc(t, v.doc)
+ t.Fatalf("SelectIndex(%#v) (for %q):\nexpected: %#v\n got: %#v", ind, v.sel, res, b)
+ }
+ })
+ }
+}
+
+func indicesEqual(t *testing.T, a, b []int) bool {
+ if a == nil && b == nil {
+ return true
+ }
+ if a == nil || b == nil {
+ t.Log("indice slice nilness differs")
+ return false
+ }
+ if len(a) != len(b) {
+ t.Log("indice slice lengths differ")
+ return false
+ }
+ for i := range a {
+ if a[i] != b[i] {
+ t.Log("indice slice element differs")
+ return false
+ }
+ }
+ return true
+}
+
+func printTestDoc(t *testing.T, doc *Document) {
+ if doc == nil {
+ t.Log(doc)
+ return
+ }
+ var buf bytes.Buffer
+ doc.Write(&buf)
+ t.Log("\n" + buf.String())
+}