Skip to content

Commit

Permalink
Implement sameas test
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko committed Oct 31, 2024
1 parent c359ba7 commit 1b026d0
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 2 deletions.
1 change: 1 addition & 0 deletions minijinja/src/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ pub(crate) fn get_builtin_tests() -> BTreeMap<Cow<'static, str>, BoxedTest> {
rv.insert("endingwith".into(), BoxedTest::new(tests::is_endingwith));
rv.insert("lower".into(), BoxedTest::new(tests::is_lower));
rv.insert("upper".into(), BoxedTest::new(tests::is_upper));
rv.insert("sameas".into(), BoxedTest::new(tests::is_sameas));

// operators
let is_eq = BoxedTest::new(tests::is_eq);
Expand Down
30 changes: 30 additions & 0 deletions minijinja/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,36 @@ mod builtins {
pub fn is_upper(name: &str) -> bool {
name.chars().all(|x| x.is_uppercase())
}

/// Checks if two values are identical.
///
/// This primarily exists for compatibilith with Jinja2. It can be seen as a much
/// stricter comparison than a regular comparison. The main difference is that
/// values that have the same structure but a different internal object will not
/// compare equal.
///
/// ```jinja
/// {{ [1, 2, 3] is sameas([1, 2, 3]) }}
/// -> false
///
/// {{ false is sameas(false) }}
/// -> true
/// ```
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_sameas(value: &Value, other: &Value) -> bool {
match (value.as_object(), other.as_object()) {
(Some(a), Some(b)) => a.is_same_object(b),
(None, Some(_)) | (Some(_), None) => false,
(None, None) => {
if value.kind() != other.kind() || value.is_integer() != other.is_integer() {
false
} else {
value == other
}
}
}
}
}

#[cfg(feature = "builtins")]
Expand Down
5 changes: 4 additions & 1 deletion minijinja/tests/inputs/tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,7 @@ is-test: {{ 'safe' is test }} | {{ 'unknown-test' is test }}
is-boolean: {{ true is boolean }} | {{ 42 is boolean }}
is-divisibleby: {{ 42 is divisibleby(2) }} | {{ 41 is divisibleby(2) }}
is-lower: {{ "foo" is lower }} | {{ "FOO" is lower }}
is-upper: {{ "foo" is upper }} | {{ "FOO" is upper }}
is-upper: {{ "foo" is upper }} | {{ "FOO" is upper }}
seq-same-as: {{ [1, 2, 3] is sameas([1, 2, 3]) }}
const-same-as: {{ true is sameas(true) }}
int-same-as: {{ 1 is sameas(1.0) }}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ State {
"number",
"odd",
"safe",
"sameas",
"sequence",
"startingwith",
"string",
Expand Down
5 changes: 4 additions & 1 deletion minijinja/tests/snapshots/test_templates__vm@tests.txt.snap
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
source: minijinja/tests/test_templates.rs
description: "even: {{ two is even }}\nodd: {{ two is odd }}\nundefined: {{ two is undefined }}\ndefined: {{ two is defined }}\nundefined2: {{ ohwell is undefined }}\ndefined2: {{ ohwell is defined }}\nnone: {{ none is none }}\nnot-none: {{ 42 is not none }}\nnumber-int: {{ two is number }}\nnumber-float: {{ two_dot_two is number }}\ninteger-int: {{ 42 is integer }}\ninteger-float: {{ 42.0 is integer }}\nfloat-int: {{ 42 is float }}\nfloat-float: {{ 42.0 is float }}\nnot-seq: {{ two is sequence }}\nseq: {{ seq is sequence }}\nreverse-not-seq: {{ seq|reverse is sequence }}\niterable: {{ seq is iterable }}\niterable-reverse: {{ seq|reverse is iterable }}\nstring-iterable: {{ string is iterable }}\nnot-iterable: {{ two is iterable }}\nnot-map: {{ two is mapping }}\nmap: {{ map is mapping }}\nstring: {{ string is string }}\nnot-string: {{ mapping is string }}\nstarts-with-a: {{ string is startingwith('a') }}\nends-with-ha: {{ string is endingwith('ha') }}\nnot-safe: {{ \"foo\" is safe }}\nsafe: {{ \"foo\"|escape is safe }}\nis-true: {{ true is true }} | {{ 42 is true }}\nis-false: {{ false is false }} | {{ 0 is false }}\nis-filter: {{ 'escape' is filter }} | {{ 'unknown-filter' is filter }}\nis-test: {{ 'safe' is test }} | {{ 'unknown-test' is test }}\nis-boolean: {{ true is boolean }} | {{ 42 is boolean }}\nis-divisibleby: {{ 42 is divisibleby(2) }} | {{ 41 is divisibleby(2) }}\nis-lower: {{ \"foo\" is lower }} | {{ \"FOO\" is lower }}\nis-upper: {{ \"foo\" is upper }} | {{ \"FOO\" is upper }}"
description: "even: {{ two is even }}\nodd: {{ two is odd }}\nundefined: {{ two is undefined }}\ndefined: {{ two is defined }}\nundefined2: {{ ohwell is undefined }}\ndefined2: {{ ohwell is defined }}\nnone: {{ none is none }}\nnot-none: {{ 42 is not none }}\nnumber-int: {{ two is number }}\nnumber-float: {{ two_dot_two is number }}\ninteger-int: {{ 42 is integer }}\ninteger-float: {{ 42.0 is integer }}\nfloat-int: {{ 42 is float }}\nfloat-float: {{ 42.0 is float }}\nnot-seq: {{ two is sequence }}\nseq: {{ seq is sequence }}\nreverse-not-seq: {{ seq|reverse is sequence }}\niterable: {{ seq is iterable }}\niterable-reverse: {{ seq|reverse is iterable }}\nstring-iterable: {{ string is iterable }}\nnot-iterable: {{ two is iterable }}\nnot-map: {{ two is mapping }}\nmap: {{ map is mapping }}\nstring: {{ string is string }}\nnot-string: {{ mapping is string }}\nstarts-with-a: {{ string is startingwith('a') }}\nends-with-ha: {{ string is endingwith('ha') }}\nnot-safe: {{ \"foo\" is safe }}\nsafe: {{ \"foo\"|escape is safe }}\nis-true: {{ true is true }} | {{ 42 is true }}\nis-false: {{ false is false }} | {{ 0 is false }}\nis-filter: {{ 'escape' is filter }} | {{ 'unknown-filter' is filter }}\nis-test: {{ 'safe' is test }} | {{ 'unknown-test' is test }}\nis-boolean: {{ true is boolean }} | {{ 42 is boolean }}\nis-divisibleby: {{ 42 is divisibleby(2) }} | {{ 41 is divisibleby(2) }}\nis-lower: {{ \"foo\" is lower }} | {{ \"FOO\" is lower }}\nis-upper: {{ \"foo\" is upper }} | {{ \"FOO\" is upper }}\nseq-same-as: {{ [1, 2, 3] is sameas([1, 2, 3]) }}\nconst-same-as: {{ true is sameas(true) }}\nint-same-as: {{ 1 is sameas(1.0) }}"
info:
two: 2
two_dot_two: 2.2
Expand Down Expand Up @@ -50,3 +50,6 @@ is-boolean: true | false
is-divisibleby: true | false
is-lower: true | false
is-upper: false | true
seq-same-as: false
const-same-as: true
int-same-as: false

0 comments on commit 1b026d0

Please sign in to comment.