@@ -91,26 +91,26 @@ func test_xpath_eval(t *testing.T, root *TNode, expr string, expected ...interfa
9191func Test_Predicates_MultiParent (t * testing.T ) {
9292 // https://github.com/antchfx/xpath/issues/75
9393 /*
94- <measCollecFile xmlns="http://www.3gpp.org/ftp/specs/archive/32_series/32.435#measCollec">
95- <measData>
96- <measInfo>
97- <measType p="1">field1</measType>
98- <measType p="2">field2</measType>
99- <measValue>
100- <r p="1">31854</r>
101- <r p="2">159773</r>
102- </measValue>
103- </measInfo>
104- <measInfo measInfoId="metric_name2">
105- <measType p="1">field3</measType>
106- <measType p="2">field4</measType>
107- <measValue>
108- <r p="1">1234</r>
109- <r p="2">567</r>
110- </measValue>
111- </measInfo>
112- </measData>
113- </measCollecFile>
94+ <measCollecFile xmlns="http://www.3gpp.org/ftp/specs/archive/32_series/32.435#measCollec">
95+ <measData>
96+ <measInfo>
97+ <measType p="1">field1</measType>
98+ <measType p="2">field2</measType>
99+ <measValue>
100+ <r p="1">31854</r>
101+ <r p="2">159773</r>
102+ </measValue>
103+ </measInfo>
104+ <measInfo measInfoId="metric_name2">
105+ <measType p="1">field3</measType>
106+ <measType p="2">field4</measType>
107+ <measValue>
108+ <r p="1">1234</r>
109+ <r p="2">567</r>
110+ </measValue>
111+ </measInfo>
112+ </measData>
113+ </measCollecFile>
114114 */
115115 doc := createNode ("" , RootNode )
116116 measCollecFile := doc .createChildNode ("measCollecFile" , ElementNode )
@@ -281,6 +281,88 @@ func TestNodeType(t *testing.T) {
281281 assertEqual (t , CommentNode , n .Type )
282282}
283283
284+ func TestCompileWithOptions_StrictEOF (t * testing.T ) {
285+ doc := createBookExample ()
286+
287+ testCases := []struct {
288+ name string
289+ expr string
290+ options CompileOptions
291+ wantErr bool
292+ wantLen int // -1 if not applicable
293+ }{
294+ {
295+ name : "StrictEOF: valid expression" ,
296+ expr : "//book" ,
297+ options : CompileOptions {StrictEOF : true },
298+ wantErr : false ,
299+ wantLen : 4 ,
300+ },
301+ {
302+ name : "StrictEOF: valid expression with predicate" ,
303+ expr : "//book[@category='web']" ,
304+ options : CompileOptions {StrictEOF : true },
305+ wantErr : false ,
306+ wantLen : 2 ,
307+ },
308+ {
309+ name : "StrictEOF: expression with extra trailing tokens returns error" ,
310+ expr : "//book,foo" ,
311+ options : CompileOptions {StrictEOF : true },
312+ wantErr : true ,
313+ wantLen : - 1 ,
314+ },
315+ {
316+ name : "StrictEOF: undeclared variable returns error" ,
317+ expr : "//book[$undeclared]" ,
318+ options : CompileOptions {StrictEOF : true },
319+ wantErr : true ,
320+ wantLen : - 1 ,
321+ },
322+ {
323+ name : "Default: expression with extra trailing tokens is accepted" ,
324+ expr : "//book,foo" ,
325+ options : CompileOptions {},
326+ wantErr : false ,
327+ wantLen : - 1 ,
328+ },
329+ {
330+ name : "StrictPreset: valid expression" ,
331+ expr : "//book/title" ,
332+ options : StrictPreset ,
333+ wantErr : false ,
334+ wantLen : 4 ,
335+ },
336+ {
337+ name : "StrictPreset: expression with extra trailing tokens returns error" ,
338+ expr : "//book/title,foo" ,
339+ options : StrictPreset ,
340+ wantErr : true ,
341+ wantLen : - 1 ,
342+ },
343+ }
344+
345+ for _ , tc := range testCases {
346+ t .Run (tc .name , func (t * testing.T ) {
347+ e , err := CompileWithOptions (tc .expr , tc .options )
348+ if tc .wantErr {
349+ if err == nil {
350+ t .Errorf ("expected error, got nil" )
351+ }
352+ return
353+ }
354+ if err != nil {
355+ t .Errorf ("unexpected error: %v" , err )
356+ return
357+ }
358+ if tc .wantLen >= 0 {
359+ nodes := iterateNodes (e .Select (createNavigator (doc )))
360+ assertEqual (t , tc .wantLen , len (nodes ))
361+ }
362+ })
363+ }
364+ }
365+
284366func iterateNavs (t * NodeIterator ) []* TNodeNavigator {
285367 var nodes []* TNodeNavigator
286368 for t .MoveNext () {
@@ -589,37 +671,37 @@ func (n *TNode) getAttribute(key string) string {
589671
590672func createBookExample () * TNode {
591673 /*
592- <?xml version="1.0" encoding="UTF-8"?>
593- <bookstore>
594- <book category="cooking">
595- <title lang="en">Everyday Italian</title>
596- <author>Giada De Laurentiis</author>
597- <year>2005</year>
598- <price>30.00</price>
599- </book>
600- <book category="children">
601- <title lang="en">Harry Potter</title>
602- <author>J K. Rowling</author>
603- <year>2005</year>
604- <price>29.99</price>
605- </book>
606- <book category="web">
607- <title lang="en">XQuery Kick Start</title>
608- <author>James McGovern</author>
609- <author>Per Bothner</author>
610- <author>Kurt Cagle</author>
611- <author>James Linn</author>
612- <author>Vaidyanathan Nagarajan</author>
613- <year>2003</year>
614- <price>49.99</price>
615- </book>
616- <book category="web">
617- <title lang="en">Learning XML</title>
618- <author>Erik T. Ray</author>
619- <year>2003</year>
620- <price>39.95</price>
621- </book>
622- </bookstore>
674+ <?xml version="1.0" encoding="UTF-8"?>
675+ <bookstore>
676+ <book category="cooking">
677+ <title lang="en">Everyday Italian</title>
678+ <author>Giada De Laurentiis</author>
679+ <year>2005</year>
680+ <price>30.00</price>
681+ </book>
682+ <book category="children">
683+ <title lang="en">Harry Potter</title>
684+ <author>J K. Rowling</author>
685+ <year>2005</year>
686+ <price>29.99</price>
687+ </book>
688+ <book category="web">
689+ <title lang="en">XQuery Kick Start</title>
690+ <author>James McGovern</author>
691+ <author>Per Bothner</author>
692+ <author>Kurt Cagle</author>
693+ <author>James Linn</author>
694+ <author>Vaidyanathan Nagarajan</author>
695+ <year>2003</year>
696+ <price>49.99</price>
697+ </book>
698+ <book category="web">
699+ <title lang="en">Learning XML</title>
700+ <author>Erik T. Ray</author>
701+ <year>2003</year>
702+ <price>39.95</price>
703+ </book>
704+ </bookstore>
623705 */
624706 type Element struct {
625707 Data string
@@ -708,24 +790,24 @@ func createBookExample() *TNode {
708790// The example document from https://way2tutorial.com/xml/xpath-node-test.php
709791func createEmployeeExample () * TNode {
710792 /*
711- <?xml version="1.0" standalone="yes"?>
712- <empinfo>
713- <employee id="1">
714- <name>Opal Kole</name>
715- <designation discipline="web" experience="3 year">Senior Engineer</designation>
716- 717- </employee>
718- <employee id="2">
719- <name from="CA">Max Miller</name>
720- <designation discipline="DBA" experience="2 year">DBA Engineer</designation>
721- 722- </employee>
723- <employee id="3">
724- <name>Beccaa Moss</name>
725- <designation discipline="appdev">Application Developer</designation>
726- 727- </employee>
728- </empinfo>
793+ <?xml version="1.0" standalone="yes"?>
794+ <empinfo>
795+ <employee id="1">
796+ <name>Opal Kole</name>
797+ <designation discipline="web" experience="3 year">Senior Engineer</designation>
798+ 799+ </employee>
800+ <employee id="2">
801+ <name from="CA">Max Miller</name>
802+ <designation discipline="DBA" experience="2 year">DBA Engineer</designation>
803+ 804+ </employee>
805+ <employee id="3">
806+ <name>Beccaa Moss</name>
807+ <designation discipline="appdev">Application Developer</designation>
808+ 809+ </employee>
810+ </empinfo>
729811 */
730812
731813 type Element struct {
@@ -808,25 +890,25 @@ func createHtmlExample() *TNode {
808890 /*
809891 <html lang="en">
810892 <head>
811- <title>My page</title>
812- <meta name="language" content="en" />
893+ <title>My page</title>
894+ <meta name="language" content="en" />
813895 </head>
814896 <body>
815- <h2>Welcome to my page</h2>
816- <ul>
817- <li>
818- <a href="/">Home</a>
819- </li>
820- <li>
821- <a href="/about">About</a>
822- </li>
823- <li>
824- <a href="/account">Login</a>
825- </li>
897+ <h2>Welcome to my page</h2>
898+ <ul>
899+ <li>
900+ <a href="/">Home</a>
901+ </li>
902+ <li>
903+ <a href="/about">About</a>
904+ </li>
905+ <li>
906+ <a href="/account">Login</a>
907+ </li>
826908 <li></li>
827- </ul>
828- <p>This is the first paragraph.</p>
829- <!-- this is the end -->
909+ </ul>
910+ <p>This is the first paragraph.</p>
911+ <!-- this is the end -->
830912 </body>
831913 </html>
832914 */
0 commit comments