From d50eb4d0e5298c5ba8209346c485f636e44b4a0a Mon Sep 17 00:00:00 2001 From: zhengchun Date: Sat, 2 Nov 2019 12:44:01 +0800 Subject: [PATCH] fix #38 `MustCompile` method will return `nopQuery` object instead of `nil` when input expr is an invalid XPath expression. --- query.go | 11 +++++++++++ xpath.go | 2 +- xpath_test.go | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/query.go b/query.go index cc293d9..7826245 100644 --- a/query.go +++ b/query.go @@ -22,6 +22,17 @@ type query interface { Clone() query } +// nopQuery is an empty query that always return nil for any query. +type nopQuery struct { + query +} + +func (nopQuery) Select(iterator) NodeNavigator { return nil } + +func (nopQuery) Evaluate(iterator) interface{} { return nil } + +func (nopQuery) Clone() query { return nopQuery{} } + // contextQuery is returns current node on the iterator object query. type contextQuery struct { count int diff --git a/xpath.go b/xpath.go index 7e3f52c..d6c9912 100644 --- a/xpath.go +++ b/xpath.go @@ -151,7 +151,7 @@ func Compile(expr string) (*Expr, error) { func MustCompile(expr string) *Expr { exp, err := Compile(expr) if err != nil { - return nil + return &Expr{s: expr, q: nopQuery{}} } return exp } diff --git a/xpath_test.go b/xpath_test.go index 0d50f91..c682d41 100644 --- a/xpath_test.go +++ b/xpath_test.go @@ -30,6 +30,22 @@ func TestCompile(t *testing.T) { t.Fatalf("/a/b/(c, .[not(c)]) should be correct but got error %s", err) } } + +func TestMustCompile(t *testing.T) { + expr := MustCompile("//") + if expr == nil { + t.Fatal("// should be compiled but got nil object") + } + + if wanted := (nopQuery{}); expr.q != wanted { + t.Fatalf("wanted nopQuery object but got %s", expr) + } + iter := expr.Select(createNavigator(html)) + if iter.MoveNext() { + t.Fatal("should be an empty node list but got one") + } +} + func TestSelf(t *testing.T) { testXPath(t, html, ".", "html") testXPath(t, html.FirstChild, ".", "head")