summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/net/html/node_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/golang.org/x/net/html/node_test.go')
-rw-r--r--vendor/golang.org/x/net/html/node_test.go146
1 files changed, 146 insertions, 0 deletions
diff --git a/vendor/golang.org/x/net/html/node_test.go b/vendor/golang.org/x/net/html/node_test.go
new file mode 100644
index 0000000..471102f
--- /dev/null
+++ b/vendor/golang.org/x/net/html/node_test.go
@@ -0,0 +1,146 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package html
+
+import (
+ "fmt"
+)
+
+// checkTreeConsistency checks that a node and its descendants are all
+// consistent in their parent/child/sibling relationships.
+func checkTreeConsistency(n *Node) error {
+ return checkTreeConsistency1(n, 0)
+}
+
+func checkTreeConsistency1(n *Node, depth int) error {
+ if depth == 1e4 {
+ return fmt.Errorf("html: tree looks like it contains a cycle")
+ }
+ if err := checkNodeConsistency(n); err != nil {
+ return err
+ }
+ for c := n.FirstChild; c != nil; c = c.NextSibling {
+ if err := checkTreeConsistency1(c, depth+1); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// checkNodeConsistency checks that a node's parent/child/sibling relationships
+// are consistent.
+func checkNodeConsistency(n *Node) error {
+ if n == nil {
+ return nil
+ }
+
+ nParent := 0
+ for p := n.Parent; p != nil; p = p.Parent {
+ nParent++
+ if nParent == 1e4 {
+ return fmt.Errorf("html: parent list looks like an infinite loop")
+ }
+ }
+
+ nForward := 0
+ for c := n.FirstChild; c != nil; c = c.NextSibling {
+ nForward++
+ if nForward == 1e6 {
+ return fmt.Errorf("html: forward list of children looks like an infinite loop")
+ }
+ if c.Parent != n {
+ return fmt.Errorf("html: inconsistent child/parent relationship")
+ }
+ }
+
+ nBackward := 0
+ for c := n.LastChild; c != nil; c = c.PrevSibling {
+ nBackward++
+ if nBackward == 1e6 {
+ return fmt.Errorf("html: backward list of children looks like an infinite loop")
+ }
+ if c.Parent != n {
+ return fmt.Errorf("html: inconsistent child/parent relationship")
+ }
+ }
+
+ if n.Parent != nil {
+ if n.Parent == n {
+ return fmt.Errorf("html: inconsistent parent relationship")
+ }
+ if n.Parent == n.FirstChild {
+ return fmt.Errorf("html: inconsistent parent/first relationship")
+ }
+ if n.Parent == n.LastChild {
+ return fmt.Errorf("html: inconsistent parent/last relationship")
+ }
+ if n.Parent == n.PrevSibling {
+ return fmt.Errorf("html: inconsistent parent/prev relationship")
+ }
+ if n.Parent == n.NextSibling {
+ return fmt.Errorf("html: inconsistent parent/next relationship")
+ }
+
+ parentHasNAsAChild := false
+ for c := n.Parent.FirstChild; c != nil; c = c.NextSibling {
+ if c == n {
+ parentHasNAsAChild = true
+ break
+ }
+ }
+ if !parentHasNAsAChild {
+ return fmt.Errorf("html: inconsistent parent/child relationship")
+ }
+ }
+
+ if n.PrevSibling != nil && n.PrevSibling.NextSibling != n {
+ return fmt.Errorf("html: inconsistent prev/next relationship")
+ }
+ if n.NextSibling != nil && n.NextSibling.PrevSibling != n {
+ return fmt.Errorf("html: inconsistent next/prev relationship")
+ }
+
+ if (n.FirstChild == nil) != (n.LastChild == nil) {
+ return fmt.Errorf("html: inconsistent first/last relationship")
+ }
+ if n.FirstChild != nil && n.FirstChild == n.LastChild {
+ // We have a sole child.
+ if n.FirstChild.PrevSibling != nil || n.FirstChild.NextSibling != nil {
+ return fmt.Errorf("html: inconsistent sole child's sibling relationship")
+ }
+ }
+
+ seen := map[*Node]bool{}
+
+ var last *Node
+ for c := n.FirstChild; c != nil; c = c.NextSibling {
+ if seen[c] {
+ return fmt.Errorf("html: inconsistent repeated child")
+ }
+ seen[c] = true
+ last = c
+ }
+ if last != n.LastChild {
+ return fmt.Errorf("html: inconsistent last relationship")
+ }
+
+ var first *Node
+ for c := n.LastChild; c != nil; c = c.PrevSibling {
+ if !seen[c] {
+ return fmt.Errorf("html: inconsistent missing child")
+ }
+ delete(seen, c)
+ first = c
+ }
+ if first != n.FirstChild {
+ return fmt.Errorf("html: inconsistent first relationship")
+ }
+
+ if len(seen) != 0 {
+ return fmt.Errorf("html: inconsistent forwards/backwards child list")
+ }
+
+ return nil
+}