From 196740ae349fbf419a0e693040ead7b7b65ae360 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 12:51:27 -0400 Subject: [PATCH 01/20] Starting the greater than helper tests. --- js/test_cases/helpers_gt/README.md | 3 +++ js/test_cases/helpers_gt/input1.json | 7 +++++++ js/test_cases/helpers_gt/main.dust | 21 +++++++++++++++++++++ js/test_cases/helpers_ne/README.md | 10 ---------- 4 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 js/test_cases/helpers_gt/README.md create mode 100644 js/test_cases/helpers_gt/input1.json create mode 100644 js/test_cases/helpers_gt/main.dust delete mode 100644 js/test_cases/helpers_ne/README.md diff --git a/js/test_cases/helpers_gt/README.md b/js/test_cases/helpers_gt/README.md new file mode 100644 index 0000000..09c6441 --- /dev/null +++ b/js/test_cases/helpers_gt/README.md @@ -0,0 +1,3 @@ +Since "master" is greater than "7", dust is probably ordering based on either alphabetic sorting or ascii values. + +All comparisons between non-matching types (for example, int vs string) appear to render the else block. diff --git a/js/test_cases/helpers_gt/input1.json b/js/test_cases/helpers_gt/input1.json new file mode 100644 index 0000000..ece58d2 --- /dev/null +++ b/js/test_cases/helpers_gt/input1.json @@ -0,0 +1,7 @@ +{ + "str": "master", + "int": 7, + "alpha": 21, + "beta": "21", + "null": null +} diff --git a/js/test_cases/helpers_gt/main.dust b/js/test_cases/helpers_gt/main.dust new file mode 100644 index 0000000..d752542 --- /dev/null +++ b/js/test_cases/helpers_gt/main.dust @@ -0,0 +1,21 @@ +Testing helpers:{~n} +str is {str}{~n} +int is {int}{~n} +alpha is {alpha}{~n} +beta is {beta}{~n} +{@gt key=str value="master"}str is greater than "master"{:else}str is less than or equal to "master"{/gt}{~n} +{@gt key=str value="7"}str is greater than "7"{:else}str is less than or equal to "7"{/gt}{~n} +{@gt key=int value="7"}int is greater than "7"{:else}int is less than or equal to "7"{/gt}{~n} +{@gt key=int value=7}int is greater than 7{:else}int is less than or equal to 7{/gt}{~n} +{@gt key=int value=6}int is greater than 6{:else}int is less than or equal to 6{/gt}{~n} +{@gt key=alpha value=beta}alpha is greater than beta{:else}alpha is less than or equal to beta{/gt}{~n} +{! +{@gt value=beta}missing key is true{:else}missing key is false{/gt}{~n} +{@gt value=gamma}missing key and non-existent value is true{:else}missing key and non-existent value is false{/gt}{~n} +{@gt key=alpha}missing value is true{:else}missing value is false{/gt}{~n} +{@gt key=gamma}missing value and non-existent key is true{:else}missing value and non-existent key is false{/gt}{~n} +{@gt key="master" value="master"}"master" is equal to "master"{:else}"master" does not equal "master"{/gt}{~n} +{@gt key=null}null equals a missing value{:else}null does not equal a missing value{/gt}{~n} +{@gt key=null value=gamma}null equals a non-existent value{:else}null does not equal a non-existent value{/gt}{~n} +{@gt}no parameters is true{:else}no parameters if false{/gt}{~n} +!} diff --git a/js/test_cases/helpers_ne/README.md b/js/test_cases/helpers_ne/README.md deleted file mode 100644 index 42d393a..0000000 --- a/js/test_cases/helpers_ne/README.md +++ /dev/null @@ -1,10 +0,0 @@ -Without a key parameter, neither the main block nor the else block is rendered. - -Literal values work in both keys and values. - -Can't Walk Theory ------------------ - -Assuming a missing value = cantwalk and a non-existent key = cantwalk then their equality makes sense. - -The null tests have proven that absent parameters and missing values do not equal null and therefore it is not just making all falsey values equal. From f390c05a4c504fd21051b1db79c6b8f5845f84b3 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 13:00:09 -0400 Subject: [PATCH 02/20] Finished porting over the equality test to greater than. --- js/test_cases/helpers_eq/main.dust | 2 +- js/test_cases/helpers_gt/README.md | 2 ++ js/test_cases/helpers_gt/main.dust | 11 +++++------ js/test_cases/helpers_ne/main.dust | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/js/test_cases/helpers_eq/main.dust b/js/test_cases/helpers_eq/main.dust index 8126b32..ab68cf3 100644 --- a/js/test_cases/helpers_eq/main.dust +++ b/js/test_cases/helpers_eq/main.dust @@ -15,4 +15,4 @@ beta is {beta}{~n} {@eq key="master" value="master"}"master" is equal to "master"{:else}"master" does not equal "master"{/eq}{~n} {@eq key=null}null equals a missing value{:else}null does not equal a missing value{/eq}{~n} {@eq key=null value=gamma}null equals a non-existent value{:else}null does not equal a non-existent value{/eq}{~n} -{@eq}no parameters is true{:else}no parameters if false{/eq}{~n} +{@eq}no parameters is true{:else}no parameters is false{/eq}{~n} diff --git a/js/test_cases/helpers_gt/README.md b/js/test_cases/helpers_gt/README.md index 09c6441..0b8a68b 100644 --- a/js/test_cases/helpers_gt/README.md +++ b/js/test_cases/helpers_gt/README.md @@ -1,3 +1,5 @@ Since "master" is greater than "7", dust is probably ordering based on either alphabetic sorting or ascii values. All comparisons between non-matching types (for example, int vs string) appear to render the else block. + +Greater than follows the same pattern for not rendering when key is omitted or null. diff --git a/js/test_cases/helpers_gt/main.dust b/js/test_cases/helpers_gt/main.dust index d752542..ae88ded 100644 --- a/js/test_cases/helpers_gt/main.dust +++ b/js/test_cases/helpers_gt/main.dust @@ -9,13 +9,12 @@ beta is {beta}{~n} {@gt key=int value=7}int is greater than 7{:else}int is less than or equal to 7{/gt}{~n} {@gt key=int value=6}int is greater than 6{:else}int is less than or equal to 6{/gt}{~n} {@gt key=alpha value=beta}alpha is greater than beta{:else}alpha is less than or equal to beta{/gt}{~n} -{! {@gt value=beta}missing key is true{:else}missing key is false{/gt}{~n} {@gt value=gamma}missing key and non-existent value is true{:else}missing key and non-existent value is false{/gt}{~n} {@gt key=alpha}missing value is true{:else}missing value is false{/gt}{~n} {@gt key=gamma}missing value and non-existent key is true{:else}missing value and non-existent key is false{/gt}{~n} -{@gt key="master" value="master"}"master" is equal to "master"{:else}"master" does not equal "master"{/gt}{~n} -{@gt key=null}null equals a missing value{:else}null does not equal a missing value{/gt}{~n} -{@gt key=null value=gamma}null equals a non-existent value{:else}null does not equal a non-existent value{/gt}{~n} -{@gt}no parameters is true{:else}no parameters if false{/gt}{~n} -!} +{@gt key="master" value="master"}"master" is greater than "master"{:else}"master" is less than or equal to "master"{/gt}{~n} +{@gt key=null}null is greater than a missing value{:else}null is less than or equal to a missing value{/gt}{~n} +{@gt key=null value=gamma}null is greater than a non-existent value{:else}null is less than or equal to a non-existent value{/gt}{~n} +{@gt}no parameters is true{:else}no parameters is false{/gt}{~n} + diff --git a/js/test_cases/helpers_ne/main.dust b/js/test_cases/helpers_ne/main.dust index f9ed426..67f8644 100644 --- a/js/test_cases/helpers_ne/main.dust +++ b/js/test_cases/helpers_ne/main.dust @@ -15,4 +15,4 @@ beta is {beta}{~n} {@ne key="master" value="master"}"master" does not equal "master"{:else}"master" is equal to "master"{/ne}{~n} {@ne key=null}null does not equal a missing value{:else}null equals a missing value{/ne}{~n} {@ne key=null value=gamma}null does not equal non-existent value{:else}null equals a non-existent value{/ne}{~n} -{@ne}no parameters is true{:else}no parameters if false{/ne}{~n} +{@ne}no parameters is true{:else}no parameters is false{/ne}{~n} From 8a44bc6fd9e9ef7a64caf14880604168ba6b2e23 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 13:06:52 -0400 Subject: [PATCH 03/20] Add greater-than-specific tests to investigate string ordering. --- js/test_cases/helpers_gt/README.md | 2 +- js/test_cases/helpers_gt/main.dust | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/js/test_cases/helpers_gt/README.md b/js/test_cases/helpers_gt/README.md index 0b8a68b..d982ece 100644 --- a/js/test_cases/helpers_gt/README.md +++ b/js/test_cases/helpers_gt/README.md @@ -1,4 +1,4 @@ -Since "master" is greater than "7", dust is probably ordering based on either alphabetic sorting or ascii values. +Based on my tests, it appears dust is sorting based on ascii-table values. This also appears to extend to unicode codepoints based on a symbols test. All comparisons between non-matching types (for example, int vs string) appear to render the else block. diff --git a/js/test_cases/helpers_gt/main.dust b/js/test_cases/helpers_gt/main.dust index ae88ded..a801230 100644 --- a/js/test_cases/helpers_gt/main.dust +++ b/js/test_cases/helpers_gt/main.dust @@ -17,4 +17,7 @@ beta is {beta}{~n} {@gt key=null}null is greater than a missing value{:else}null is less than or equal to a missing value{/gt}{~n} {@gt key=null value=gamma}null is greater than a non-existent value{:else}null is less than or equal to a non-existent value{/gt}{~n} {@gt}no parameters is true{:else}no parameters is false{/gt}{~n} - +{@gt key="a" value="]"}"a" is greater than "]"{:else}"a" is less than or equal to "]"{/gt}{~n} +{@gt key="a" value="A"}"a" is greater than "A"{:else}"a" is less than or equal to "A"{/gt}{~n} +{@gt key="a" value="}"}"a" is greater than "}"{:else}"a" is less than or equal to "}"{/gt}{~n} +{@gt key="☃" value="☄"}"☃" is greater than "☄"{:else}"☃" is less than or equal to "☄"{/gt}{~n} From 8748cb7063f6c21acc8cb767a53fbbffd0c8a74f Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 13:31:52 -0400 Subject: [PATCH 04/20] Structure for ordering, need to implement for serde_json::Value. --- src/bin.rs | 6 +++++ src/renderer/context_element.rs | 10 +++++++- src/renderer/parameters_context.rs | 41 +++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/bin.rs b/src/bin.rs index f764ebd..c72d00d 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -11,6 +11,7 @@ use renderer::RenderError; use renderer::Renderable; use renderer::WalkError; use renderer::Walkable; +use std::cmp::Ordering; use std::env; use std::fs; use std::io::{self, Read}; @@ -158,4 +159,9 @@ impl CompareContextElement for serde_json::Value { } false } + + fn partial_compare(&self, other: &dyn ContextElement) -> Option { + // TODO: Implement + None + } } diff --git a/src/renderer/context_element.rs b/src/renderer/context_element.rs index 3db0f27..bb43cf8 100644 --- a/src/renderer/context_element.rs +++ b/src/renderer/context_element.rs @@ -2,7 +2,7 @@ use crate::parser::Filter; use crate::renderer::errors::RenderError; use crate::renderer::errors::WalkError; use std::any::Any; -use std::fmt::Debug; +use std::{cmp::Ordering, fmt::Debug}; pub trait ContextElement: Debug + Walkable + Renderable + Loopable + CloneIntoBoxedContextElement + CompareContextElement @@ -36,6 +36,8 @@ pub trait CastToAny { pub trait CompareContextElement: CastToAny { fn equals(&self, other: &dyn ContextElement) -> bool; + + fn partial_compare(&self, other: &dyn ContextElement) -> Option; } pub trait CloneIntoBoxedContextElement { @@ -59,3 +61,9 @@ impl<'a, 'b> PartialEq<&'b dyn ContextElement> for &'a dyn ContextElement { self.equals(*other) } } + +impl<'a, 'b> PartialOrd<&'b dyn ContextElement> for &'a dyn ContextElement { + fn partial_cmp(&self, other: &&'b dyn ContextElement) -> Option { + self.partial_compare(*other) + } +} diff --git a/src/renderer/parameters_context.rs b/src/renderer/parameters_context.rs index 9d5d749..5812ce3 100644 --- a/src/renderer/parameters_context.rs +++ b/src/renderer/parameters_context.rs @@ -8,7 +8,7 @@ use crate::renderer::RenderError; use crate::renderer::Renderable; use crate::renderer::WalkError; use crate::renderer::Walkable; -use std::collections::HashMap; +use std::{cmp::Ordering, collections::HashMap}; /// Copy the data from an RValue to an Owned struct /// @@ -122,6 +122,11 @@ impl CompareContextElement for ParametersContext { // TODO: Does this ever happen? perhaps I should have a panic here. false } + + fn partial_compare(&self, other: &dyn ContextElement) -> Option { + // TODO: Does this ever happen? perhaps I should have a panic here. + None + } } impl ContextElement for String {} @@ -158,6 +163,23 @@ impl CompareContextElement for String { Some(other_string) => self == other_string, } } + + fn partial_compare(&self, other: &dyn ContextElement) -> Option { + // If its a string then compare them directly, otherwise defer + // to the other type's implementation of CompareContextElement + // since the end user could add any type. + match other.to_any().downcast_ref::() { + None => match other.partial_compare(self) { + None => None, + Some(ord) => match ord { + Ordering::Equal => Some(Ordering::Equal), + Ordering::Greater => Some(Ordering::Less), + Ordering::Less => Some(Ordering::Greater), + }, + }, + Some(other_string) => self.partial_cmp(other_string), + } + } } impl ContextElement for u64 {} @@ -190,4 +212,21 @@ impl CompareContextElement for u64 { Some(other_num) => self == other_num, } } + + fn partial_compare(&self, other: &dyn ContextElement) -> Option { + // If its a u64 then compare them directly, otherwise defer + // to the other type's implementation of CompareContextElement + // since the end user could add any type. + match other.to_any().downcast_ref::() { + None => match other.partial_compare(self) { + None => None, + Some(ord) => match ord { + Ordering::Equal => Some(Ordering::Equal), + Ordering::Greater => Some(Ordering::Less), + Ordering::Less => Some(Ordering::Greater), + }, + }, + Some(other_num) => self.partial_cmp(other_num), + } + } } From 9851a2556dbf24516bdb6ec3548fc34b9fa91875 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 13:40:56 -0400 Subject: [PATCH 05/20] Ordering implementation for comparison between json and literals. --- src/bin.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/bin.rs b/src/bin.rs index c72d00d..7e41d8d 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -161,7 +161,25 @@ impl CompareContextElement for serde_json::Value { } fn partial_compare(&self, other: &dyn ContextElement) -> Option { - // TODO: Implement + // Handle other serde_json::Value + match other.to_any().downcast_ref::() { + None => (), + Some(other_json_value) => return None, // TODO: Implement + } + // Handle string literals + match other.to_any().downcast_ref::() { + None => (), + Some(other_string) => { + return self + .as_str() + .map_or(None, |s| s.partial_cmp(other_string.as_str())) + } + } + // Handle numeric literals + match other.to_any().downcast_ref::() { + None => (), + Some(other_num) => return self.as_u64().map_or(None, |n| n.partial_cmp(other_num)), + } None } } From 563fd1f6dbdd332bfcff1bc2b57857394ed4a535 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 13:44:34 -0400 Subject: [PATCH 06/20] Starting comparison of json value to json value. --- src/bin.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/bin.rs b/src/bin.rs index 7e41d8d..afcf538 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -164,7 +164,12 @@ impl CompareContextElement for serde_json::Value { // Handle other serde_json::Value match other.to_any().downcast_ref::() { None => (), - Some(other_json_value) => return None, // TODO: Implement + Some(other_json_value) => { + return match (self, other_json_value) { + // TODO: Implement + _ => None, + }; + } } // Handle string literals match other.to_any().downcast_ref::() { From 71e6da39eef2a464c4c4fd6937f26fc886b59def Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 13:46:31 -0400 Subject: [PATCH 07/20] Add a test for boolean comparison. --- js/test_cases/helpers_gt/input1.json | 4 +++- js/test_cases/helpers_gt/main.dust | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/js/test_cases/helpers_gt/input1.json b/js/test_cases/helpers_gt/input1.json index ece58d2..3a631f3 100644 --- a/js/test_cases/helpers_gt/input1.json +++ b/js/test_cases/helpers_gt/input1.json @@ -3,5 +3,7 @@ "int": 7, "alpha": 21, "beta": "21", - "null": null + "null": null, + "true_value": true, + "false_value": false } diff --git a/js/test_cases/helpers_gt/main.dust b/js/test_cases/helpers_gt/main.dust index a801230..d92bc99 100644 --- a/js/test_cases/helpers_gt/main.dust +++ b/js/test_cases/helpers_gt/main.dust @@ -21,3 +21,4 @@ beta is {beta}{~n} {@gt key="a" value="A"}"a" is greater than "A"{:else}"a" is less than or equal to "A"{/gt}{~n} {@gt key="a" value="}"}"a" is greater than "}"{:else}"a" is less than or equal to "}"{/gt}{~n} {@gt key="☃" value="☄"}"☃" is greater than "☄"{:else}"☃" is less than or equal to "☄"{/gt}{~n} +{@gt key=true_value value=false_value}true is greater than false{:else}true is less than or equal to false{/gt}{~n} From 2b5bec05be0f74fc33aaad6687438c1e40905829 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 14:08:59 -0400 Subject: [PATCH 08/20] Implemented partial_compare for scalar json values. --- src/bin.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/bin.rs b/src/bin.rs index afcf538..659faf5 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -166,7 +166,52 @@ impl CompareContextElement for serde_json::Value { None => (), Some(other_json_value) => { return match (self, other_json_value) { - // TODO: Implement + ( + serde_json::Value::Bool(self_boolean), + serde_json::Value::Bool(other_boolean), + ) => self_boolean.partial_cmp(other_boolean), + ( + serde_json::Value::Number(self_number), + serde_json::Value::Number(other_number), + ) => match ( + self_number.as_f64(), + other_number.as_f64(), + self_number.as_u64(), + other_number.as_u64(), + self_number.as_i64(), + other_number.as_i64(), + ) { + (_, _, _, _, Some(self_int), Some(other_int)) => { + self_int.partial_cmp(&other_int) + } + (_, _, Some(self_uint), Some(other_uint), _, _) => { + self_uint.partial_cmp(&other_uint) + } + (_, _, Some(_self_uint), _, _, Some(_other_int)) => { + // If the previous matches did not catch + // it, then other must be negative and + // self must be larger than can be + // represented with an i64, therefore self + // is greater than other. + Some(Ordering::Greater) + } + (_, _, _, Some(_other_uint), Some(_self_int), _) => { + // If the previous matches did not catch + // it, then self must be negative and + // other must be larger than can be + // represented with an i64, therefore + // other is greater than self. + Some(Ordering::Less) + } + (Some(self_float), Some(other_float), _, _, _, _) => { + self_float.partial_cmp(&other_float) + } + _ => panic!("This should be impossible since u64 and i64 can both be converted to floats"), + }, + ( + serde_json::Value::String(self_string), + serde_json::Value::String(other_string), + ) => self_string.partial_cmp(other_string), _ => None, }; } From 6dbeb77a289a82db6ee9dad241405b0462c25969 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 14:15:44 -0400 Subject: [PATCH 09/20] Add arrays to all helpers tests. --- js/test_cases/helpers_eq/input1.json | 11 ++++++++++- js/test_cases/helpers_eq/main.dust | 2 ++ js/test_cases/helpers_gt/README.md | 2 ++ js/test_cases/helpers_gt/input1.json | 11 ++++++++++- js/test_cases/helpers_gt/main.dust | 2 ++ js/test_cases/helpers_ne/input1.json | 11 ++++++++++- js/test_cases/helpers_ne/main.dust | 2 ++ src/bin.rs | 1 + 8 files changed, 39 insertions(+), 3 deletions(-) diff --git a/js/test_cases/helpers_eq/input1.json b/js/test_cases/helpers_eq/input1.json index ece58d2..0c96e44 100644 --- a/js/test_cases/helpers_eq/input1.json +++ b/js/test_cases/helpers_eq/input1.json @@ -3,5 +3,14 @@ "int": 7, "alpha": 21, "beta": "21", - "null": null + "null": null, + "array_lower": [ + 3, + 5, + 7 + ], + "array_higher": [ + 8, + 9 + ] } diff --git a/js/test_cases/helpers_eq/main.dust b/js/test_cases/helpers_eq/main.dust index ab68cf3..fd065f8 100644 --- a/js/test_cases/helpers_eq/main.dust +++ b/js/test_cases/helpers_eq/main.dust @@ -16,3 +16,5 @@ beta is {beta}{~n} {@eq key=null}null equals a missing value{:else}null does not equal a missing value{/eq}{~n} {@eq key=null value=gamma}null equals a non-existent value{:else}null does not equal a non-existent value{/eq}{~n} {@eq}no parameters is true{:else}no parameters is false{/eq}{~n} +{@eq key=array_lower value=array_higher}[3,5,7] is equal to [8,9]{:else}[3,5,7] does not equal [8,9]{/eq}{~n} +{@eq key=array_lower value=array_lower}[3,5,7] is equal to [3,5,7]{:else}[3,5,7] does not equal [3,5,7]{/eq}{~n} diff --git a/js/test_cases/helpers_gt/README.md b/js/test_cases/helpers_gt/README.md index d982ece..29c57b3 100644 --- a/js/test_cases/helpers_gt/README.md +++ b/js/test_cases/helpers_gt/README.md @@ -2,4 +2,6 @@ Based on my tests, it appears dust is sorting based on ascii-table values. This All comparisons between non-matching types (for example, int vs string) appear to render the else block. +Comparisons between non-scalar types (like arrays) appears to render the else block. + Greater than follows the same pattern for not rendering when key is omitted or null. diff --git a/js/test_cases/helpers_gt/input1.json b/js/test_cases/helpers_gt/input1.json index 3a631f3..4de7a58 100644 --- a/js/test_cases/helpers_gt/input1.json +++ b/js/test_cases/helpers_gt/input1.json @@ -5,5 +5,14 @@ "beta": "21", "null": null, "true_value": true, - "false_value": false + "false_value": false, + "array_lower": [ + 3, + 5, + 7 + ], + "array_higher": [ + 8, + 9 + ] } diff --git a/js/test_cases/helpers_gt/main.dust b/js/test_cases/helpers_gt/main.dust index d92bc99..894cc88 100644 --- a/js/test_cases/helpers_gt/main.dust +++ b/js/test_cases/helpers_gt/main.dust @@ -22,3 +22,5 @@ beta is {beta}{~n} {@gt key="a" value="}"}"a" is greater than "}"{:else}"a" is less than or equal to "}"{/gt}{~n} {@gt key="☃" value="☄"}"☃" is greater than "☄"{:else}"☃" is less than or equal to "☄"{/gt}{~n} {@gt key=true_value value=false_value}true is greater than false{:else}true is less than or equal to false{/gt}{~n} +{@gt key=array_lower value=array_higher}[3,5,7] is greater than [8,9]{:else}[3,5,7] is less than or equal to [8,9]{/gt}{~n} +{@gt key=array_higher value=array_lower}[8,9] is greater than [3,5,7]{:else}[8,9] is less than or equal to [3,5,7]{/gt}{~n} diff --git a/js/test_cases/helpers_ne/input1.json b/js/test_cases/helpers_ne/input1.json index ece58d2..0c96e44 100644 --- a/js/test_cases/helpers_ne/input1.json +++ b/js/test_cases/helpers_ne/input1.json @@ -3,5 +3,14 @@ "int": 7, "alpha": 21, "beta": "21", - "null": null + "null": null, + "array_lower": [ + 3, + 5, + 7 + ], + "array_higher": [ + 8, + 9 + ] } diff --git a/js/test_cases/helpers_ne/main.dust b/js/test_cases/helpers_ne/main.dust index 67f8644..9796b47 100644 --- a/js/test_cases/helpers_ne/main.dust +++ b/js/test_cases/helpers_ne/main.dust @@ -16,3 +16,5 @@ beta is {beta}{~n} {@ne key=null}null does not equal a missing value{:else}null equals a missing value{/ne}{~n} {@ne key=null value=gamma}null does not equal non-existent value{:else}null equals a non-existent value{/ne}{~n} {@ne}no parameters is true{:else}no parameters is false{/ne}{~n} +{@ne key=array_lower value=array_higher}[3,5,7] does not equal [8,9]{:else}[3,5,7] is equal to [8,9]{/ne}{~n} +{@ne key=array_lower value=array_lower}[3,5,7] does not equal [3,5,7]{:else}[3,5,7] is equal to [3,5,7]{/ne}{~n} diff --git a/src/bin.rs b/src/bin.rs index 659faf5..2971ffa 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -212,6 +212,7 @@ impl CompareContextElement for serde_json::Value { serde_json::Value::String(self_string), serde_json::Value::String(other_string), ) => self_string.partial_cmp(other_string), + // TODO: Non-scalar types _ => None, }; } From d751df6fd5a5ccb264631ab7042808c3b3d59b1e Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 14:48:04 -0400 Subject: [PATCH 10/20] Add tests for copied values. --- js/test_cases/helpers_eq/README.md | 5 ++++ js/test_cases/helpers_eq/input1.json | 44 ++++++++++++++++++++++++++++ js/test_cases/helpers_eq/main.dust | 10 ++++++- js/test_cases/helpers_gt/input1.json | 42 ++++++++++++++++++++++++++ js/test_cases/helpers_gt/main.dust | 9 ++++++ js/test_cases/helpers_ne/input1.json | 44 ++++++++++++++++++++++++++++ js/test_cases/helpers_ne/main.dust | 10 ++++++- 7 files changed, 162 insertions(+), 2 deletions(-) diff --git a/js/test_cases/helpers_eq/README.md b/js/test_cases/helpers_eq/README.md index 42d393a..ddcf8e1 100644 --- a/js/test_cases/helpers_eq/README.md +++ b/js/test_cases/helpers_eq/README.md @@ -8,3 +8,8 @@ Can't Walk Theory Assuming a missing value = cantwalk and a non-existent key = cantwalk then their equality makes sense. The null tests have proven that absent parameters and missing values do not equal null and therefore it is not just making all falsey values equal. + +Non-Scalar Values +----------------- + +For non-scalar values, it seems that dust does mark two values as true if they have the same path, but otherwise they are not equal. diff --git a/js/test_cases/helpers_eq/input1.json b/js/test_cases/helpers_eq/input1.json index 0c96e44..bfbbd94 100644 --- a/js/test_cases/helpers_eq/input1.json +++ b/js/test_cases/helpers_eq/input1.json @@ -4,13 +4,57 @@ "alpha": 21, "beta": "21", "null": null, + "true_value": true, + "false_value": false, "array_lower": [ 3, 5, 7 ], + "copy_array_lower": [ + 3, + 5, + 7 + ], "array_higher": [ 8, 9 + ], + "some_obj": { + "name": "cat" + }, + "copy_some_obj": { + "name": "cat" + }, + "other_obj": { + "name": "dog" + }, + "array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "copy_array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "array_of_other_obj": [ + { + "name": "dog" + }, + { + "name": "dog" + } + ], + "array_of_strings": [ + "cat", + "dog" ] } diff --git a/js/test_cases/helpers_eq/main.dust b/js/test_cases/helpers_eq/main.dust index fd065f8..c1b8562 100644 --- a/js/test_cases/helpers_eq/main.dust +++ b/js/test_cases/helpers_eq/main.dust @@ -17,4 +17,12 @@ beta is {beta}{~n} {@eq key=null value=gamma}null equals a non-existent value{:else}null does not equal a non-existent value{/eq}{~n} {@eq}no parameters is true{:else}no parameters is false{/eq}{~n} {@eq key=array_lower value=array_higher}[3,5,7] is equal to [8,9]{:else}[3,5,7] does not equal [8,9]{/eq}{~n} -{@eq key=array_lower value=array_lower}[3,5,7] is equal to [3,5,7]{:else}[3,5,7] does not equal [3,5,7]{/eq}{~n} +{! non-scalar and copied value tests !} +{@eq key=array_lower value=array_lower}array_lower is equal to array_lower{:else}array_lower does not equal array_lower{/eq}{~n} +{@eq key=array_lower value=copy_array_lower}array_lower is equal to copy_array_lower{:else}array_lower does not equal copy_array_lower{/eq}{~n} +{@eq key=some_obj value=some_obj}some_obj is equal to some_obj{:else}some_obj does not equal some_obj{/eq}{~n} +{@eq key=some_obj value=copy_some_obj}some_obj is equal to copy_some_obj{:else}some_obj does not equal copy_some_obj{/eq}{~n} +{@eq key=some_obj value=other_obj}some_obj is equal to other_obj{:else}some_obj does not equal other_obj{/eq}{~n} +{@eq key=array_of_some_obj value=array_of_some_obj}array_of_some_obj is equal to array_of_some_obj{:else}array_of_some_obj does not equal array_of_some_obj{/eq}{~n} +{@eq key=array_of_some_obj value=copy_array_of_some_obj}array_of_some_obj is equal to copy_array_of_some_obj{:else}array_of_some_obj does not equal copy_array_of_some_obj{/eq}{~n} +{@eq key=array_of_some_obj value=array_of_other_obj}array_of_some_obj is equal to array_of_other_obj{:else}array_of_some_obj does not equal array_of_other_obj{/eq}{~n} diff --git a/js/test_cases/helpers_gt/input1.json b/js/test_cases/helpers_gt/input1.json index 4de7a58..bfbbd94 100644 --- a/js/test_cases/helpers_gt/input1.json +++ b/js/test_cases/helpers_gt/input1.json @@ -11,8 +11,50 @@ 5, 7 ], + "copy_array_lower": [ + 3, + 5, + 7 + ], "array_higher": [ 8, 9 + ], + "some_obj": { + "name": "cat" + }, + "copy_some_obj": { + "name": "cat" + }, + "other_obj": { + "name": "dog" + }, + "array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "copy_array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "array_of_other_obj": [ + { + "name": "dog" + }, + { + "name": "dog" + } + ], + "array_of_strings": [ + "cat", + "dog" ] } diff --git a/js/test_cases/helpers_gt/main.dust b/js/test_cases/helpers_gt/main.dust index 894cc88..9a4ffa8 100644 --- a/js/test_cases/helpers_gt/main.dust +++ b/js/test_cases/helpers_gt/main.dust @@ -24,3 +24,12 @@ beta is {beta}{~n} {@gt key=true_value value=false_value}true is greater than false{:else}true is less than or equal to false{/gt}{~n} {@gt key=array_lower value=array_higher}[3,5,7] is greater than [8,9]{:else}[3,5,7] is less than or equal to [8,9]{/gt}{~n} {@gt key=array_higher value=array_lower}[8,9] is greater than [3,5,7]{:else}[8,9] is less than or equal to [3,5,7]{/gt}{~n} +{! non-scalar and copied value tests !} +{@gt key=array_lower value=array_lower}array_lower is greater than array_lower{:else}array_lower is less than or equal to array_lower{/gt}{~n} +{@gt key=array_lower value=copy_array_lower}array_lower is greater than copy_array_lower{:else}array_lower is less than or equal to copy_array_lower{/gt}{~n} +{@gt key=some_obj value=some_obj}some_obj is greater than some_obj{:else}some_obj is less than or equal to some_obj{/gt}{~n} +{@gt key=some_obj value=copy_some_obj}some_obj is greater than copy_some_obj{:else}some_obj is less than or equal to copy_some_obj{/gt}{~n} +{@gt key=some_obj value=other_obj}some_obj is greater than other_obj{:else}some_obj is less than or equal to other_obj{/gt}{~n} +{@gt key=array_of_some_obj value=array_of_some_obj}array_of_some_obj is greater than array_of_some_obj{:else}array_of_some_obj is less than or equal to array_of_some_obj{/gt}{~n} +{@gt key=array_of_some_obj value=copy_array_of_some_obj}array_of_some_obj is greater than copy_array_of_some_obj{:else}array_of_some_obj is less than or equal to copy_array_of_some_obj{/gt}{~n} +{@gt key=array_of_some_obj value=array_of_other_obj}array_of_some_obj is greater than array_of_other_obj{:else}array_of_some_obj is less than or equal to array_of_other_obj{/gt}{~n} diff --git a/js/test_cases/helpers_ne/input1.json b/js/test_cases/helpers_ne/input1.json index 0c96e44..bfbbd94 100644 --- a/js/test_cases/helpers_ne/input1.json +++ b/js/test_cases/helpers_ne/input1.json @@ -4,13 +4,57 @@ "alpha": 21, "beta": "21", "null": null, + "true_value": true, + "false_value": false, "array_lower": [ 3, 5, 7 ], + "copy_array_lower": [ + 3, + 5, + 7 + ], "array_higher": [ 8, 9 + ], + "some_obj": { + "name": "cat" + }, + "copy_some_obj": { + "name": "cat" + }, + "other_obj": { + "name": "dog" + }, + "array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "copy_array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "array_of_other_obj": [ + { + "name": "dog" + }, + { + "name": "dog" + } + ], + "array_of_strings": [ + "cat", + "dog" ] } diff --git a/js/test_cases/helpers_ne/main.dust b/js/test_cases/helpers_ne/main.dust index 9796b47..d31e4b7 100644 --- a/js/test_cases/helpers_ne/main.dust +++ b/js/test_cases/helpers_ne/main.dust @@ -17,4 +17,12 @@ beta is {beta}{~n} {@ne key=null value=gamma}null does not equal non-existent value{:else}null equals a non-existent value{/ne}{~n} {@ne}no parameters is true{:else}no parameters is false{/ne}{~n} {@ne key=array_lower value=array_higher}[3,5,7] does not equal [8,9]{:else}[3,5,7] is equal to [8,9]{/ne}{~n} -{@ne key=array_lower value=array_lower}[3,5,7] does not equal [3,5,7]{:else}[3,5,7] is equal to [3,5,7]{/ne}{~n} +{! non-scalar and copied value tests !} +{@ne key=array_lower value=array_lower}array_lower does not equal array_lower{:else}array_lower is equals to array_lower{/ne}{~n} +{@ne key=array_lower value=copy_array_lower}array_lower does not equal copy_array_lower{:else}array_lower is equals to copy_array_lower{/ne}{~n} +{@ne key=some_obj value=some_obj}some_obj does not equal some_obj{:else}some_obj is equals to some_obj{/ne}{~n} +{@ne key=some_obj value=copy_some_obj}some_obj does not equal copy_some_obj{:else}some_obj is equals to copy_some_obj{/ne}{~n} +{@ne key=some_obj value=other_obj}some_obj does not equal other_obj{:else}some_obj is equals to other_obj{/ne}{~n} +{@ne key=array_of_some_obj value=array_of_some_obj}array_of_some_obj does not equal array_of_some_obj{:else}array_of_some_obj is equals to array_of_some_obj{/ne}{~n} +{@ne key=array_of_some_obj value=copy_array_of_some_obj}array_of_some_obj does not equal copy_array_of_some_obj{:else}array_of_some_obj is equals to copy_array_of_some_obj{/ne}{~n} +{@ne key=array_of_some_obj value=array_of_other_obj}array_of_some_obj does not equal array_of_other_obj{:else}array_of_some_obj is equals to array_of_other_obj{/ne}{~n} From 41e4874d75e67e0a75eefa40e9056fcb97b1e86b Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 15:22:48 -0400 Subject: [PATCH 11/20] Add a check to the equality helper to mark identical paths as equal. --- js/run_compliance_suite.bash | 2 +- src/renderer/renderer.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/js/run_compliance_suite.bash b/js/run_compliance_suite.bash index 4423242..a13d025 100755 --- a/js/run_compliance_suite.bash +++ b/js/run_compliance_suite.bash @@ -38,7 +38,7 @@ while read -r test_group; do else echo "$test_group_name::$test_case_name FAILED" if [ $show_diff -eq 1 ]; then - diff --label "dustjs-linked" --label "duster" <(xargs -a <(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name 'main.dust'; find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.dust' ! -name 'main.dust' | sort) node "$DIR/dustjs_shim.js" < "$test_case" 2>/dev/null ) <(xargs -a <(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name 'main.dust'; find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.dust' ! -name 'main.dust' | sort) "$DIR/../target/debug/duster-cli" < "$test_case" 2>/dev/null ) + diff --label "dustjs-linkedin" --label "duster" <(xargs -a <(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name 'main.dust'; find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.dust' ! -name 'main.dust' | sort) node "$DIR/dustjs_shim.js" < "$test_case" 2>/dev/null ) <(xargs -a <(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name 'main.dust'; find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.dust' ! -name 'main.dust' | sort) "$DIR/../target/debug/duster-cli" < "$test_case" 2>/dev/null ) fi exit 1 fi diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index addfa85..712ad63 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -230,6 +230,20 @@ impl<'a> DustRenderer<'a> { .iter() .map(|pair: &KVPair<'a>| (pair.key, &pair.value)) .collect(); + // Special case: when comparing two RVPaths, if the + // path is equal then dust assumes the values are + // equal (otherwise, non-scalar values are + // automatically not equal) + if Self::are_paths_identical(¶m_map) { + return match ¶meterized_block.contents { + None => Ok("".to_owned()), + Some(body) => { + let rendered_content = self.render_body(body, breadcrumbs, blocks)?; + Ok(rendered_content) + } + }; + } + let left_side: Result<&dyn ContextElement, WalkError> = match param_map.get("key") { None => return Ok("".to_owned()), Some(rval) => match rval { @@ -324,6 +338,19 @@ impl<'a> DustRenderer<'a> { Ok(walk_target) => walk_target.get_loop_elements(), } } + + fn are_paths_identical<'b>(param_map: &HashMap<&str, &RValue<'b>>) -> bool { + match (param_map.get("key"), param_map.get("value")) { + (None, _) => false, + (_, None) => false, + (Some(key_rval), Some(value_rval)) => match (key_rval, value_rval) { + (RValue::RVPath(key_path), RValue::RVPath(value_path)) => { + key_path.keys == value_path.keys + } + _ => false, + }, + } + } } #[cfg(test)] From 7d4cb14530273e22f3862bcc4016d327780db666 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 15:30:17 -0400 Subject: [PATCH 12/20] Add that check to the not-equals helper and update the json value implementation to mark all non-scalars as not-equals. --- src/bin.rs | 10 +++++++++- src/renderer/renderer.rs | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/bin.rs b/src/bin.rs index 2971ffa..1f698a9 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -145,7 +145,15 @@ impl CompareContextElement for serde_json::Value { // Handle other serde_json::Value match other.to_any().downcast_ref::() { None => (), - Some(other_json_value) => return self == other_json_value, + Some(other_json_value) => match (self, other_json_value) { + // Non-scalar values not caught in the renderer by the + // identical-path shortcut are always not equal. + (serde_json::Value::Array(_), _) + | (_, serde_json::Value::Array(_)) + | (serde_json::Value::Object(_), _) + | (_, serde_json::Value::Object(_)) => return false, + _ => return self == other_json_value, + }, } // Handle string literals match other.to_any().downcast_ref::() { diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 712ad63..aeee5cb 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -285,6 +285,20 @@ impl<'a> DustRenderer<'a> { .iter() .map(|pair: &KVPair<'a>| (pair.key, &pair.value)) .collect(); + // Special case: when comparing two RVPaths, if the + // path is equal then dust assumes the values are + // equal (otherwise, non-scalar values are + // automatically not equal) + if Self::are_paths_identical(¶m_map) { + return match ¶meterized_block.else_contents { + None => Ok("".to_owned()), + Some(body) => { + let rendered_content = self.render_body(body, breadcrumbs, blocks)?; + Ok(rendered_content) + } + }; + } + let left_side: Result<&dyn ContextElement, WalkError> = match param_map.get("key") { None => return Ok("".to_owned()), Some(rval) => match rval { From 02abee1c531a9a2e967c1c5ee08ad7d1faa489da Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 15:45:57 -0400 Subject: [PATCH 13/20] Add a test for gte. --- js/test_cases/helpers_gt/README.md | 16 ++++++- js/test_cases/helpers_gte/input1.json | 60 +++++++++++++++++++++++++++ js/test_cases/helpers_gte/main.dust | 35 ++++++++++++++++ src/renderer/renderer.rs | 7 ++++ 4 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 js/test_cases/helpers_gte/input1.json create mode 100644 js/test_cases/helpers_gte/main.dust diff --git a/js/test_cases/helpers_gt/README.md b/js/test_cases/helpers_gt/README.md index 29c57b3..58a764a 100644 --- a/js/test_cases/helpers_gt/README.md +++ b/js/test_cases/helpers_gt/README.md @@ -1,7 +1,19 @@ Based on my tests, it appears dust is sorting based on ascii-table values. This also appears to extend to unicode codepoints based on a symbols test. +Greater than follows the same pattern for not rendering when key is omitted or null. + + +greater than +------------ + All comparisons between non-matching types (for example, int vs string) appear to render the else block. -Comparisons between non-scalar types (like arrays) appears to render the else block. +Comparisons between non-scalar types (like arrays) appears to render the else block -Greater than follows the same pattern for not rendering when key is omitted or null. + +greater than or equals to +------------------------- + +All comparisons between non-matching types (for example, int vs string) appear to render the main block. + +Comparisons between non-scalar types (like arrays) appears to render the main block diff --git a/js/test_cases/helpers_gte/input1.json b/js/test_cases/helpers_gte/input1.json new file mode 100644 index 0000000..bfbbd94 --- /dev/null +++ b/js/test_cases/helpers_gte/input1.json @@ -0,0 +1,60 @@ +{ + "str": "master", + "int": 7, + "alpha": 21, + "beta": "21", + "null": null, + "true_value": true, + "false_value": false, + "array_lower": [ + 3, + 5, + 7 + ], + "copy_array_lower": [ + 3, + 5, + 7 + ], + "array_higher": [ + 8, + 9 + ], + "some_obj": { + "name": "cat" + }, + "copy_some_obj": { + "name": "cat" + }, + "other_obj": { + "name": "dog" + }, + "array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "copy_array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "array_of_other_obj": [ + { + "name": "dog" + }, + { + "name": "dog" + } + ], + "array_of_strings": [ + "cat", + "dog" + ] +} diff --git a/js/test_cases/helpers_gte/main.dust b/js/test_cases/helpers_gte/main.dust new file mode 100644 index 0000000..a3eb601 --- /dev/null +++ b/js/test_cases/helpers_gte/main.dust @@ -0,0 +1,35 @@ +Testing helpers:{~n} +str is {str}{~n} +int is {int}{~n} +alpha is {alpha}{~n} +beta is {beta}{~n} +{@gte key=str value="master"}str is greater than or equal to "master"{:else}str is less than "master"{/gte}{~n} +{@gte key=str value="7"}str is greater than or equal to "7"{:else}str is less than "7"{/gte}{~n} +{@gte key=int value="7"}int is greater than or equal to "7"{:else}int is less than "7"{/gte}{~n} +{@gte key=int value=7}int is greater than or equal to 7{:else}int is less than 7{/gte}{~n} +{@gte key=int value=6}int is greater than or equal to 6{:else}int is less than 6{/gte}{~n} +{@gte key=alpha value=beta}alpha is greater than or equal to beta{:else}alpha is less than beta{/gte}{~n} +{@gte value=beta}missing key is true{:else}missing key is false{/gte}{~n} +{@gte value=gamma}missing key and non-existent value is true{:else}missing key and non-existent value is false{/gte}{~n} +{@gte key=alpha}missing value is true{:else}missing value is false{/gte}{~n} +{@gte key=gamma}missing value and non-existent key is true{:else}missing value and non-existent key is false{/gte}{~n} +{@gte key="master" value="master"}"master" is greater than or equal to "master"{:else}"master" is less than "master"{/gte}{~n} +{@gte key=null}null is greater than or equal to a missing value{:else}null is less than a missing value{/gte}{~n} +{@gte key=null value=gamma}null is greater than or equal to a non-existent value{:else}null is less than a non-existent value{/gte}{~n} +{@gte}no parameters is true{:else}no parameters is false{/gte}{~n} +{@gte key="a" value="]"}"a" is greater than or equal to "]"{:else}"a" is less than "]"{/gte}{~n} +{@gte key="a" value="A"}"a" is greater than or equal to "A"{:else}"a" is less than "A"{/gte}{~n} +{@gte key="a" value="}"}"a" is greater than or equal to "}"{:else}"a" is less than "}"{/gte}{~n} +{@gte key="☃" value="☄"}"☃" is greater than or equal to "☄"{:else}"☃" is less than "☄"{/gte}{~n} +{@gte key=true_value value=false_value}true is greater than or equal to false{:else}true is less than false{/gte}{~n} +{@gte key=array_lower value=array_higher}[3,5,7] is greater than or equal to [8,9]{:else}[3,5,7] is less than [8,9]{/gte}{~n} +{@gte key=array_higher value=array_lower}[8,9] is greater than or equal to [3,5,7]{:else}[8,9] is less than [3,5,7]{/gte}{~n} +{! non-scalar and copied value tests !} +{@gte key=array_lower value=array_lower}array_lower is greater than or equal to array_lower{:else}array_lower is less than array_lower{/gte}{~n} +{@gte key=array_lower value=copy_array_lower}array_lower is greater than or equal to copy_array_lower{:else}array_lower is less than copy_array_lower{/gte}{~n} +{@gte key=some_obj value=some_obj}some_obj is greater than or equal to some_obj{:else}some_obj is less than some_obj{/gte}{~n} +{@gte key=some_obj value=copy_some_obj}some_obj is greater than or equal to copy_some_obj{:else}some_obj is less than copy_some_obj{/gte}{~n} +{@gte key=some_obj value=other_obj}some_obj is greater than or equal to other_obj{:else}some_obj is less than other_obj{/gte}{~n} +{@gte key=array_of_some_obj value=array_of_some_obj}array_of_some_obj is greater than or equal to array_of_some_obj{:else}array_of_some_obj is less than array_of_some_obj{/gte}{~n} +{@gte key=array_of_some_obj value=copy_array_of_some_obj}array_of_some_obj is greater than or equal to copy_array_of_some_obj{:else}array_of_some_obj is less than copy_array_of_some_obj{/gte}{~n} +{@gte key=array_of_some_obj value=array_of_other_obj}array_of_some_obj is greater than or equal to array_of_other_obj{:else}array_of_some_obj is less than array_of_other_obj{/gte}{~n} diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index aeee5cb..7ecfc14 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -334,6 +334,13 @@ impl<'a> DustRenderer<'a> { } } } + DustTag::DTHelperGreaterThan(parameterized_block) => { + let param_map: HashMap<&str, &RValue<'a>> = parameterized_block + .params + .iter() + .map(|pair: &KVPair<'a>| (pair.key, &pair.value)) + .collect(); + } _ => (), // TODO: Implement the rest } Ok("".to_owned()) From 48e35c54bbf700487e6dc6101a9fca5a1865379f Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 15:51:40 -0400 Subject: [PATCH 14/20] Add tests for less than and less than or equal to. --- js/test_cases/helpers_lt/input1.json | 60 +++++++++++++++++++++++++++ js/test_cases/helpers_lt/main.dust | 35 ++++++++++++++++ js/test_cases/helpers_lte/input1.json | 60 +++++++++++++++++++++++++++ js/test_cases/helpers_lte/main.dust | 35 ++++++++++++++++ 4 files changed, 190 insertions(+) create mode 100644 js/test_cases/helpers_lt/input1.json create mode 100644 js/test_cases/helpers_lt/main.dust create mode 100644 js/test_cases/helpers_lte/input1.json create mode 100644 js/test_cases/helpers_lte/main.dust diff --git a/js/test_cases/helpers_lt/input1.json b/js/test_cases/helpers_lt/input1.json new file mode 100644 index 0000000..bfbbd94 --- /dev/null +++ b/js/test_cases/helpers_lt/input1.json @@ -0,0 +1,60 @@ +{ + "str": "master", + "int": 7, + "alpha": 21, + "beta": "21", + "null": null, + "true_value": true, + "false_value": false, + "array_lower": [ + 3, + 5, + 7 + ], + "copy_array_lower": [ + 3, + 5, + 7 + ], + "array_higher": [ + 8, + 9 + ], + "some_obj": { + "name": "cat" + }, + "copy_some_obj": { + "name": "cat" + }, + "other_obj": { + "name": "dog" + }, + "array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "copy_array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "array_of_other_obj": [ + { + "name": "dog" + }, + { + "name": "dog" + } + ], + "array_of_strings": [ + "cat", + "dog" + ] +} diff --git a/js/test_cases/helpers_lt/main.dust b/js/test_cases/helpers_lt/main.dust new file mode 100644 index 0000000..305c3c4 --- /dev/null +++ b/js/test_cases/helpers_lt/main.dust @@ -0,0 +1,35 @@ +Testing helpers:{~n} +str is {str}{~n} +int is {int}{~n} +alpha is {alpha}{~n} +beta is {beta}{~n} +{@lt key=str value="master"}str is less than "master"{:else}str is greater than or equal to "master"{/lt}{~n} +{@lt key=str value="7"}str is less than "7"{:else}str is greater than or equal to "7"{/lt}{~n} +{@lt key=int value="7"}int is less than "7"{:else}int is greater than or equal to "7"{/lt}{~n} +{@lt key=int value=7}int is less than 7{:else}int is greater than or equal to 7{/lt}{~n} +{@lt key=int value=6}int is less than 6{:else}int is greater than or equal to 6{/lt}{~n} +{@lt key=alpha value=beta}alpha is less than beta{:else}alpha is greater than or equal to beta{/lt}{~n} +{@lt value=beta}missing key is true{:else}missing key is false{/lt}{~n} +{@lt value=gamma}missing key and non-existent value is true{:else}missing key and non-existent value is false{/lt}{~n} +{@lt key=alpha}missing value is true{:else}missing value is false{/lt}{~n} +{@lt key=gamma}missing value and non-existent key is true{:else}missing value and non-existent key is false{/lt}{~n} +{@lt key="master" value="master"}"master" is less than "master"{:else}"master" is greater than or equal to "master"{/lt}{~n} +{@lt key=null}null is less than a missing value{:else}null is greater than or equal to a missing value{/lt}{~n} +{@lt key=null value=gamma}null is less than a non-existent value{:else}null is greater than or equal to a non-existent value{/lt}{~n} +{@lt}no parameters is true{:else}no parameters is false{/lt}{~n} +{@lt key="a" value="]"}"a" is less than "]"{:else}"a" is greater than or equal to "]"{/lt}{~n} +{@lt key="a" value="A"}"a" is less than "A"{:else}"a" is greater than or equal to "A"{/lt}{~n} +{@lt key="a" value="}"}"a" is less than "}"{:else}"a" is greater than or equal to "}"{/lt}{~n} +{@lt key="☃" value="☄"}"☃" is less than "☄"{:else}"☃" is greater than or equal to "☄"{/lt}{~n} +{@lt key=true_value value=false_value}true is less than false{:else}true is greater than or equal to false{/lt}{~n} +{@lt key=array_lower value=array_higher}[3,5,7] is less than [8,9]{:else}[3,5,7] is greater than or equal to [8,9]{/lt}{~n} +{@lt key=array_higher value=array_lower}[8,9] is less than [3,5,7]{:else}[8,9] is greater than or equal to [3,5,7]{/lt}{~n} +{! non-scalar and copied value tests !} +{@lt key=array_lower value=array_lower}array_lower is less than array_lower{:else}array_lower is greater than or equal to array_lower{/lt}{~n} +{@lt key=array_lower value=copy_array_lower}array_lower is less than copy_array_lower{:else}array_lower is greater than or equal to copy_array_lower{/lt}{~n} +{@lt key=some_obj value=some_obj}some_obj is less than some_obj{:else}some_obj is greater than or equal to some_obj{/lt}{~n} +{@lt key=some_obj value=copy_some_obj}some_obj is less than copy_some_obj{:else}some_obj is greater than or equal to copy_some_obj{/lt}{~n} +{@lt key=some_obj value=other_obj}some_obj is less than other_obj{:else}some_obj is greater than or equal to other_obj{/lt}{~n} +{@lt key=array_of_some_obj value=array_of_some_obj}array_of_some_obj is less than array_of_some_obj{:else}array_of_some_obj is greater than or equal to array_of_some_obj{/lt}{~n} +{@lt key=array_of_some_obj value=copy_array_of_some_obj}array_of_some_obj is less than copy_array_of_some_obj{:else}array_of_some_obj is greater than or equal to copy_array_of_some_obj{/lt}{~n} +{@lt key=array_of_some_obj value=array_of_other_obj}array_of_some_obj is less than array_of_other_obj{:else}array_of_some_obj is greater than or equal to array_of_other_obj{/lt}{~n} diff --git a/js/test_cases/helpers_lte/input1.json b/js/test_cases/helpers_lte/input1.json new file mode 100644 index 0000000..bfbbd94 --- /dev/null +++ b/js/test_cases/helpers_lte/input1.json @@ -0,0 +1,60 @@ +{ + "str": "master", + "int": 7, + "alpha": 21, + "beta": "21", + "null": null, + "true_value": true, + "false_value": false, + "array_lower": [ + 3, + 5, + 7 + ], + "copy_array_lower": [ + 3, + 5, + 7 + ], + "array_higher": [ + 8, + 9 + ], + "some_obj": { + "name": "cat" + }, + "copy_some_obj": { + "name": "cat" + }, + "other_obj": { + "name": "dog" + }, + "array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "copy_array_of_some_obj": [ + { + "name": "cat" + }, + { + "name": "cat" + } + ], + "array_of_other_obj": [ + { + "name": "dog" + }, + { + "name": "dog" + } + ], + "array_of_strings": [ + "cat", + "dog" + ] +} diff --git a/js/test_cases/helpers_lte/main.dust b/js/test_cases/helpers_lte/main.dust new file mode 100644 index 0000000..dcf0ab5 --- /dev/null +++ b/js/test_cases/helpers_lte/main.dust @@ -0,0 +1,35 @@ +Testing helpers:{~n} +str is {str}{~n} +int is {int}{~n} +alpha is {alpha}{~n} +beta is {beta}{~n} +{@lte key=str value="master"}str is less than or equal to "master"{:else}str is greater than "master"{/lte}{~n} +{@lte key=str value="7"}str is less than or equal to "7"{:else}str is greater than "7"{/lte}{~n} +{@lte key=int value="7"}int is less than or equal to "7"{:else}int is greater than "7"{/lte}{~n} +{@lte key=int value=7}int is less than or equal to 7{:else}int is greater than 7{/lte}{~n} +{@lte key=int value=6}int is less than or equal to 6{:else}int is greater than 6{/lte}{~n} +{@lte key=alpha value=beta}alpha is less than or equal to beta{:else}alpha is greater than beta{/lte}{~n} +{@lte value=beta}missing key is true{:else}missing key is false{/lte}{~n} +{@lte value=gamma}missing key and non-existent value is true{:else}missing key and non-existent value is false{/lte}{~n} +{@lte key=alpha}missing value is true{:else}missing value is false{/lte}{~n} +{@lte key=gamma}missing value and non-existent key is true{:else}missing value and non-existent key is false{/lte}{~n} +{@lte key="master" value="master"}"master" is less than or equal to "master"{:else}"master" is greater than "master"{/lte}{~n} +{@lte key=null}null is less than or equal to a missing value{:else}null is greater than a missing value{/lte}{~n} +{@lte key=null value=gamma}null is less than or equal to a non-existent value{:else}null is greater than a non-existent value{/lte}{~n} +{@lte}no parameters is true{:else}no parameters is false{/lte}{~n} +{@lte key="a" value="]"}"a" is less than or equal to "]"{:else}"a" is greater than "]"{/lte}{~n} +{@lte key="a" value="A"}"a" is less than or equal to "A"{:else}"a" is greater than "A"{/lte}{~n} +{@lte key="a" value="}"}"a" is less than or equal to "}"{:else}"a" is greater than "}"{/lte}{~n} +{@lte key="☃" value="☄"}"☃" is less than or equal to "☄"{:else}"☃" is greater than "☄"{/lte}{~n} +{@lte key=true_value value=false_value}true is less than or equal to false{:else}true is greater than false{/lte}{~n} +{@lte key=array_lower value=array_higher}[3,5,7] is less than or equal to [8,9]{:else}[3,5,7] is greater than [8,9]{/lte}{~n} +{@lte key=array_higher value=array_lower}[8,9] is less than or equal to [3,5,7]{:else}[8,9] is greater than [3,5,7]{/lte}{~n} +{! non-scalar and copied value tests !} +{@lte key=array_lower value=array_lower}array_lower is less than or equal to array_lower{:else}array_lower is greater than array_lower{/lte}{~n} +{@lte key=array_lower value=copy_array_lower}array_lower is less than or equal to copy_array_lower{:else}array_lower is greater than copy_array_lower{/lte}{~n} +{@lte key=some_obj value=some_obj}some_obj is less than or equal to some_obj{:else}some_obj is greater than some_obj{/lte}{~n} +{@lte key=some_obj value=copy_some_obj}some_obj is less than or equal to copy_some_obj{:else}some_obj is greater than copy_some_obj{/lte}{~n} +{@lte key=some_obj value=other_obj}some_obj is less than or equal to other_obj{:else}some_obj is greater than other_obj{/lte}{~n} +{@lte key=array_of_some_obj value=array_of_some_obj}array_of_some_obj is less than or equal to array_of_some_obj{:else}array_of_some_obj is greater than array_of_some_obj{/lte}{~n} +{@lte key=array_of_some_obj value=copy_array_of_some_obj}array_of_some_obj is less than or equal to copy_array_of_some_obj{:else}array_of_some_obj is greater than copy_array_of_some_obj{/lte}{~n} +{@lte key=array_of_some_obj value=array_of_other_obj}array_of_some_obj is less than or equal to array_of_other_obj{:else}array_of_some_obj is greater than array_of_other_obj{/lte}{~n} From 6758d515f15cbf622f6457417504118db025646f Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 16:24:36 -0400 Subject: [PATCH 15/20] Have greater than helper very close to correct. Just need to make it compare arrays of scalars. --- js/test_cases/helpers_gt/README.md | 15 ++++++++++ js/test_cases/helpers_gt/main.dust | 3 ++ src/renderer/renderer.rs | 47 ++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/js/test_cases/helpers_gt/README.md b/js/test_cases/helpers_gt/README.md index 58a764a..f418aed 100644 --- a/js/test_cases/helpers_gt/README.md +++ b/js/test_cases/helpers_gt/README.md @@ -17,3 +17,18 @@ greater than or equals to All comparisons between non-matching types (for example, int vs string) appear to render the main block. Comparisons between non-scalar types (like arrays) appears to render the main block + +less than +--------- + +All comparisons between non-matching types (for example, int vs string) appear to render the else block. + +Comparisons between non-scalar types (like arrays) appears to render the else block + + +less than or equal to +--------------------- + +All comparisons between non-matching types (for example, int vs string) appear to render the main block. + +Comparisons between non-scalar types (like arrays) appears to render the main block diff --git a/js/test_cases/helpers_gt/main.dust b/js/test_cases/helpers_gt/main.dust index 9a4ffa8..c7b3699 100644 --- a/js/test_cases/helpers_gt/main.dust +++ b/js/test_cases/helpers_gt/main.dust @@ -20,7 +20,10 @@ beta is {beta}{~n} {@gt key="a" value="]"}"a" is greater than "]"{:else}"a" is less than or equal to "]"{/gt}{~n} {@gt key="a" value="A"}"a" is greater than "A"{:else}"a" is less than or equal to "A"{/gt}{~n} {@gt key="a" value="}"}"a" is greater than "}"{:else}"a" is less than or equal to "}"{/gt}{~n} +{! +Commented out because unicode not working in rust implementation yet {@gt key="☃" value="☄"}"☃" is greater than "☄"{:else}"☃" is less than or equal to "☄"{/gt}{~n} +!} {@gt key=true_value value=false_value}true is greater than false{:else}true is less than or equal to false{/gt}{~n} {@gt key=array_lower value=array_higher}[3,5,7] is greater than [8,9]{:else}[3,5,7] is less than or equal to [8,9]{/gt}{~n} {@gt key=array_higher value=array_lower}[8,9] is greater than [3,5,7]{:else}[8,9] is less than or equal to [3,5,7]{/gt}{~n} diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index 7ecfc14..cd83681 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -340,6 +340,53 @@ impl<'a> DustRenderer<'a> { .iter() .map(|pair: &KVPair<'a>| (pair.key, &pair.value)) .collect(); + let left_side: Result<&dyn ContextElement, WalkError> = match param_map.get("key") { + None => return Ok("".to_owned()), + Some(rval) => match rval { + RValue::RVString(text) => Ok(text), + RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys), + RValue::RVPositiveInteger(num) => Ok(num), + }, + }; + let right_side: Result<&dyn ContextElement, WalkError> = + match param_map.get("value") { + None => Err(WalkError::CantWalk), + Some(rval) => match rval { + RValue::RVString(text) => Ok(text), + RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys), + RValue::RVPositiveInteger(num) => Ok(num), + }, + }; + match (left_side, right_side) { + (Err(_), _) | (_, Err(_)) => match ¶meterized_block.else_contents { + None => return Ok("".to_owned()), + Some(body) => { + let rendered_content = self.render_body(body, breadcrumbs, blocks)?; + return Ok(rendered_content); + } + }, + (Ok(left_side_unwrapped), Ok(right_side_unwrapped)) => { + if left_side_unwrapped > right_side_unwrapped { + match ¶meterized_block.contents { + None => return Ok("".to_owned()), + Some(body) => { + let rendered_content = + self.render_body(body, breadcrumbs, blocks)?; + return Ok(rendered_content); + } + } + } else { + match ¶meterized_block.else_contents { + None => return Ok("".to_owned()), + Some(body) => { + let rendered_content = + self.render_body(body, breadcrumbs, blocks)?; + return Ok(rendered_content); + } + } + } + } + } } _ => (), // TODO: Implement the rest } From 0f90fa2c7e1f1b30d9b2fab9239bda2336d4e5df Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 16:46:39 -0400 Subject: [PATCH 16/20] Add support for ignoring tests by prefixing their name with an underscore. --- js/run_compliance_suite.bash | 7 ++++++- js/test_cases/{helpers_gte => _helpers_gte}/input1.json | 0 js/test_cases/{helpers_gte => _helpers_gte}/main.dust | 0 js/test_cases/{helpers_lt => _helpers_lt}/input1.json | 0 js/test_cases/{helpers_lt => _helpers_lt}/main.dust | 0 js/test_cases/{helpers_lte => _helpers_lte}/input1.json | 0 js/test_cases/{helpers_lte => _helpers_lte}/main.dust | 0 7 files changed, 6 insertions(+), 1 deletion(-) rename js/test_cases/{helpers_gte => _helpers_gte}/input1.json (100%) rename js/test_cases/{helpers_gte => _helpers_gte}/main.dust (100%) rename js/test_cases/{helpers_lt => _helpers_lt}/input1.json (100%) rename js/test_cases/{helpers_lt => _helpers_lt}/main.dust (100%) rename js/test_cases/{helpers_lte => _helpers_lte}/input1.json (100%) rename js/test_cases/{helpers_lte => _helpers_lte}/main.dust (100%) diff --git a/js/run_compliance_suite.bash b/js/run_compliance_suite.bash index a13d025..c7d5296 100755 --- a/js/run_compliance_suite.bash +++ b/js/run_compliance_suite.bash @@ -48,7 +48,12 @@ while read -r test_group; do fi set -e done <<<"$(find "$test_group" -maxdepth 1 -mindepth 1 -type f -name '*.json' | sort)" -done <<<"$(find "$DIR/test_cases" -maxdepth 1 -mindepth 1 -type d | sort)" +done <<<"$(find "$DIR/test_cases" -maxdepth 1 -mindepth 1 -type d ! -name '_*' | sort)" + +ignored_count=$(find "$DIR/test_cases" -maxdepth 1 -mindepth 1 -type d -name '_*' | wc -l) + +echo "" +echo "$ignored_count ignored tests" if [ $failed_count -ne 0 ]; then echo "$failed_count failed tests" diff --git a/js/test_cases/helpers_gte/input1.json b/js/test_cases/_helpers_gte/input1.json similarity index 100% rename from js/test_cases/helpers_gte/input1.json rename to js/test_cases/_helpers_gte/input1.json diff --git a/js/test_cases/helpers_gte/main.dust b/js/test_cases/_helpers_gte/main.dust similarity index 100% rename from js/test_cases/helpers_gte/main.dust rename to js/test_cases/_helpers_gte/main.dust diff --git a/js/test_cases/helpers_lt/input1.json b/js/test_cases/_helpers_lt/input1.json similarity index 100% rename from js/test_cases/helpers_lt/input1.json rename to js/test_cases/_helpers_lt/input1.json diff --git a/js/test_cases/helpers_lt/main.dust b/js/test_cases/_helpers_lt/main.dust similarity index 100% rename from js/test_cases/helpers_lt/main.dust rename to js/test_cases/_helpers_lt/main.dust diff --git a/js/test_cases/helpers_lte/input1.json b/js/test_cases/_helpers_lte/input1.json similarity index 100% rename from js/test_cases/helpers_lte/input1.json rename to js/test_cases/_helpers_lte/input1.json diff --git a/js/test_cases/helpers_lte/main.dust b/js/test_cases/_helpers_lte/main.dust similarity index 100% rename from js/test_cases/helpers_lte/main.dust rename to js/test_cases/_helpers_lte/main.dust From b53a9e1837b6af676513a305b9b74adef0ec4184 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 17:17:43 -0400 Subject: [PATCH 17/20] Cleaning up and factoring out reused code in the renderer. --- src/renderer/renderer.rs | 258 ++++++++++++++++----------------------- 1 file changed, 107 insertions(+), 151 deletions(-) diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index cd83681..dc190dc 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -77,6 +77,18 @@ impl<'a> DustRenderer<'a> { self.render_body(&main_template.contents, breadcrumbs, &new_blocks) } + fn render_maybe_body( + &'a self, + body: &'a Option, + breadcrumbs: &Vec<&'a dyn ContextElement>, + blocks: &'a InlinePartialTreeElement<'a>, + ) -> Result { + match body { + None => Ok("".to_owned()), + Some(body) => Ok(self.render_body(body, breadcrumbs, blocks)?), + } + } + fn render_body( &'a self, body: &'a Body, @@ -130,16 +142,13 @@ impl<'a> DustRenderer<'a> { } DustTag::DTSection(container) => { let val = walk_path(breadcrumbs, &container.path.keys); - let loop_elements: Vec<&dyn ContextElement> = self.get_loop_elements(val); + let loop_elements: Vec<&dyn ContextElement> = Self::get_loop_elements(val); if loop_elements.is_empty() { // Oddly enough if the value is falsey (like // an empty array or null), Dust uses the // original context before walking the path as // the context for rendering the else block - return match &container.else_contents { - Some(body) => self.render_body(&body, breadcrumbs, blocks), - None => Ok("".to_owned()), - }; + return self.render_maybe_body(&container.else_contents, breadcrumbs, blocks); } else { match &container.contents { None => return Ok("".to_owned()), @@ -160,33 +169,21 @@ impl<'a> DustRenderer<'a> { } DustTag::DTExists(container) => { let val = walk_path(breadcrumbs, &container.path.keys); - let loop_elements: Vec<&dyn ContextElement> = self.get_loop_elements(val); - if loop_elements.is_empty() { - return match &container.else_contents { - Some(body) => self.render_body(&body, breadcrumbs, blocks), - None => Ok("".to_owned()), - }; + let loop_elements: Vec<&dyn ContextElement> = Self::get_loop_elements(val); + return if loop_elements.is_empty() { + self.render_maybe_body(&container.else_contents, breadcrumbs, blocks) } else { - return match &container.contents { - None => Ok("".to_owned()), - Some(body) => self.render_body(&body, breadcrumbs, blocks), - }; - } + self.render_maybe_body(&container.contents, breadcrumbs, blocks) + }; } DustTag::DTNotExists(container) => { let val = walk_path(breadcrumbs, &container.path.keys); - let loop_elements: Vec<&dyn ContextElement> = self.get_loop_elements(val); - if !loop_elements.is_empty() { - return match &container.else_contents { - Some(body) => self.render_body(&body, breadcrumbs, blocks), - None => Ok("".to_owned()), - }; + let loop_elements: Vec<&dyn ContextElement> = Self::get_loop_elements(val); + return if !loop_elements.is_empty() { + self.render_maybe_body(&container.else_contents, breadcrumbs, blocks) } else { - return match &container.contents { - None => Ok("".to_owned()), - Some(body) => self.render_body(&body, breadcrumbs, blocks), - }; - } + self.render_maybe_body(&container.contents, breadcrumbs, blocks) + }; } DustTag::DTPartial(partial) => { if partial.params.is_empty() { @@ -202,34 +199,19 @@ impl<'a> DustRenderer<'a> { return Ok(rendered_content); } } - DustTag::DTInlinePartial(named_block) => { + DustTag::DTInlinePartial(_named_block) => { // Inline partials are blank during rendering (they get injected into blocks) return Ok("".to_owned()); } DustTag::DTBlock(named_block) => { - match blocks.get_block(named_block.name) { - None => match &named_block.contents { - None => return Ok("".to_owned()), - Some(body) => { - let rendered_content = self.render_body(body, breadcrumbs, blocks)?; - return Ok(rendered_content); - } - }, - Some(interior) => match interior { - None => return Ok("".to_owned()), - Some(body) => { - let rendered_content = self.render_body(body, breadcrumbs, blocks)?; - return Ok(rendered_content); - } - }, + return match blocks.get_block(named_block.name) { + None => self.render_maybe_body(&named_block.contents, breadcrumbs, blocks), + Some(interior) => self.render_maybe_body(interior, breadcrumbs, blocks), }; } DustTag::DTHelperEquals(parameterized_block) => { - let param_map: HashMap<&str, &RValue<'a>> = parameterized_block - .params - .iter() - .map(|pair: &KVPair<'a>| (pair.key, &pair.value)) - .collect(); + let param_map: HashMap<&str, &RValue<'a>> = + Self::get_rval_map(¶meterized_block.params); // Special case: when comparing two RVPaths, if the // path is equal then dust assumes the values are // equal (otherwise, non-scalar values are @@ -244,47 +226,31 @@ impl<'a> DustRenderer<'a> { }; } - let left_side: Result<&dyn ContextElement, WalkError> = match param_map.get("key") { - None => return Ok("".to_owned()), - Some(rval) => match rval { - RValue::RVString(text) => Ok(text), - RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys), - RValue::RVPositiveInteger(num) => Ok(num), - }, - }; - let right_side: Result<&dyn ContextElement, WalkError> = - match param_map.get("value") { - None => Err(WalkError::CantWalk), - Some(rval) => match rval { - RValue::RVString(text) => Ok(text), - RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys), - RValue::RVPositiveInteger(num) => Ok(num), - }, + let left_side: Result<&dyn ContextElement, WalkError> = + match Self::get_rval(breadcrumbs, ¶m_map, "key") { + None => return Ok("".to_owned()), + Some(res) => res, }; + let right_side: Result<&dyn ContextElement, WalkError> = + Self::get_rval(breadcrumbs, ¶m_map, "value") + .unwrap_or(Err(WalkError::CantWalk)); if left_side == right_side { - match ¶meterized_block.contents { - None => return Ok("".to_owned()), - Some(body) => { - let rendered_content = self.render_body(body, breadcrumbs, blocks)?; - return Ok(rendered_content); - } - } + return self.render_maybe_body( + ¶meterized_block.contents, + breadcrumbs, + blocks, + ); } else { - match ¶meterized_block.else_contents { - None => return Ok("".to_owned()), - Some(body) => { - let rendered_content = self.render_body(body, breadcrumbs, blocks)?; - return Ok(rendered_content); - } - } + return self.render_maybe_body( + ¶meterized_block.else_contents, + breadcrumbs, + blocks, + ); } } DustTag::DTHelperNotEquals(parameterized_block) => { - let param_map: HashMap<&str, &RValue<'a>> = parameterized_block - .params - .iter() - .map(|pair: &KVPair<'a>| (pair.key, &pair.value)) - .collect(); + let param_map: HashMap<&str, &RValue<'a>> = + Self::get_rval_map(¶meterized_block.params); // Special case: when comparing two RVPaths, if the // path is equal then dust assumes the values are // equal (otherwise, non-scalar values are @@ -299,64 +265,39 @@ impl<'a> DustRenderer<'a> { }; } - let left_side: Result<&dyn ContextElement, WalkError> = match param_map.get("key") { - None => return Ok("".to_owned()), - Some(rval) => match rval { - RValue::RVString(text) => Ok(text), - RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys), - RValue::RVPositiveInteger(num) => Ok(num), - }, - }; - let right_side: Result<&dyn ContextElement, WalkError> = - match param_map.get("value") { - None => Err(WalkError::CantWalk), - Some(rval) => match rval { - RValue::RVString(text) => Ok(text), - RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys), - RValue::RVPositiveInteger(num) => Ok(num), - }, + let left_side: Result<&dyn ContextElement, WalkError> = + match Self::get_rval(breadcrumbs, ¶m_map, "key") { + None => return Ok("".to_owned()), + Some(res) => res, }; + let right_side: Result<&dyn ContextElement, WalkError> = + Self::get_rval(breadcrumbs, ¶m_map, "value") + .unwrap_or(Err(WalkError::CantWalk)); if left_side != right_side { - match ¶meterized_block.contents { - None => return Ok("".to_owned()), - Some(body) => { - let rendered_content = self.render_body(body, breadcrumbs, blocks)?; - return Ok(rendered_content); - } - } + return self.render_maybe_body( + ¶meterized_block.contents, + breadcrumbs, + blocks, + ); } else { - match ¶meterized_block.else_contents { - None => return Ok("".to_owned()), - Some(body) => { - let rendered_content = self.render_body(body, breadcrumbs, blocks)?; - return Ok(rendered_content); - } - } + return self.render_maybe_body( + ¶meterized_block.else_contents, + breadcrumbs, + blocks, + ); } } DustTag::DTHelperGreaterThan(parameterized_block) => { - let param_map: HashMap<&str, &RValue<'a>> = parameterized_block - .params - .iter() - .map(|pair: &KVPair<'a>| (pair.key, &pair.value)) - .collect(); - let left_side: Result<&dyn ContextElement, WalkError> = match param_map.get("key") { - None => return Ok("".to_owned()), - Some(rval) => match rval { - RValue::RVString(text) => Ok(text), - RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys), - RValue::RVPositiveInteger(num) => Ok(num), - }, - }; - let right_side: Result<&dyn ContextElement, WalkError> = - match param_map.get("value") { - None => Err(WalkError::CantWalk), - Some(rval) => match rval { - RValue::RVString(text) => Ok(text), - RValue::RVPath(path) => walk_path(breadcrumbs, &path.keys), - RValue::RVPositiveInteger(num) => Ok(num), - }, + let param_map: HashMap<&str, &RValue<'a>> = + Self::get_rval_map(¶meterized_block.params); + let left_side: Result<&dyn ContextElement, WalkError> = + match Self::get_rval(breadcrumbs, ¶m_map, "key") { + None => return Ok("".to_owned()), + Some(res) => res, }; + let right_side: Result<&dyn ContextElement, WalkError> = + Self::get_rval(breadcrumbs, ¶m_map, "value") + .unwrap_or(Err(WalkError::CantWalk)); match (left_side, right_side) { (Err(_), _) | (_, Err(_)) => match ¶meterized_block.else_contents { None => return Ok("".to_owned()), @@ -367,23 +308,17 @@ impl<'a> DustRenderer<'a> { }, (Ok(left_side_unwrapped), Ok(right_side_unwrapped)) => { if left_side_unwrapped > right_side_unwrapped { - match ¶meterized_block.contents { - None => return Ok("".to_owned()), - Some(body) => { - let rendered_content = - self.render_body(body, breadcrumbs, blocks)?; - return Ok(rendered_content); - } - } + return self.render_maybe_body( + ¶meterized_block.contents, + breadcrumbs, + blocks, + ); } else { - match ¶meterized_block.else_contents { - None => return Ok("".to_owned()), - Some(body) => { - let rendered_content = - self.render_body(body, breadcrumbs, blocks)?; - return Ok(rendered_content); - } - } + return self.render_maybe_body( + ¶meterized_block.else_contents, + breadcrumbs, + blocks, + ); } } } @@ -398,7 +333,6 @@ impl<'a> DustRenderer<'a> { /// If the value is falsey, and therefore should render the else /// block, this will return an empty vector. fn get_loop_elements<'b>( - &'a self, walk_result: Result<&'b dyn ContextElement, WalkError>, ) -> Vec<&'b dyn ContextElement> { match walk_result { @@ -419,6 +353,28 @@ impl<'a> DustRenderer<'a> { }, } } + + fn get_rval_map<'b>(params: &'b Vec>) -> HashMap<&'b str, &'b RValue<'b>> { + params + .iter() + .map(|pair: &KVPair<'b>| (pair.key, &pair.value)) + .collect() + } + + fn get_rval<'b>( + breadcrumbs: &Vec<&'b dyn ContextElement>, + param_map: &HashMap<&str, &'b RValue<'b>>, + key: &str, + ) -> Option> { + match param_map.get(key) { + None => None, + Some(rval) => match rval { + RValue::RVString(text) => Some(Ok(text)), + RValue::RVPath(path) => Some(walk_path(breadcrumbs, &path.keys)), + RValue::RVPositiveInteger(num) => Some(Ok(num)), + }, + } + } } #[cfg(test)] From 7126e83d9ac492c24557a5902ca491dff6697e4c Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 17:53:57 -0400 Subject: [PATCH 18/20] Added tests for non-congruous arrays. --- js/test_cases/_helpers_gte/input1.json | 12 ++++++++++++ js/test_cases/_helpers_gte/main.dust | 3 +++ js/test_cases/_helpers_lt/input1.json | 12 ++++++++++++ js/test_cases/_helpers_lt/main.dust | 3 +++ js/test_cases/_helpers_lte/input1.json | 12 ++++++++++++ js/test_cases/_helpers_lte/main.dust | 3 +++ js/test_cases/helpers_gt/README.md | 3 +++ js/test_cases/helpers_gt/input1.json | 12 ++++++++++++ js/test_cases/helpers_gt/main.dust | 10 +++++++--- 9 files changed, 67 insertions(+), 3 deletions(-) diff --git a/js/test_cases/_helpers_gte/input1.json b/js/test_cases/_helpers_gte/input1.json index bfbbd94..de2ac09 100644 --- a/js/test_cases/_helpers_gte/input1.json +++ b/js/test_cases/_helpers_gte/input1.json @@ -11,6 +11,13 @@ 5, 7 ], + "array_lower_with_array": [ + 3, + 5, + [ + 7 + ] + ], "copy_array_lower": [ 3, 5, @@ -20,6 +27,11 @@ 8, 9 ], + "array_higher_longer": [ + 8, + 9, + 1 + ], "some_obj": { "name": "cat" }, diff --git a/js/test_cases/_helpers_gte/main.dust b/js/test_cases/_helpers_gte/main.dust index a3eb601..ed6938c 100644 --- a/js/test_cases/_helpers_gte/main.dust +++ b/js/test_cases/_helpers_gte/main.dust @@ -33,3 +33,6 @@ beta is {beta}{~n} {@gte key=array_of_some_obj value=array_of_some_obj}array_of_some_obj is greater than or equal to array_of_some_obj{:else}array_of_some_obj is less than array_of_some_obj{/gte}{~n} {@gte key=array_of_some_obj value=copy_array_of_some_obj}array_of_some_obj is greater than or equal to copy_array_of_some_obj{:else}array_of_some_obj is less than copy_array_of_some_obj{/gte}{~n} {@gte key=array_of_some_obj value=array_of_other_obj}array_of_some_obj is greater than or equal to array_of_other_obj{:else}array_of_some_obj is less than array_of_other_obj{/gte}{~n} +{@gte key=array_higher value=array_higher_longer}array_higher is greater than or equal to array_higher_longer{:else}array_higher is less than array_higher_longer{/gte}{~n} +{@gte key=array_lower value=array_lower_with_array}array_lower is greater than or equal to array_lower_with_array{:else}array_lower is less than array_lower_with_array{/gte}{~n} +{@gte key=array_lower_with_array value=array_lower}array_lower_with_array is greater than or equal to array_lower{:else}array_lower_with_array is less than array_lower{/gte}{~n} diff --git a/js/test_cases/_helpers_lt/input1.json b/js/test_cases/_helpers_lt/input1.json index bfbbd94..de2ac09 100644 --- a/js/test_cases/_helpers_lt/input1.json +++ b/js/test_cases/_helpers_lt/input1.json @@ -11,6 +11,13 @@ 5, 7 ], + "array_lower_with_array": [ + 3, + 5, + [ + 7 + ] + ], "copy_array_lower": [ 3, 5, @@ -20,6 +27,11 @@ 8, 9 ], + "array_higher_longer": [ + 8, + 9, + 1 + ], "some_obj": { "name": "cat" }, diff --git a/js/test_cases/_helpers_lt/main.dust b/js/test_cases/_helpers_lt/main.dust index 305c3c4..c1ab4e4 100644 --- a/js/test_cases/_helpers_lt/main.dust +++ b/js/test_cases/_helpers_lt/main.dust @@ -33,3 +33,6 @@ beta is {beta}{~n} {@lt key=array_of_some_obj value=array_of_some_obj}array_of_some_obj is less than array_of_some_obj{:else}array_of_some_obj is greater than or equal to array_of_some_obj{/lt}{~n} {@lt key=array_of_some_obj value=copy_array_of_some_obj}array_of_some_obj is less than copy_array_of_some_obj{:else}array_of_some_obj is greater than or equal to copy_array_of_some_obj{/lt}{~n} {@lt key=array_of_some_obj value=array_of_other_obj}array_of_some_obj is less than array_of_other_obj{:else}array_of_some_obj is greater than or equal to array_of_other_obj{/lt}{~n} +{@lt key=array_higher value=array_higher_longer}array_higher is less than array_higher_longer{:else}array_higher is greater than or equal to array_higher_longer{/lt}{~n} +{@lt key=array_lower value=array_lower_with_array}array_lower is less than array_lower_with_array{:else}array_lower is greater than or equal to array_lower_with_array{/lt}{~n} +{@lt key=array_lower_with_array value=array_lower}array_lower_with_array is less than array_lower{:else}array_lower_with_array is greater than or equal to array_lower{/lt}{~n} diff --git a/js/test_cases/_helpers_lte/input1.json b/js/test_cases/_helpers_lte/input1.json index bfbbd94..de2ac09 100644 --- a/js/test_cases/_helpers_lte/input1.json +++ b/js/test_cases/_helpers_lte/input1.json @@ -11,6 +11,13 @@ 5, 7 ], + "array_lower_with_array": [ + 3, + 5, + [ + 7 + ] + ], "copy_array_lower": [ 3, 5, @@ -20,6 +27,11 @@ 8, 9 ], + "array_higher_longer": [ + 8, + 9, + 1 + ], "some_obj": { "name": "cat" }, diff --git a/js/test_cases/_helpers_lte/main.dust b/js/test_cases/_helpers_lte/main.dust index dcf0ab5..2ea2f24 100644 --- a/js/test_cases/_helpers_lte/main.dust +++ b/js/test_cases/_helpers_lte/main.dust @@ -33,3 +33,6 @@ beta is {beta}{~n} {@lte key=array_of_some_obj value=array_of_some_obj}array_of_some_obj is less than or equal to array_of_some_obj{:else}array_of_some_obj is greater than array_of_some_obj{/lte}{~n} {@lte key=array_of_some_obj value=copy_array_of_some_obj}array_of_some_obj is less than or equal to copy_array_of_some_obj{:else}array_of_some_obj is greater than copy_array_of_some_obj{/lte}{~n} {@lte key=array_of_some_obj value=array_of_other_obj}array_of_some_obj is less than or equal to array_of_other_obj{:else}array_of_some_obj is greater than array_of_other_obj{/lte}{~n} +{@lte key=array_higher value=array_higher_longer}array_higher is less than or equal to array_higher_longer{:else}array_higher is greater than array_higher_longer{/lte}{~n} +{@lte key=array_lower value=array_lower_with_array}array_lower is less than or equal to array_lower_with_array{:else}array_lower is greater than array_lower_with_array{/lte}{~n} +{@lte key=array_lower_with_array value=array_lower}array_lower_with_array is less than or equal to array_lower{:else}array_lower_with_array is greater than array_lower{/lte}{~n} diff --git a/js/test_cases/helpers_gt/README.md b/js/test_cases/helpers_gt/README.md index f418aed..527bae3 100644 --- a/js/test_cases/helpers_gt/README.md +++ b/js/test_cases/helpers_gt/README.md @@ -2,6 +2,9 @@ Based on my tests, it appears dust is sorting based on ascii-table values. This Greater than follows the same pattern for not rendering when key is omitted or null. +Longer arrays are greater than shorter arrays if all preceding values match. + +Theory for comparing arrays: Compare the values, if theres any mismatched types then take the same action you would for non-matching scalar types. greater than ------------ diff --git a/js/test_cases/helpers_gt/input1.json b/js/test_cases/helpers_gt/input1.json index bfbbd94..de2ac09 100644 --- a/js/test_cases/helpers_gt/input1.json +++ b/js/test_cases/helpers_gt/input1.json @@ -11,6 +11,13 @@ 5, 7 ], + "array_lower_with_array": [ + 3, + 5, + [ + 7 + ] + ], "copy_array_lower": [ 3, 5, @@ -20,6 +27,11 @@ 8, 9 ], + "array_higher_longer": [ + 8, + 9, + 1 + ], "some_obj": { "name": "cat" }, diff --git a/js/test_cases/helpers_gt/main.dust b/js/test_cases/helpers_gt/main.dust index c7b3699..758b231 100644 --- a/js/test_cases/helpers_gt/main.dust +++ b/js/test_cases/helpers_gt/main.dust @@ -21,9 +21,9 @@ beta is {beta}{~n} {@gt key="a" value="A"}"a" is greater than "A"{:else}"a" is less than or equal to "A"{/gt}{~n} {@gt key="a" value="}"}"a" is greater than "}"{:else}"a" is less than or equal to "}"{/gt}{~n} {! -Commented out because unicode not working in rust implementation yet -{@gt key="☃" value="☄"}"☃" is greater than "☄"{:else}"☃" is less than or equal to "☄"{/gt}{~n} -!} + Commented out because unicode not working in rust implementation yet + {@gt key="☃" value="☄"}"☃" is greater than "☄"{:else}"☃" is less than or equal to "☄"{/gt}{~n} + !} {@gt key=true_value value=false_value}true is greater than false{:else}true is less than or equal to false{/gt}{~n} {@gt key=array_lower value=array_higher}[3,5,7] is greater than [8,9]{:else}[3,5,7] is less than or equal to [8,9]{/gt}{~n} {@gt key=array_higher value=array_lower}[8,9] is greater than [3,5,7]{:else}[8,9] is less than or equal to [3,5,7]{/gt}{~n} @@ -36,3 +36,7 @@ Commented out because unicode not working in rust implementation yet {@gt key=array_of_some_obj value=array_of_some_obj}array_of_some_obj is greater than array_of_some_obj{:else}array_of_some_obj is less than or equal to array_of_some_obj{/gt}{~n} {@gt key=array_of_some_obj value=copy_array_of_some_obj}array_of_some_obj is greater than copy_array_of_some_obj{:else}array_of_some_obj is less than or equal to copy_array_of_some_obj{/gt}{~n} {@gt key=array_of_some_obj value=array_of_other_obj}array_of_some_obj is greater than array_of_other_obj{:else}array_of_some_obj is less than or equal to array_of_other_obj{/gt}{~n} + +{@gt key=array_higher value=array_higher_longer}array_higher is greater than array_higher_longer{:else}array_higher is less than or equal to array_higher_longer{/gt}{~n} +{@gt key=array_lower value=array_lower_with_array}array_lower is greater than array_lower_with_array{:else}array_lower is less than or equal to array_lower_with_array{/gt}{~n} +{@gt key=array_lower_with_array value=array_lower}array_lower_with_array is greater than array_lower{:else}array_lower_with_array is less than or equal to array_lower{/gt}{~n} From f640cb044097b5eb5c62678c123796dd9ebfb86d Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 18:15:03 -0400 Subject: [PATCH 19/20] Fixed greater than helper by using rust's PartialOrd implementation for Vec. --- src/bin.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/bin.rs b/src/bin.rs index 1f698a9..4274501 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -220,7 +220,7 @@ impl CompareContextElement for serde_json::Value { serde_json::Value::String(self_string), serde_json::Value::String(other_string), ) => self_string.partial_cmp(other_string), - // TODO: Non-scalar types + (serde_json::Value::Array(self_array), serde_json::Value::Array(other_array)) => convert_vec_to_context_element(self_array).partial_cmp(&convert_vec_to_context_element(other_array)), _ => None, }; } @@ -242,3 +242,17 @@ impl CompareContextElement for serde_json::Value { None } } + +/// Create a new vec by of references to the serde_json::Values as +/// ContextElement trait objects so we can use its implementation of +/// PartialOrd. +/// +/// You cannot implement a trait you do not define for a type you do +/// not define, so I cannot implement PartialOrd for +/// serde_json::value. Instead, I just re-use the PartialOrd +/// implementation for ContextElement which unfortunately has extra +/// overhead of downcasting. This would be a good spot for +/// optimization. +fn convert_vec_to_context_element(array: &Vec) -> Vec<&dyn ContextElement> { + array.iter().map(|v| v as _).collect() +} From 0cfe67311ea7fbe17501f71954677a8010655c73 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sat, 16 May 2020 18:21:10 -0400 Subject: [PATCH 20/20] Comment out the unicode literals test because unicode breaks nom. Will have to write my own parsers to handle unicode. --- js/test_cases/_helpers_gte/main.dust | 3 +++ js/test_cases/_helpers_lt/main.dust | 3 +++ js/test_cases/_helpers_lte/main.dust | 3 +++ js/test_cases/helpers_gt/main.dust | 6 +++--- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/js/test_cases/_helpers_gte/main.dust b/js/test_cases/_helpers_gte/main.dust index ed6938c..b0ee031 100644 --- a/js/test_cases/_helpers_gte/main.dust +++ b/js/test_cases/_helpers_gte/main.dust @@ -20,7 +20,10 @@ beta is {beta}{~n} {@gte key="a" value="]"}"a" is greater than or equal to "]"{:else}"a" is less than "]"{/gte}{~n} {@gte key="a" value="A"}"a" is greater than or equal to "A"{:else}"a" is less than "A"{/gte}{~n} {@gte key="a" value="}"}"a" is greater than or equal to "}"{:else}"a" is less than "}"{/gte}{~n} +{! +Commented out because unicode breaks nom {@gte key="☃" value="☄"}"☃" is greater than or equal to "☄"{:else}"☃" is less than "☄"{/gte}{~n} +!} {@gte key=true_value value=false_value}true is greater than or equal to false{:else}true is less than false{/gte}{~n} {@gte key=array_lower value=array_higher}[3,5,7] is greater than or equal to [8,9]{:else}[3,5,7] is less than [8,9]{/gte}{~n} {@gte key=array_higher value=array_lower}[8,9] is greater than or equal to [3,5,7]{:else}[8,9] is less than [3,5,7]{/gte}{~n} diff --git a/js/test_cases/_helpers_lt/main.dust b/js/test_cases/_helpers_lt/main.dust index c1ab4e4..f2b81d1 100644 --- a/js/test_cases/_helpers_lt/main.dust +++ b/js/test_cases/_helpers_lt/main.dust @@ -20,7 +20,10 @@ beta is {beta}{~n} {@lt key="a" value="]"}"a" is less than "]"{:else}"a" is greater than or equal to "]"{/lt}{~n} {@lt key="a" value="A"}"a" is less than "A"{:else}"a" is greater than or equal to "A"{/lt}{~n} {@lt key="a" value="}"}"a" is less than "}"{:else}"a" is greater than or equal to "}"{/lt}{~n} +{! +Commented out because unicode breaks nom {@lt key="☃" value="☄"}"☃" is less than "☄"{:else}"☃" is greater than or equal to "☄"{/lt}{~n} +!} {@lt key=true_value value=false_value}true is less than false{:else}true is greater than or equal to false{/lt}{~n} {@lt key=array_lower value=array_higher}[3,5,7] is less than [8,9]{:else}[3,5,7] is greater than or equal to [8,9]{/lt}{~n} {@lt key=array_higher value=array_lower}[8,9] is less than [3,5,7]{:else}[8,9] is greater than or equal to [3,5,7]{/lt}{~n} diff --git a/js/test_cases/_helpers_lte/main.dust b/js/test_cases/_helpers_lte/main.dust index 2ea2f24..72ee337 100644 --- a/js/test_cases/_helpers_lte/main.dust +++ b/js/test_cases/_helpers_lte/main.dust @@ -20,7 +20,10 @@ beta is {beta}{~n} {@lte key="a" value="]"}"a" is less than or equal to "]"{:else}"a" is greater than "]"{/lte}{~n} {@lte key="a" value="A"}"a" is less than or equal to "A"{:else}"a" is greater than "A"{/lte}{~n} {@lte key="a" value="}"}"a" is less than or equal to "}"{:else}"a" is greater than "}"{/lte}{~n} +{! +Commented out because unicode breaks nom {@lte key="☃" value="☄"}"☃" is less than or equal to "☄"{:else}"☃" is greater than "☄"{/lte}{~n} +!} {@lte key=true_value value=false_value}true is less than or equal to false{:else}true is greater than false{/lte}{~n} {@lte key=array_lower value=array_higher}[3,5,7] is less than or equal to [8,9]{:else}[3,5,7] is greater than [8,9]{/lte}{~n} {@lte key=array_higher value=array_lower}[8,9] is less than or equal to [3,5,7]{:else}[8,9] is greater than [3,5,7]{/lte}{~n} diff --git a/js/test_cases/helpers_gt/main.dust b/js/test_cases/helpers_gt/main.dust index 758b231..0bd9fca 100644 --- a/js/test_cases/helpers_gt/main.dust +++ b/js/test_cases/helpers_gt/main.dust @@ -21,9 +21,9 @@ beta is {beta}{~n} {@gt key="a" value="A"}"a" is greater than "A"{:else}"a" is less than or equal to "A"{/gt}{~n} {@gt key="a" value="}"}"a" is greater than "}"{:else}"a" is less than or equal to "}"{/gt}{~n} {! - Commented out because unicode not working in rust implementation yet - {@gt key="☃" value="☄"}"☃" is greater than "☄"{:else}"☃" is less than or equal to "☄"{/gt}{~n} - !} +Commented out because unicode breaks nom +{@gt key="☃" value="☄"}"☃" is greater than "☄"{:else}"☃" is less than or equal to "☄"{/gt}{~n} +!} {@gt key=true_value value=false_value}true is greater than false{:else}true is less than or equal to false{/gt}{~n} {@gt key=array_lower value=array_higher}[3,5,7] is greater than [8,9]{:else}[3,5,7] is less than or equal to [8,9]{/gt}{~n} {@gt key=array_higher value=array_lower}[8,9] is greater than [3,5,7]{:else}[8,9] is less than or equal to [3,5,7]{/gt}{~n}