Skip to content

Commit 56bb8fb

Browse files
committed
Bug fixes
1 parent 3286bce commit 56bb8fb

File tree

8 files changed

+71
-64
lines changed

8 files changed

+71
-64
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"cSpell.words": [
3+
"arraystack",
34
"autoplay",
45
"Combinators",
56
"DOCTYPEDTD",

FUTURE-CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
## v0.0.3
2-
- Combinators
2+
- Write test for (closest, QuerySelector, QuerySelectorAll)
3+
- Serializer bug fix

node-tree.go

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,9 @@ func (node *Node) IsTextNode() bool {
207207
return node.GetTagName() == ""
208208
}
209209

210-
// Closest traverses the node tree and its parents (heading toward the root node) until it finds a node that matches the full query.
211-
/*
212-
Ex:
213-
query = "div .video-container #div"
214-
215-
<div class="video-container id="div"></div>
216-
217-
As shown elements with every described specifiers will only match.
218-
But this is not the case for QuerySearch, QuerySelector and QuerySelectorAll.
219-
*/
210+
// Closest traverses the node tree and its parents (heading toward the root node) until it finds a node that matches the selector and returns that node.
220211
// Adapted from [https://developer.mozilla.org/en-US/docs/Web/API/Element/closest](MDN Element: closest() method)
221-
func (node *Node) Closest(query string) *Node {
212+
func (node *Node) Closest(selector string) *Node {
222213
traverser := NewTraverser(node)
223214

224215
return traverser.GetCurrentNode()

querying.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,8 @@ func (node *Node) GetElementsById(idName string) NodeList {
101101
}
102102

103103
/*
104-
QuerySearch tokenizes the query string and search for nodes that matches with the right most query token. After matching right most query it proceeds to match nodes parents nodes for left over tokens and then passed that node to (yield/range). QuerySearch search the whole node tree for matches unless yield get canceled or range iterator get cancel.
105-
*/
106-
104+
QuerySearch search returns a iterator that traverse through the node tree from given node and passes nodes that matches the given selector.
105+
*/
107106
func QuerySearch(node *Node, selector string) iter.Seq[*Node] {
108107
traverser := NewTraverser(node)
109108
return func(yield func(node *Node) bool) {
@@ -130,18 +129,18 @@ func matchFromRightMostSelectors(node *Node, selectorTokens []CombinatorEl) bool
130129
}
131130

132131

133-
// QuerySelector only returns the first node that matches with the QuerySearch.
134-
func (node *Node) QuerySelector(query string) *Node {
135-
iter := QuerySearch(node, query)
132+
// QuerySelector returns the first node that matches with the selector from the node.
133+
func (node *Node) QuerySelector(selector string) *Node {
134+
iter := QuerySearch(node, selector)
136135
for node := range iter {
137136
return node
138137
}
139138
return nil
140139
}
141140

142-
// QuerySelectorAll stores nodes passed down by QuerySearch in a nodeList and returns the nodeList.
143-
func (node *Node) QuerySelectorAll(query string) NodeList {
144-
iter := QuerySearch(node, query)
141+
// QuerySelectorAll returns a NodeList that has node that matches the selector form the node.
142+
func (node *Node) QuerySelectorAll(selector string) NodeList {
143+
iter := QuerySearch(node, selector)
145144
nodeList := NewNodeList()
146145

147146
for node := range iter {

querying_test.go

Lines changed: 47 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"os"
55
"testing"
66

7-
"github.com/emirpasic/gods/stacks/linkedliststack"
7+
Stack "github.com/emirpasic/gods/stacks/arraystack"
88
GoHtml "github.com/udan-jayanith/GoHTML"
99
)
1010

@@ -80,7 +80,7 @@ func TestGetElementsByClassName(t *testing.T) {
8080

8181
nodeList := node.GetElementsByClassName("ordered-item")
8282
iterator := nodeList.IterNodeList()
83-
stack := linkedliststack.New()
83+
stack := Stack.New()
8484
stack.Push("Mango")
8585
stack.Push("Orange")
8686
stack.Push("Apple")
@@ -122,7 +122,7 @@ func TestGetElementsById(t *testing.T) {
122122

123123
nodeList := node.GetElementsById("idElement")
124124
iter := nodeList.IterNodeList()
125-
stack := linkedliststack.New()
125+
stack := Stack.New()
126126
stack.Push("Lorem")
127127
stack.Push("")
128128

@@ -138,48 +138,62 @@ func TestGetElementsById(t *testing.T) {
138138
}
139139
}
140140

141-
func TestQuerySelector(t *testing.T) {
142-
node, err := testFile4NodeTree()
141+
func testFile5NodeTree() (*GoHtml.Node, error) {
142+
file, err := os.Open("test-files/5.html")
143143
if err != nil {
144-
t.Fatal(err)
145-
return
144+
return nil, err
146145
}
147-
node = node.QuerySelector("html ol li")
148-
if node == nil {
149-
t.Fatal("Node is nill after QuerySelector")
150-
} else if node.GetInnerText() != "Apple" {
151-
t.Log(node)
152-
t.Fatal("Unexpected text")
146+
147+
node, _ := GoHtml.Decode(file)
148+
return node, nil
149+
}
150+
151+
func TestQuerySelector(t *testing.T) {
152+
rootNode, _ := testFile5NodeTree()
153+
if rootNode == nil {
154+
t.Fatal("Node is nil")
153155
}
156+
157+
node := rootNode.QuerySelector("#list .item")
158+
if node == nil {
159+
t.Fatal("Node is nil after querying.")
160+
} else if node.GetInnerText() != "One" {
161+
t.Fatal("Node contains unexpected inner text. Expected One but got", node.GetInnerText())
162+
}
163+
//TODO: write test for testcases below.
164+
/*
165+
t.Log(rootNode.QuerySelector("body p"))
166+
t.Log(rootNode.QuerySelector("html head > title"))
167+
t.Log(rootNode.QuerySelector("section+ul"))
168+
t.Log(rootNode.QuerySelector(".item~.last-item"))
169+
*/
154170
}
155171

172+
156173
func TestQuerySelectorAll(t *testing.T) {
157-
node, err := testFile4NodeTree()
174+
rootNode, err := testFile5NodeTree()
158175
if err != nil {
159176
t.Fatal(err)
160-
return
161177
}
162-
163-
nodeList := node.QuerySelectorAll(".unordered-list li")
164-
if nodeList.Len() == 0 {
165-
t.Fatal("Node list is empty")
166-
}else if nodeList.Len() != 3{
167-
t.Fatal("Extra node in the node list.", nodeList.Len())
178+
nodeList := rootNode.QuerySelectorAll("article h2")
179+
if nodeList.Len() != 2 {
180+
t.Fatal("Expected node list length of 2 but got", nodeList.Len())
168181
}
169-
stack := linkedliststack.New()
170-
stack.Push("Kottue")
171-
stack.Push("Pizza")
172-
stack.Push("Cake")
182+
183+
stack := Stack.New()
184+
stack.Push("Second Post (Draft)")
185+
stack.Push("First Post")
173186

174187
iter := nodeList.IterNodeList()
175-
for node := range iter{
176-
val, _ := stack.Pop()
177-
str := val.(string)
178-
if node.GetInnerText() != str{
179-
t.Fatal("Got unexpected text.", "Expected", str, "But got", node.GetInnerText())
180-
}else{
181-
t.Log(node.GetInnerText())
188+
for node := range iter {
189+
if stack.Size() == 0 {
190+
break
191+
}
192+
v, _ := stack.Pop()
193+
str := v.(string)
194+
if str != node.GetInnerText() {
195+
t.Fatal("Unexpected inner text from the node. Expected", str, "but got", node.GetInnerText())
182196
}
183197
}
184-
}
185198

199+
}

selectors.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package GoHtml
22

33
import (
44
"strings"
5-
65
"golang.org/x/net/html"
76
)
87

@@ -194,13 +193,13 @@ func (ce *CombinatorEl) getNextSibling(node *Node) *Node {
194193
}
195194

196195
func (ce *CombinatorEl) getSubsequentSibling(node *Node) *Node {
197-
if node == nil || !matchNode(node, ce.Selector2.selector, ce.Selector2.selectorType) {
196+
if node == nil || !matchNode(node, ce.Selector2.selectorName, ce.Selector2.selectorType) {
198197
return nil
199198
}
200199

201200
traverser := NewTraverser(node)
202201
for traverser.GetCurrentNode() != nil {
203-
if matchNode(traverser.GetCurrentNode(), ce.Selector1.selector, ce.Selector1.selectorType) {
202+
if matchNode(traverser.GetCurrentNode(), ce.Selector1.selectorName, ce.Selector1.selectorType) {
204203
return traverser.GetCurrentNode()
205204
}
206205
traverser.Previous()

selectors_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package GoHtml_test
22

3-
import(
3+
import (
44
"testing"
5-
"github.com/udan-jayanith/GoHTML"
5+
6+
GoHtml "github.com/udan-jayanith/GoHTML"
67
)
78

8-
func TestTokenizeSelector(t *testing.T){
9+
func TestTokenizeSelector(t *testing.T) {
910
slice := GoHtml.TokenizeSelectorsAndCombinators(".class-1 > .class-2 + .class-3 a")
10-
for _, el := range slice{
11-
t.Log(el)
11+
if len(slice) != 4 {
12+
t.Fatal("Exacted slice length of", 4, "but got", len(slice))
1213
}
13-
}
14+
}

test-files/5.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ <h2>First Post</h2>
1212
<a href="/readmore" class="btn primary">Read More</a>
1313
</article>
1414

15+
<hr>
1516
<article data-type="post draft" class="entry hidden">
1617
<h2>Second Post (Draft)</h2>
1718
<p class="text">Should be hidden but still queryable.</p>
@@ -22,7 +23,7 @@ <h2>Second Post (Draft)</h2>
2223
<ul id="list">
2324
<li class="item">One</li>
2425
<li class="item special">Two <span>extra</span></li>
25-
<li class="item">Three</li>
26+
<li class="item last-item">Three</li>
2627
</ul>
2728

2829
<form id="login" action="/login">

0 commit comments

Comments
 (0)