Skip to content

Commit f5cc119

Browse files
committed
pass more tests
1 parent 0631dcc commit f5cc119

12 files changed

Lines changed: 1378 additions & 86 deletions

File tree

crates/oxc_angular_compiler/tests/expression_parser_test.rs

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,8 @@ mod parse_action {
453453
check_binding("a?.[\"a\"]", Some("a?.['a']"));
454454
check_binding("this.a?.[\"a\"]", Some("a?.['a']"));
455455
check_binding("a.a?.[\"a\"]", Some("a.a?.['a']"));
456-
// Safe keyed read with pipe - Angular wraps pipe in parens
457-
check_binding("a.a?.[\"a\" | foo]", Some("a.a?.[('a' | foo)]"));
456+
// Safe keyed read with pipe - Angular's serialize() does NOT wrap pipes in parens
457+
check_binding("a.a?.[\"a\" | foo]", Some("a.a?.['a' | foo]"));
458458
}
459459

460460
#[test]
@@ -676,16 +676,16 @@ mod parse_binding {
676676

677677
#[test]
678678
fn should_parse_pipes() {
679-
// Angular serialize() wraps pipes in parens
680-
check_binding("a(b | c)", Some("a((b | c))"));
681-
check_binding("a.b(c.d(e) | f)", Some("a.b((c.d(e) | f))"));
682-
check_binding("[1, 2, 3] | a", Some("([1, 2, 3] | a)"));
683-
check_binding(r#"{a: 1, "b": 2} | c"#, Some("({a: 1, 'b': 2} | c)"));
684-
check_binding("a[b] | c", Some("(a[b] | c)"));
685-
check_binding("a?.b | c", Some("(a?.b | c)"));
686-
check_binding("true | a", Some("(true | a)"));
687-
check_binding("a | b:c | d", Some("((a | b:c) | d)"));
688-
check_binding("a | b:(c | d)", Some("(a | b:((c | d)))"));
679+
// Angular serialize() does NOT wrap pipes in parens
680+
check_binding("a(b | c)", Some("a(b | c)"));
681+
check_binding("a.b(c.d(e) | f)", Some("a.b(c.d(e) | f)"));
682+
check_binding("[1, 2, 3] | a", Some("[1, 2, 3] | a"));
683+
check_binding(r#"{a: 1, "b": 2} | c"#, Some("{a: 1, 'b': 2} | c"));
684+
check_binding("a[b] | c", Some("a[b] | c"));
685+
check_binding("a?.b | c", Some("a?.b | c"));
686+
check_binding("true | a", Some("true | a"));
687+
check_binding("a | b:c | d", Some("a | b:c | d"));
688+
check_binding("a | b:(c | d)", Some("a | b:(c | d)"));
689689
}
690690

691691
// TS: describe("should parse incomplete pipes")
@@ -694,7 +694,7 @@ mod parse_binding {
694694

695695
#[test]
696696
fn should_parse_missing_pipe_names_end() {
697-
check_binding("a | b | ", Some("((a | b) | )"));
697+
check_binding("a | b | ", Some("a | b | "));
698698
expect_binding_error(
699699
"a | b | ",
700700
"Unexpected end of input, expected identifier or keyword",
@@ -703,7 +703,7 @@ mod parse_binding {
703703

704704
#[test]
705705
fn should_parse_missing_pipe_names_middle() {
706-
check_binding("a | | b", Some("((a | ) | b)"));
706+
check_binding("a | | b", Some("a | | b"));
707707
expect_binding_error(
708708
"a | | b",
709709
"Unexpected token |, expected identifier or keyword",
@@ -712,25 +712,25 @@ mod parse_binding {
712712

713713
#[test]
714714
fn should_parse_missing_pipe_names_start() {
715-
check_binding(" | a | b", Some("(( | a) | b)"));
715+
check_binding(" | a | b", Some(" | a | b"));
716716
expect_binding_error(" | a | b", "Unexpected token |");
717717
}
718718

719719
#[test]
720720
fn should_parse_missing_pipe_args_end() {
721-
check_binding("a | b | c: ", Some("((a | b) | c:)"));
721+
check_binding("a | b | c: ", Some("a | b | c:"));
722722
expect_binding_error("a | b | c: ", "Unexpected end of expression");
723723
}
724724

725725
#[test]
726726
fn should_parse_missing_pipe_args_middle() {
727-
check_binding("a | b: | c", Some("((a | b:) | c)"));
727+
check_binding("a | b: | c", Some("a | b: | c"));
728728
expect_binding_error("a | b: | c", "Unexpected token |");
729729
}
730730

731731
#[test]
732732
fn should_parse_incomplete_pipe_args() {
733-
check_binding("a | b: (a | ) + | c", Some("((a | b:((a | )) + ) | c)"));
733+
check_binding("a | b: (a | ) + | c", Some("a | b:(a | ) + | c"));
734734
expect_binding_error("a | b: (a | ) + | c", "Unexpected token |");
735735
}
736736
}
@@ -786,14 +786,15 @@ mod parse_binding {
786786

787787
#[test]
788788
fn should_parse_template_literal_with_pipes_inside_interpolations() {
789-
// Angular's serialize() wraps pipes in parentheses
789+
// Angular's serialize() does NOT wrap pipes in parentheses
790790
check_binding(
791791
"`hello ${name | capitalize}!!!`",
792-
Some("`hello ${(name | capitalize)}!!!`"),
792+
Some("`hello ${name | capitalize}!!!`"),
793793
);
794+
// Explicit parentheses are preserved
794795
check_binding(
795796
"`hello ${(name | capitalize)}!!!`",
796-
Some("`hello ${((name | capitalize))}!!!`"),
797+
Some("`hello ${(name | capitalize)}!!!`"),
797798
);
798799
}
799800

@@ -962,8 +963,8 @@ mod assignment {
962963
fn should_support_field_assignments() {
963964
check_action("a = 12", None);
964965
check_action("a.a.a = 123", None);
965-
// Angular's serialize() adds trailing semicolon for chain expressions
966-
check_action("a = 123; b = 234;", None);
966+
// Angular's serialize() does NOT add trailing semicolon for chain expressions
967+
check_action("a = 123; b = 234;", Some("a = 123; b = 234"));
967968
}
968969

969970
#[test]
@@ -996,8 +997,8 @@ mod error_recovery {
996997

997998
#[test]
998999
fn should_recover_from_missing_paren() {
999-
// Angular's serialize() adds trailing semicolon for chain expressions
1000-
check_action("(a;b", Some("(a); b;"));
1000+
// Angular's serialize() does NOT add trailing semicolon for chain expressions
1001+
check_action("(a;b", Some("(a); b"));
10011002
}
10021003

10031004
#[test]

crates/oxc_angular_compiler/tests/expression_serializer_test.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ mod chains {
129129

130130
#[test]
131131
fn serializes_chains() {
132-
// Angular's serialize() adds trailing semicolon for chain expressions
132+
// Angular's serialize() does NOT add trailing semicolon for chain expressions
133133
let result = parse_action_and_serialize(" 1234; 4321 ");
134-
assert_eq!(result, "1234; 4321;");
134+
assert_eq!(result, "1234; 4321");
135135
}
136136
}
137137

@@ -316,9 +316,9 @@ mod pipes {
316316

317317
#[test]
318318
fn serializes_pipes() {
319-
// Angular's serialize() wraps pipes in parentheses
319+
// Angular's serialize() does NOT wrap pipes in parentheses
320320
let result = parse_and_serialize(" foo | pipe ");
321-
assert_eq!(result, "(foo | pipe)");
321+
assert_eq!(result, "foo | pipe");
322322
}
323323
}
324324

crates/oxc_angular_compiler/tests/utils/unparser.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,11 @@ fn binary_op_str(op: BinaryOperator) -> &'static str {
130130
}
131131

132132
fn visit_chain(chain: &Chain<'_>, out: &mut String) {
133-
// Angular's serialize() always adds a trailing semicolon for chain expressions
133+
// Angular's serialize() does NOT add a trailing semicolon for chain expressions
134134
let len = chain.expressions.len();
135135
for (i, expr) in chain.expressions.iter().enumerate() {
136136
visit_expression(expr, out);
137-
if i == len - 1 {
138-
out.push(';'); // Trailing semicolon for last expression
139-
} else {
137+
if i < len - 1 {
140138
out.push_str("; ");
141139
}
142140
}
@@ -152,16 +150,14 @@ fn visit_conditional(cond: &Conditional<'_>, out: &mut String) {
152150
}
153151

154152
fn visit_pipe(pipe: &BindingPipe<'_>, out: &mut String) {
155-
// Angular's serialize() wraps pipes in parentheses
156-
out.push('(');
153+
// Angular's serialize() does NOT wrap pipes in parentheses
157154
visit_expression(&pipe.exp, out);
158155
out.push_str(" | ");
159156
out.push_str(pipe.name.as_str());
160157
for arg in pipe.args.iter() {
161158
out.push(':');
162159
visit_expression(arg, out);
163160
}
164-
out.push(')');
165161
}
166162

167163
fn visit_call(call: &Call<'_>, out: &mut String) {

tasks/angular_conformance/fixtures/expression_parser_parser_spec.json

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,7 +1528,28 @@
15281528
{
15291529
"name": "should not report interpolation inside a string",
15301530
"path": "parser/parseAction/should not report interpolation inside a string",
1531-
"assertions": []
1531+
"assertions": [
1532+
{
1533+
"type": "CheckAction",
1534+
"input": "\"{{a()}}\"",
1535+
"expected": null
1536+
},
1537+
{
1538+
"type": "CheckAction",
1539+
"input": "'{{a()}}'",
1540+
"expected": null
1541+
},
1542+
{
1543+
"type": "CheckAction",
1544+
"input": "\"{{a('\\\"')}}\"",
1545+
"expected": null
1546+
},
1547+
{
1548+
"type": "CheckAction",
1549+
"input": "'{{a(\"\\'\")}}'",
1550+
"expected": null
1551+
}
1552+
]
15321553
}
15331554
]
15341555
},
@@ -1828,7 +1849,28 @@
18281849
{
18291850
"name": "should not report interpolation inside a string",
18301851
"path": "parser/parseBinding/should not report interpolation inside a string",
1831-
"assertions": []
1852+
"assertions": [
1853+
{
1854+
"type": "CheckBinding",
1855+
"input": "\"{{exp}}\"",
1856+
"expected": null
1857+
},
1858+
{
1859+
"type": "CheckBinding",
1860+
"input": "'{{exp}}'",
1861+
"expected": null
1862+
},
1863+
{
1864+
"type": "CheckBinding",
1865+
"input": "'{{\\\"}}'",
1866+
"expected": null
1867+
},
1868+
{
1869+
"type": "CheckBinding",
1870+
"input": "'{{\\'}}'",
1871+
"expected": null
1872+
}
1873+
]
18321874
},
18331875
{
18341876
"name": "should parse conditional expression",
@@ -2155,7 +2197,28 @@
21552197
{
21562198
"name": "should not report interpolation inside a string",
21572199
"path": "parser/parseSimpleBinding/should not report interpolation inside a string",
2158-
"assertions": []
2200+
"assertions": [
2201+
{
2202+
"type": "CheckBinding",
2203+
"input": "\"{{exp}}\"",
2204+
"expected": null
2205+
},
2206+
{
2207+
"type": "CheckBinding",
2208+
"input": "'{{exp}}'",
2209+
"expected": null
2210+
},
2211+
{
2212+
"type": "CheckBinding",
2213+
"input": "'{{\\\"}}'",
2214+
"expected": null
2215+
},
2216+
{
2217+
"type": "CheckBinding",
2218+
"input": "'{{\\'}}'",
2219+
"expected": null
2220+
}
2221+
]
21592222
},
21602223
{
21612224
"name": "should report when encountering field write",

tasks/angular_conformance/fixtures/expression_parser_serializer_spec.json

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,13 @@
5656
{
5757
"name": "serializes chains",
5858
"path": "serializer/serialize/serializes chains",
59-
"assertions": []
59+
"assertions": [
60+
{
61+
"type": "SerializeExpression",
62+
"input": " 1234; 4321 ",
63+
"expected": "1234; 4321"
64+
}
65+
]
6066
},
6167
{
6268
"name": "serializes conditionals",
@@ -228,7 +234,13 @@
228234
{
229235
"name": "serializes property writes",
230236
"path": "serializer/serialize/serializes property writes",
231-
"assertions": []
237+
"assertions": [
238+
{
239+
"type": "SerializeExpression",
240+
"input": " foo . bar = baz ",
241+
"expected": "foo.bar = baz"
242+
}
243+
]
232244
},
233245
{
234246
"name": "serializes safe property reads",

0 commit comments

Comments
 (0)