From 1f2db5e8e28f4fe811ad179bd2edbbda5670da34 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Tue, 15 Sep 2020 23:52:36 +0800 Subject: [PATCH 1/6] (test) add failing case for param grammar contains null --- src/grammar.pest | 5 ++--- src/grammar.rs | 4 +++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/grammar.pest b/src/grammar.pest index cc3f52177..2ef0c1ae6 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -1,5 +1,5 @@ WHITESPACE = _{ " "|"\t"|"\n"|"\r" } -keywords = @{ "as" | "else" } +keywords = { "as" | "else" } escape = @{ ("\\" ~ "{{" ~ "{{"?) | ("\\" ~ "\\"+ ~ &"{{") } raw_text = ${ ( escape | (!"{{" ~ ANY) )+ } @@ -14,8 +14,7 @@ literal = { string_literal | null_literal = { "null" } boolean_literal = { "true"|"false" } -number_literal = @{ "-"? ~ ASCII_DIGIT+ ~ "."? ~ ASCII_DIGIT* -~ ("E" ~ "-"? ~ ASCII_DIGIT+)? } +number_literal = @{ "-"? ~ ASCII_DIGIT+ ~ "."? ~ ASCII_DIGIT* ~ ("E" ~ "-"? ~ ASCII_DIGIT+)? } string_literal = @{ ("\"" ~ (!"\"" ~ ("\\\"" | ANY))* ~ "\"") | ("'" ~ (!"'" ~ ("\\'" | ANY))* ~ "'") } array_literal = { "[" ~ literal? ~ ("," ~ literal)* ~ "]" } object_literal = { "{" ~ (string_literal ~ ":" ~ literal)? diff --git a/src/grammar.rs b/src/grammar.rs index d493f06a0..61de3a6eb 100644 --- a/src/grammar.rs +++ b/src/grammar.rs @@ -100,7 +100,7 @@ mod test { #[test] fn test_param() { - let s = vec!["hello", "\"json literal\""]; + let s = vec!["hello", "\"json literal\"", "nullable", "truestory"]; for i in s.iter() { assert_rule!(Rule::param, i); } @@ -132,6 +132,7 @@ mod test { "{\"hello\": \"world\"}", "{}", "{\"a\":1, \"b\":2 }", + "\"nullable\"", ]; for i in s.iter() { assert_rule!(Rule::literal, i); @@ -289,6 +290,7 @@ mod test { "./[/foo]", "[foo]", "@root/a/b", + "nullable", ]; for i in s.iter() { assert_rule_match!(Rule::path, i); From ec3ba02a53a7792513634711c89d157f8f3f77c4 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Wed, 16 Sep 2020 08:35:57 +0800 Subject: [PATCH 2/6] (test) add test to reproduce #381 --- src/registry.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/registry.rs b/src/registry.rs index 946b0ec7a..caa8a3af5 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -895,4 +895,57 @@ mod test { .unwrap() ); } + + #[test] + fn test_keys_starts_with_null() { + env_logger::init(); + let reg = Registry::new(); + let data = json!({ + "optional": true, + "is_null": true, + "nullable": true, + "null": true, + "falsevalue": true, + }); + assert_eq!( + "optional: true --> true", + reg.render_template( + "optional: {{optional}} --> {{#if optional }}true{{else}}false{{/if}}", + &data + ) + .unwrap() + ); + assert_eq!( + "is_null: true --> true", + reg.render_template( + "is_null: {{is_null}} --> {{#if is_null }}true{{else}}false{{/if}}", + &data + ) + .unwrap() + ); + assert_eq!( + "nullable: true --> true", + reg.render_template( + "nullable: {{nullable}} --> {{#if nullable }}true{{else}}false{{/if}}", + &data + ) + .unwrap() + ); + assert_eq!( + "falsevalue: true --> true", + reg.render_template( + "falsevalue: {{falsevalue}} --> {{#if falsevalue }}true{{else}}false{{/if}}", + &data + ) + .unwrap() + ); + assert_eq!( + "null: true --> false", + reg.render_template( + "null: {{null}} --> {{#if null }}true{{else}}false{{/if}}", + &data + ) + .unwrap() + ); + } } From 59d2c6f3b96c27cd6d9f442aefe034a1576d6a46 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Sat, 19 Sep 2020 10:46:16 +0800 Subject: [PATCH 3/6] (fix) null and boolean literal rules --- src/grammar.pest | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/grammar.pest b/src/grammar.pest index 2ef0c1ae6..3736ff006 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -12,8 +12,8 @@ literal = { string_literal | null_literal | boolean_literal } -null_literal = { "null" } -boolean_literal = { "true"|"false" } +null_literal = @{ "null" ~ !symbol_char } +boolean_literal = @{ "true"|"false" ~ !symbol_char } number_literal = @{ "-"? ~ ASCII_DIGIT+ ~ "."? ~ ASCII_DIGIT* ~ ("E" ~ "-"? ~ ASCII_DIGIT+)? } string_literal = @{ ("\"" ~ (!"\"" ~ ("\\\"" | ANY))* ~ "\"") | ("'" ~ (!"'" ~ ("\\'" | ANY))* ~ "'") } array_literal = { "[" ~ literal? ~ ("," ~ literal)* ~ "]" } @@ -30,7 +30,7 @@ reference = ${ path_inline } name = _{ subexpression | reference } -param = { !(keywords ~ !symbol_char) ~ (literal | reference | subexpression) } +param = { !(keywords ~ !symbol_char) ~ ( literal | reference | subexpression) } hash = { identifier ~ "=" ~ param } block_param = { "as" ~ "|" ~ identifier ~ identifier? ~ "|"} exp_line = _{ identifier ~ (hash|param)* ~ block_param?} From 2a578ae6ce4ad64e0597cf812963241f659c8491 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Sat, 19 Sep 2020 13:14:59 +0800 Subject: [PATCH 4/6] (fix) literal for boolean --- src/grammar.pest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/grammar.pest b/src/grammar.pest index 3736ff006..9f4d180a4 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -13,7 +13,7 @@ literal = { string_literal | boolean_literal } null_literal = @{ "null" ~ !symbol_char } -boolean_literal = @{ "true"|"false" ~ !symbol_char } +boolean_literal = @{ ("true"|"false") ~ !symbol_char } number_literal = @{ "-"? ~ ASCII_DIGIT+ ~ "."? ~ ASCII_DIGIT* ~ ("E" ~ "-"? ~ ASCII_DIGIT+)? } string_literal = @{ ("\"" ~ (!"\"" ~ ("\\\"" | ANY))* ~ "\"") | ("'" ~ (!"'" ~ ("\\'" | ANY))* ~ "'") } array_literal = { "[" ~ literal? ~ ("," ~ literal)* ~ "]" } From 3ad1edcd14433f8aa64c21ee4293acd94b2f9998 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Sat, 19 Sep 2020 13:18:14 +0800 Subject: [PATCH 5/6] (test) add another case to demo key with null as string --- src/registry.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/registry.rs b/src/registry.rs index caa8a3af5..34ecf5d56 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -947,5 +947,13 @@ mod test { ) .unwrap() ); + assert_eq!( + "null: true --> true", + reg.render_template( + "null: {{null}} --> {{#if this.[null]}}true{{else}}false{{/if}}", + &data + ) + .unwrap() + ); } } From 567eea6f42371ae966cfa936572cda4fa336d6eb Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Sat, 19 Sep 2020 20:54:23 +0800 Subject: [PATCH 6/6] (refactor) grammar clean up --- src/grammar.pest | 6 +++--- src/grammar.rs | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/grammar.pest b/src/grammar.pest index 9f4d180a4..415b0a2e8 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -20,8 +20,8 @@ array_literal = { "[" ~ literal? ~ ("," ~ literal)* ~ "]" } object_literal = { "{" ~ (string_literal ~ ":" ~ literal)? ~ ("," ~ string_literal ~ ":" ~ literal)* ~ "}" } -symbol_char = _{'a'..'z'|'A'..'Z'|ASCII_DIGIT|"-"|"_"|"$"|'\u{80}'..'\u{7ff}'|'\u{800}'..'\u{ffff}'|'\u{10000}'..'\u{10ffff}'} -partial_symbol_char = _{'a'..'z'|'A'..'Z'|ASCII_DIGIT|"-"|"_"|'\u{80}'..'\u{7ff}'|'\u{800}'..'\u{ffff}'|'\u{10000}'..'\u{10ffff}'|"/"|"."} +symbol_char = _{ASCII_ALPHANUMERIC|"-"|"_"|"$"|'\u{80}'..'\u{7ff}'|'\u{800}'..'\u{ffff}'|'\u{10000}'..'\u{10ffff}'} +partial_symbol_char = _{ASCII_ALPHANUMERIC|"-"|"_"|'\u{80}'..'\u{7ff}'|'\u{800}'..'\u{ffff}'|'\u{10000}'..'\u{10ffff}'|"/"|"."} path_char = _{ "/" } identifier = @{ symbol_char+ } @@ -30,7 +30,7 @@ reference = ${ path_inline } name = _{ subexpression | reference } -param = { !(keywords ~ !symbol_char) ~ ( literal | reference | subexpression) } +param = { !(keywords ~ !symbol_char) ~ (literal | reference | subexpression) } hash = { identifier ~ "=" ~ param } block_param = { "as" ~ "|" ~ identifier ~ identifier? ~ "|"} exp_line = _{ identifier ~ (hash|param)* ~ block_param?} diff --git a/src/grammar.rs b/src/grammar.rs index 61de3a6eb..5de84ba14 100644 --- a/src/grammar.rs +++ b/src/grammar.rs @@ -84,6 +84,7 @@ mod test { "this.[$id]", "[$id]", "$id", + "this.[null]", ]; for i in s.iter() { assert_rule!(Rule::reference, i);