xee_xpath_ast/parser/
mod.rs

1mod axis_node_test;
2mod kind_test;
3mod name;
4mod parser_core;
5mod pattern;
6mod primary;
7mod signature;
8mod types;
9mod xpath_type;
10
11use chumsky::input::Stream;
12use chumsky::inspector::SimpleState;
13use chumsky::{input::ValueInput, prelude::*};
14
15use std::borrow::Cow;
16
17use xee_name::VariableNames;
18use xee_xpath_lexer::{lexer, Token};
19
20use crate::ast;
21use crate::ast::unique_names;
22use crate::ast::Span;
23use crate::error::ParserError;
24use crate::Namespaces;
25
26use super::parser::parser_core::parser;
27use super::parser::types::{BoxedParser, State};
28
29fn create_token_iter(src: &str) -> impl Iterator<Item = (Token, SimpleSpan)> + '_ {
30    lexer(src).map(|(tok, span)| (tok, span.into()))
31}
32
33fn tokens(src: &str) -> impl ValueInput<'_, Token = Token<'_>, Span = Span> {
34    Stream::from_iter(create_token_iter(src))
35        .map((src.len()..src.len()).into(), |(tok, span)| (tok, span))
36}
37
38fn parse<'a, I, T>(
39    parser: BoxedParser<'a, I, T>,
40    input: I,
41    namespaces: Cow<'a, Namespaces>,
42) -> std::result::Result<T, ParserError>
43where
44    I: ValueInput<'a, Token = Token<'a>, Span = Span>,
45    T: std::fmt::Debug,
46{
47    let mut state = SimpleState(State { namespaces });
48    parser
49        .parse_with_state(input, &mut state)
50        .into_result()
51        .map_err(|e| e.into_iter().next().unwrap())
52}
53
54impl ast::XPath {
55    pub fn parse<'a>(
56        input: &'a str,
57        namespaces: &'a Namespaces,
58        variable_names: &'a VariableNames,
59    ) -> Result<Self, ParserError> {
60        let mut xpath = parse(parser().xpath, tokens(input), Cow::Borrowed(namespaces))?;
61        // rename all variables to unique names
62        unique_names(&mut xpath, variable_names);
63        Ok(xpath)
64    }
65
66    // parse xpath, and then a single }
67    // This is useful to support XSLT value templates
68    pub fn parse_value_template<'a>(
69        input: &'a str,
70        namespaces: &'a Namespaces,
71        variable_names: &'a VariableNames,
72    ) -> Result<Self, ParserError> {
73        let mut state = SimpleState(State {
74            namespaces: Cow::Borrowed(namespaces),
75        });
76        let r = parser()
77            .xpath_right_brace
78            .parse_with_state(tokens(input), &mut state);
79        let (output, errors) = r.into_output_errors();
80        if let Some(mut xpath) = output {
81            // rename all variables to unique names
82            unique_names(&mut xpath, variable_names);
83            Ok(xpath)
84        } else {
85            Err(errors.into_iter().next().unwrap())
86        }
87    }
88}
89
90impl ast::ExprSingle {
91    pub fn parse(src: &str) -> Result<ast::ExprSingleS, ParserError> {
92        let namespaces = Namespaces::default();
93        parse(parser().expr_single, tokens(src), Cow::Owned(namespaces))
94    }
95}
96
97impl ast::Signature {
98    pub fn parse<'a>(input: &'a str, namespaces: &'a Namespaces) -> Result<Self, ParserError> {
99        parse(parser().signature, tokens(input), Cow::Borrowed(namespaces))
100    }
101}
102
103pub fn parse_kind_test(src: &str) -> Result<ast::KindTest, ParserError> {
104    let namespaces = Namespaces::default();
105    parse(parser().kind_test, tokens(src), Cow::Owned(namespaces))
106}
107
108pub fn parse_sequence_type<'a>(
109    input: &'a str,
110    namespaces: &'a Namespaces,
111) -> Result<ast::SequenceType, ParserError> {
112    parse(
113        parser().sequence_type,
114        tokens(input),
115        Cow::Borrowed(namespaces),
116    )
117}
118
119pub fn parse_item_type<'a>(
120    input: &'a str,
121    namespaces: &'a Namespaces,
122) -> Result<ast::ItemType, ParserError> {
123    parse(parser().item_type, tokens(input), Cow::Borrowed(namespaces))
124}
125
126pub fn parse_name<'a>(src: &'a str, namespaces: &'a Namespaces) -> Result<ast::NameS, ParserError> {
127    parse(parser().name, tokens(src), Cow::Borrowed(namespaces))
128}
129
130#[cfg(test)]
131mod tests {
132
133    use super::*;
134
135    use ahash::HashSetExt;
136    use insta::assert_ron_snapshot;
137
138    fn parse_xpath_simple(src: &str) -> Result<ast::XPath, ParserError> {
139        let namespaces = Namespaces::default();
140        parse(parser().xpath, tokens(src), Cow::Owned(namespaces))
141    }
142
143    fn parse_xpath_simple_element_ns(src: &str) -> Result<ast::XPath, ParserError> {
144        let namespaces = Namespaces::new(
145            Namespaces::default_namespaces(),
146            "http://example.com".to_string(),
147            "".to_string(),
148        );
149        parse(parser().xpath, tokens(src), Cow::Owned(namespaces))
150    }
151
152    #[test]
153    fn test_unprefixed_name() {
154        let namespaces = Namespaces::default();
155        assert_ron_snapshot!(parse_name("foo", &namespaces));
156    }
157
158    #[test]
159    fn test_prefixed_name() {
160        let namespaces = Namespaces::default();
161        assert_ron_snapshot!(parse_name("xs:foo", &namespaces));
162    }
163
164    #[test]
165    fn test_qualified_name() {
166        let namespaces = Namespaces::default();
167        assert_ron_snapshot!(parse_name("Q{http://example.com}foo", &namespaces));
168    }
169
170    #[test]
171    fn test_literal() {
172        assert_ron_snapshot!(ast::ExprSingle::parse("1"));
173    }
174
175    #[test]
176    fn test_var_ref() {
177        assert_ron_snapshot!(ast::ExprSingle::parse("$foo"));
178    }
179
180    #[test]
181    fn test_expr_single_addition() {
182        assert_ron_snapshot!(ast::ExprSingle::parse("1 + 2"));
183    }
184
185    #[test]
186    fn test_simple_map_expr() {
187        assert_ron_snapshot!(ast::ExprSingle::parse("1 ! 2"));
188    }
189
190    #[test]
191    fn test_unary_expr() {
192        assert_ron_snapshot!(ast::ExprSingle::parse("-1"));
193    }
194
195    #[test]
196    fn test_additive_expr() {
197        assert_ron_snapshot!(ast::ExprSingle::parse("1 + 2"));
198    }
199
200    #[test]
201    fn test_additive_expr_repeat() {
202        assert_ron_snapshot!(ast::ExprSingle::parse("1 + 2 + 3"));
203    }
204
205    #[test]
206    fn test_or_expr() {
207        assert_ron_snapshot!(ast::ExprSingle::parse("1 or 2"));
208    }
209
210    #[test]
211    fn test_and_expr() {
212        assert_ron_snapshot!(ast::ExprSingle::parse("1 and 2"));
213    }
214
215    #[test]
216    fn test_comparison_expr() {
217        assert_ron_snapshot!(ast::ExprSingle::parse("1 < 2"));
218    }
219
220    #[test]
221    fn test_concat_expr() {
222        assert_ron_snapshot!(ast::ExprSingle::parse("'a' || 'b'"));
223    }
224
225    #[test]
226    fn test_nested_expr() {
227        assert_ron_snapshot!(ast::ExprSingle::parse("1 + (2 * 3)"));
228    }
229
230    #[test]
231    fn test_xpath_single_expr() {
232        assert_ron_snapshot!(ast::ExprSingle::parse("1 + 2"));
233    }
234
235    #[test]
236    fn test_xpath_multi_expr() {
237        assert_ron_snapshot!(parse_xpath_simple("1 + 2, 3 + 4"));
238    }
239
240    #[test]
241    fn test_single_let_expr() {
242        assert_ron_snapshot!(ast::ExprSingle::parse("let $x := 1 return 5"));
243    }
244
245    #[test]
246    fn test_single_let_expr_var_ref() {
247        assert_ron_snapshot!(ast::ExprSingle::parse("let $x := 1 return $x"));
248    }
249
250    #[test]
251    fn test_nested_let_expr() {
252        assert_ron_snapshot!(ast::ExprSingle::parse("let $x := 1, $y := 2 return 5"));
253    }
254
255    #[test]
256    fn test_single_for_expr() {
257        assert_ron_snapshot!(ast::ExprSingle::parse("for $x in 1 return 5"));
258    }
259
260    #[test]
261    fn test_for_loop() {
262        assert_ron_snapshot!(ast::ExprSingle::parse("for $x in 1 to 2 return $x"));
263    }
264
265    #[test]
266    fn test_if_expr() {
267        assert_ron_snapshot!(ast::ExprSingle::parse("if (1) then 2 else 3"));
268    }
269
270    #[test]
271    fn test_quantified() {
272        assert_ron_snapshot!(ast::ExprSingle::parse(
273            "every $x in (1, 2) satisfies $x > 0"
274        ));
275    }
276
277    #[test]
278    fn test_quantified_nested() {
279        assert_ron_snapshot!(ast::ExprSingle::parse(
280            "every $x in (1, 2), $y in (3, 4) satisfies $x > 0 and $y > 0"
281        ));
282    }
283
284    #[test]
285    fn test_inline_function() {
286        assert_ron_snapshot!(ast::ExprSingle::parse("function($x) { $x }"));
287    }
288
289    #[test]
290    fn test_inline_function_with_param_types() {
291        assert_ron_snapshot!(ast::ExprSingle::parse("function($x as xs:integer) { $x }"));
292    }
293
294    #[test]
295    fn test_inline_function_with_return_type() {
296        assert_ron_snapshot!(ast::ExprSingle::parse("function($x) as xs:integer { $x }"));
297    }
298
299    #[test]
300    fn test_inline_function2() {
301        assert_ron_snapshot!(ast::ExprSingle::parse("function($x, $y) { $x + $y }"));
302    }
303
304    #[test]
305    fn test_dynamic_function_call() {
306        assert_ron_snapshot!(ast::ExprSingle::parse("$foo()"));
307    }
308
309    #[test]
310    fn test_dynamic_function_call_args() {
311        assert_ron_snapshot!(ast::ExprSingle::parse("$foo(1 + 1, 3)"));
312    }
313
314    #[test]
315    fn test_dynamic_function_call_placeholder() {
316        assert_ron_snapshot!(ast::ExprSingle::parse("$foo(1, ?)"));
317    }
318
319    #[test]
320    fn test_static_function_call() {
321        assert_ron_snapshot!(ast::ExprSingle::parse("my_function()"));
322    }
323
324    #[test]
325    fn test_static_function_call_fn_prefix() {
326        assert_ron_snapshot!(ast::ExprSingle::parse("fn:root()"));
327    }
328
329    #[test]
330    fn test_static_function_call_q() {
331        assert_ron_snapshot!(ast::ExprSingle::parse("Q{http://example.com}something()"));
332    }
333
334    #[test]
335    fn test_static_function_call_args() {
336        assert_ron_snapshot!(ast::ExprSingle::parse("my_function(1, 2)"));
337    }
338
339    #[test]
340    fn test_named_function_ref() {
341        assert_ron_snapshot!(ast::ExprSingle::parse("my_function#2"));
342    }
343
344    #[test]
345    fn test_static_function_call_placeholder() {
346        assert_ron_snapshot!(ast::ExprSingle::parse("my_function(?, 1)"));
347    }
348
349    #[test]
350    fn test_simple_comma() {
351        assert_ron_snapshot!(parse_xpath_simple("1, 2"));
352    }
353
354    #[test]
355    fn test_complex_comma() {
356        assert_ron_snapshot!(parse_xpath_simple("(1, 2), (3, 4)"));
357    }
358
359    #[test]
360    fn test_range() {
361        assert_ron_snapshot!(ast::ExprSingle::parse("1 to 2"));
362    }
363
364    #[test]
365    fn test_simple_map() {
366        assert_ron_snapshot!(ast::ExprSingle::parse("(1, 2) ! (. * 2)"));
367    }
368
369    #[test]
370    fn test_predicate() {
371        assert_ron_snapshot!(ast::ExprSingle::parse("(1, 2)[2]"));
372    }
373
374    #[test]
375    fn test_axis() {
376        assert_ron_snapshot!(ast::ExprSingle::parse("child::foo"));
377    }
378
379    #[test]
380    fn test_multiple_steps() {
381        assert_ron_snapshot!(ast::ExprSingle::parse("child::foo/child::bar"));
382    }
383
384    #[test]
385    fn test_with_predicate() {
386        assert_ron_snapshot!(ast::ExprSingle::parse("child::foo[1]"));
387    }
388
389    #[test]
390    fn test_axis_with_predicate() {
391        assert_ron_snapshot!(ast::ExprSingle::parse("child::foo[1]"));
392    }
393
394    #[test]
395    fn test_axis_star() {
396        assert_ron_snapshot!(ast::ExprSingle::parse("child::*"));
397    }
398
399    #[test]
400    fn test_axis_wildcard_prefix() {
401        assert_ron_snapshot!(ast::ExprSingle::parse("child::*:foo"));
402    }
403
404    #[test]
405    fn test_axis_wildcard_local_name() {
406        assert_ron_snapshot!(ast::ExprSingle::parse("child::fn:*"));
407    }
408
409    #[test]
410    fn test_axis_wildcard_q_name() {
411        assert_ron_snapshot!(ast::ExprSingle::parse("child::Q{http://example.com}*"));
412    }
413
414    #[test]
415    fn test_reverse_axis() {
416        assert_ron_snapshot!(ast::ExprSingle::parse("parent::foo"));
417    }
418
419    #[test]
420    fn test_node_test() {
421        assert_ron_snapshot!(ast::ExprSingle::parse("self::node()"));
422    }
423
424    #[test]
425    fn test_text_test() {
426        assert_ron_snapshot!(ast::ExprSingle::parse("self::text()"));
427    }
428
429    #[test]
430    fn test_comment_test() {
431        assert_ron_snapshot!(ast::ExprSingle::parse("self::comment()"));
432    }
433
434    #[test]
435    fn test_namespace_node_test() {
436        assert_ron_snapshot!(ast::ExprSingle::parse("self::namespace-node()"));
437    }
438
439    #[test]
440    fn test_attribute_test_no_args() {
441        assert_ron_snapshot!(ast::ExprSingle::parse("self::attribute()"));
442    }
443
444    #[test]
445    fn test_attribute_test_star_arg() {
446        assert_ron_snapshot!(ast::ExprSingle::parse("self::attribute(*)"));
447    }
448
449    #[test]
450    fn test_attribute_test_name_arg() {
451        assert_ron_snapshot!(ast::ExprSingle::parse("self::attribute(foo)"));
452    }
453
454    #[test]
455    fn test_attribute_test_name_arg_type_arg() {
456        assert_ron_snapshot!(ast::ExprSingle::parse("self::attribute(foo, xs:integer)"));
457    }
458
459    #[test]
460    fn test_element_test() {
461        assert_ron_snapshot!(ast::ExprSingle::parse("self::element()"));
462    }
463
464    #[test]
465    fn test_abbreviated_forward_step() {
466        assert_ron_snapshot!(ast::ExprSingle::parse("foo"));
467    }
468
469    #[test]
470    fn test_abbreviated_forward_step_with_attribute_test() {
471        assert_ron_snapshot!(ast::ExprSingle::parse("foo/attribute()"));
472    }
473
474    // XXX should test for attribute axis for SchemaAttributeTest too
475
476    #[test]
477    fn test_namespace_node_default_axis() {
478        assert_ron_snapshot!(ast::ExprSingle::parse("foo/namespace-node()"));
479    }
480
481    #[test]
482    fn test_abbreviated_forward_step_attr() {
483        assert_ron_snapshot!(ast::ExprSingle::parse("@foo"));
484    }
485
486    #[test]
487    fn test_abbreviated_reverse_step() {
488        assert_ron_snapshot!(ast::ExprSingle::parse("foo/.."));
489    }
490
491    #[test]
492    fn test_abbreviated_reverse_step_with_predicates() {
493        assert_ron_snapshot!(ast::ExprSingle::parse("..[1]"));
494    }
495
496    #[test]
497    fn test_starts_single_slash() {
498        assert_ron_snapshot!(ast::ExprSingle::parse("/child::foo"));
499    }
500
501    #[test]
502    fn test_single_slash_by_itself() {
503        assert_ron_snapshot!(ast::ExprSingle::parse("/"));
504    }
505
506    #[test]
507    fn test_double_slash_by_itself() {
508        assert_ron_snapshot!(ast::ExprSingle::parse("//"));
509    }
510
511    #[test]
512    fn test_starts_double_slash() {
513        assert_ron_snapshot!(ast::ExprSingle::parse("//child::foo"));
514    }
515
516    #[test]
517    fn test_double_slash_middle() {
518        assert_ron_snapshot!(ast::ExprSingle::parse("child::foo//child::bar"));
519    }
520
521    #[test]
522    fn test_union() {
523        assert_ron_snapshot!(ast::ExprSingle::parse("child::foo | child::bar"));
524    }
525
526    #[test]
527    fn test_intersect() {
528        assert_ron_snapshot!(ast::ExprSingle::parse("child::foo intersect child::bar"));
529    }
530
531    #[test]
532    fn test_except() {
533        assert_ron_snapshot!(ast::ExprSingle::parse("child::foo except child::bar"));
534    }
535
536    #[test]
537    fn test_xpath_parse_error() {
538        assert_ron_snapshot!(ast::ExprSingle::parse("1 + 2 +"));
539    }
540
541    #[test]
542    fn test_xpath_ge() {
543        assert_ron_snapshot!(ast::ExprSingle::parse("1 >= 2"));
544    }
545
546    #[test]
547    fn test_signature_without_params() {
548        let namespaces = Namespaces::default();
549        assert_ron_snapshot!(ast::Signature::parse("fn:foo() as xs:integer", &namespaces));
550    }
551
552    #[test]
553    fn test_signature_without_params2() {
554        let namespaces = Namespaces::default();
555        assert_ron_snapshot!(ast::Signature::parse(
556            "fn:foo() as xs:integer*",
557            &namespaces
558        ));
559    }
560
561    #[test]
562    fn test_signature_with_params() {
563        let namespaces = Namespaces::default();
564        assert_ron_snapshot!(ast::Signature::parse(
565            "fn:foo($a as xs:decimal*) as xs:integer",
566            &namespaces
567        ));
568    }
569
570    #[test]
571    fn test_signature_with_node_param() {
572        let namespaces = Namespaces::default();
573        assert_ron_snapshot!(ast::Signature::parse(
574            "fn:foo($a as node()) as xs:integer",
575            &namespaces
576        ));
577    }
578
579    #[test]
580    fn test_signature_with_node_param_and_question_mark() {
581        let namespaces = Namespaces::default();
582        assert_ron_snapshot!(ast::Signature::parse(
583            "fn:foo($a as node()?) as xs:integer",
584            &namespaces
585        ));
586    }
587
588    #[test]
589    fn test_signature_with_minus_in_name() {
590        let namespaces = Namespaces::default();
591        assert_ron_snapshot!(ast::Signature::parse(
592            "fn:foo-bar($a as node()?) as xs:integer",
593            &namespaces
594        ));
595    }
596
597    #[test]
598    fn test_unary_multiple() {
599        assert_ron_snapshot!(ast::ExprSingle::parse("+-1"));
600    }
601
602    #[test]
603    fn test_cast_as() {
604        assert_ron_snapshot!(ast::ExprSingle::parse("1 cast as xs:integer"));
605    }
606
607    #[test]
608    fn test_cast_as_with_question_mark() {
609        assert_ron_snapshot!(ast::ExprSingle::parse("1 cast as xs:integer?"));
610    }
611
612    #[test]
613    fn test_castable_as() {
614        assert_ron_snapshot!(ast::ExprSingle::parse("1 castable as xs:integer"));
615    }
616
617    #[test]
618    fn test_castable_as_with_question_mark() {
619        assert_ron_snapshot!(ast::ExprSingle::parse("1 castable as xs:integer?"));
620    }
621
622    #[test]
623    fn test_instance_of() {
624        assert_ron_snapshot!(ast::ExprSingle::parse("1 instance of xs:integer"));
625    }
626
627    #[test]
628    fn test_instance_of_with_star() {
629        assert_ron_snapshot!(ast::ExprSingle::parse("1 instance of xs:integer*"));
630    }
631
632    #[test]
633    fn test_treat() {
634        assert_ron_snapshot!(ast::ExprSingle::parse("1 treat as xs:integer"));
635    }
636
637    // This should be passing, see https://github.com/Paligo/xee/issues/35
638    // #[test]
639    // fn test_treat_invalid() {
640    //     assert_ron_snapshot!(ast::ExprSingle::parse("3 treat as item("));
641    // }
642
643    #[test]
644    fn test_treat_with_star() {
645        assert_ron_snapshot!(ast::ExprSingle::parse("1 treat as xs:integer*"));
646    }
647
648    #[test]
649    fn test_default_element_namespace_element_kind_test() {
650        assert_ron_snapshot!(parse_xpath_simple_element_ns("element(foo)"));
651    }
652
653    #[test]
654    fn test_default_element_namespace_attribute_kind_test() {
655        assert_ron_snapshot!(parse_xpath_simple_element_ns("attribute(foo)"));
656    }
657
658    #[test]
659    fn test_default_element_namespace_element_name_test() {
660        assert_ron_snapshot!(parse_xpath_simple_element_ns("foo"));
661    }
662
663    #[test]
664    fn test_default_element_namespace_explicit_element_name_test() {
665        assert_ron_snapshot!(parse_xpath_simple_element_ns("child::foo"));
666    }
667
668    #[test]
669    fn test_default_element_namespace_attribute_name_test() {
670        assert_ron_snapshot!(parse_xpath_simple_element_ns("@foo"));
671    }
672
673    #[test]
674    fn test_default_element_namespace_explicit_attribute_name_test() {
675        assert_ron_snapshot!(parse_xpath_simple_element_ns("attribute::foo"));
676    }
677
678    #[test]
679    fn test_function_call_without_arguments() {
680        assert_ron_snapshot!(parse_xpath_simple("fn:foo()"));
681    }
682
683    #[test]
684    fn test_reserved_function_name() {
685        assert_ron_snapshot!(parse_xpath_simple("switch()"));
686    }
687
688    #[test]
689    fn test_reserved_function_name_reference() {
690        assert_ron_snapshot!(parse_xpath_simple("switch#2"));
691    }
692
693    #[test]
694    fn test_occurrence_indicators_ambiguity() {
695        // See Constraint: occurrence-indicators
696        assert_ron_snapshot!(parse_xpath_simple("4 treat as item() + - 5"));
697    }
698
699    #[test]
700    fn test_occurrence_indicators_disambiguate() {
701        // See Constraint: occurrence-indicators
702        assert_ron_snapshot!(parse_xpath_simple("(4 treat as item()) + - 5"));
703    }
704
705    #[test]
706    fn test_occurrence_indicators_function() {
707        // See Constraint: occurrence-indicators
708        assert_ron_snapshot!(parse_xpath_simple("function () as xs:string * {}"));
709    }
710
711    #[test]
712    fn test_leading_lone_slash_can_form_a_path_expression() {
713        // See Constraint: leading-lone-slash
714
715        // if the token immediately following a slash can form a path
716        // expression, then the slash must be the beginning of a path
717        // expression, not the entirety of it
718        assert_ron_snapshot!(parse_xpath_simple("/ *"));
719    }
720
721    #[test]
722    fn test_leading_lone_slash_can_form_a_path_expression_error() {
723        // See Constraint: leading-lone-slash
724        assert_ron_snapshot!(parse_xpath_simple("/ * 5"))
725    }
726
727    #[test]
728    fn test_leading_lone_slash_disambiguate() {
729        // See Constraint: leading-lone-slash
730        assert_ron_snapshot!(parse_xpath_simple("(/) * 5"))
731    }
732
733    #[test]
734    fn test_grammar_note_parens() {
735        // See Grammar Note: parens
736        // This should be interpreted as a comment, not a function call
737        assert_ron_snapshot!(parse_xpath_simple("address (: this may be empty :)"));
738    }
739
740    #[test]
741    fn test_symbol_as_name_test() {
742        assert_ron_snapshot!(parse_xpath_simple("/if"))
743    }
744
745    #[test]
746    fn test_another_symbol_as_name_test() {
747        assert_ron_snapshot!(parse_xpath_simple("/else"))
748    }
749
750    #[test]
751    fn test_symbol_as_name_test_with_prefix() {
752        assert_ron_snapshot!(parse_xpath_simple("fn:if"))
753    }
754
755    #[test]
756    fn test_symbol_as_name_test_with_prefix_wildcard() {
757        assert_ron_snapshot!(parse_xpath_simple("*:if"))
758    }
759
760    #[test]
761    fn test_any_function_type() {
762        let namespaces = Namespaces::default();
763        assert_ron_snapshot!(parse_sequence_type("function(*)", &namespaces));
764    }
765
766    #[test]
767    fn test_typed_function_type() {
768        let namespaces = Namespaces::default();
769        assert_ron_snapshot!(parse_sequence_type(
770            "function(xs:integer) as xs:integer",
771            &namespaces
772        ));
773    }
774
775    #[test]
776    fn test_map_constructor() {
777        assert_ron_snapshot!(parse_xpath_simple("map { 1: 2 }"))
778    }
779
780    #[test]
781    fn test_curly_array_constructor() {
782        assert_ron_snapshot!(parse_xpath_simple("array { 1, 2}"))
783    }
784
785    #[test]
786    fn test_square_array_constructor() {
787        assert_ron_snapshot!(parse_xpath_simple("[1, 2]"))
788    }
789
790    #[test]
791    fn test_unary_lookup_name() {
792        assert_ron_snapshot!(parse_xpath_simple("?name"))
793    }
794
795    #[test]
796    fn test_unary_lookup_integer() {
797        assert_ron_snapshot!(parse_xpath_simple("?1"))
798    }
799
800    #[test]
801    fn test_unary_lookup_star() {
802        assert_ron_snapshot!(parse_xpath_simple("?*"))
803    }
804
805    #[test]
806    fn test_unary_lookup_expr() {
807        assert_ron_snapshot!(parse_xpath_simple("?(1 + 1)"))
808    }
809
810    #[test]
811    fn test_lookup_name() {
812        assert_ron_snapshot!(parse_xpath_simple("1?name"))
813    }
814
815    #[test]
816    fn test_any_array() {
817        assert_ron_snapshot!(parse_xpath_simple("'foo' instance of array(*)"))
818    }
819
820    #[test]
821    fn test_typed_array() {
822        assert_ron_snapshot!(parse_xpath_simple("'foo' instance of array(xs:integer)"))
823    }
824
825    #[test]
826    fn test_any_map() {
827        assert_ron_snapshot!(parse_xpath_simple("'foo' instance of map(*)"))
828    }
829
830    #[test]
831    fn test_parse_empty_array() {
832        assert_ron_snapshot!(parse_xpath_simple("[]"))
833    }
834
835    #[test]
836    fn test_arrow_function_static() {
837        assert_ron_snapshot!(parse_xpath_simple("'foo' => fn:concat('bar')"))
838    }
839
840    #[test]
841    fn test_arrow_function_static_with_placeholder() {
842        assert_ron_snapshot!(parse_xpath_simple("'$' => fn:concat(?)"))
843    }
844
845    #[test]
846    fn test_inline_function_with_empty_body() {
847        assert_ron_snapshot!(parse_xpath_simple(
848            "let $f := function($x) { (: there's nothing here :)} return $f(2)"
849        ))
850    }
851
852    #[test]
853    fn test_comment_before_expression() {
854        assert_ron_snapshot!(parse_xpath_simple("(: comment :)/foo"))
855    }
856
857    #[test]
858    fn test_multiple_comments_before_expression() {
859        assert_ron_snapshot!(parse_xpath_simple(r#"(: a :)(: b :)foo"#))
860    }
861    #[test]
862    fn test_xpath_parse_value_template() {
863        let namespaces = Namespaces::default();
864        let xpath =
865            ast::XPath::parse_value_template("1 + 2}", &namespaces, &VariableNames::new()).unwrap();
866        assert_eq!(xpath.0.span, Span::new(0, 5));
867        assert_ron_snapshot!(xpath);
868    }
869
870    #[test]
871    fn test_xpath_parse_value_template_with_leftover() {
872        let namespaces = Namespaces::default();
873        let xpath =
874            ast::XPath::parse_value_template("1 + 2}foo", &namespaces, &VariableNames::new())
875                .unwrap();
876        assert_eq!(xpath.0.span, Span::new(0, 5));
877        assert_ron_snapshot!(xpath);
878    }
879
880    #[test]
881    fn test_xpath_parse_value_template_a_with_leftover() {
882        let namespaces = Namespaces::default();
883        let xpath =
884            ast::XPath::parse_value_template("a}foo", &namespaces, &VariableNames::new()).unwrap();
885        assert_eq!(xpath.0.span, Span::new(0, 1));
886        assert_ron_snapshot!(xpath);
887    }
888
889    #[test]
890    fn test_xpath_parse_value_template_with_second_value_following() {
891        let namespaces = Namespaces::default();
892        let xpath =
893            ast::XPath::parse_value_template("a}foo{b}!", &namespaces, &VariableNames::new())
894                .unwrap();
895        assert_eq!(xpath.0.span, Span::new(0, 1));
896        assert_ron_snapshot!(xpath);
897    }
898
899    // #[test]
900    // fn test_function_that_takes_function_parameter() {
901    //     assert_ron_snapshot!(parse_xpath_simple("filter(1, function($item) { true() })"))
902    // }
903    // #[test]
904    // fn test_symbol_as_name_test_with_localname_wildcard() {
905    //     assert_ron_snapshot!(parse_xpath_simple("if:*"))
906    // }
907}