From 6e909014e6826e14d629e4e49c51394b27a9094e Mon Sep 17 00:00:00 2001 From: clsr Date: Fri, 25 Aug 2017 15:06:28 +0200 Subject: Implement draft/cnm-selector --- selector_test.go | 305 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 selector_test.go (limited to 'selector_test.go') 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()) +} -- cgit