Add tests for explicit context setting that check failure conditions and implement a helper function to generate a new breadcrumb stack.
This commit is contained in:
parent
8121c93392
commit
4a21ae5af3
@ -37,4 +37,24 @@ Explicitly setting a context does not work on a reference, but it has revealed t
|
||||
Paths
|
||||
-----
|
||||
|
||||
Explicit contexts do support deep paths
|
||||
Explicit contexts do support deep paths.
|
||||
|
||||
Else Blocks
|
||||
-----------
|
||||
|
||||
Else blocks also use an explicit context.
|
||||
|
||||
Complete Failure
|
||||
----------------
|
||||
|
||||
If the walk destination does not exist, and the explicit context does not exist, then you end up with absolutely no context.
|
||||
|
||||
Regular Path Failure
|
||||
--------------------
|
||||
|
||||
If the regular path fails but the explicit path succeeds then the context is set to the explicit path.
|
||||
|
||||
Falsey Explicit Path
|
||||
--------------------
|
||||
|
||||
Since dust would not walk to a falsey path, theres no difference between a falsey path and a non-existent path.
|
||||
|
@ -24,5 +24,6 @@
|
||||
"explicit": {
|
||||
"pet": "cat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"empty_array": []
|
||||
}
|
||||
|
@ -157,3 +157,101 @@ Variable Explicit{~n}
|
||||
{/person}
|
||||
{/loop}
|
||||
|
||||
{! What context is set on else blocks? !}
|
||||
Else Block Regular{~n}
|
||||
=================={~n}
|
||||
{#loop}
|
||||
{#empty_array}
|
||||
MAIN {$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{:else}
|
||||
ELSE {$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{/empty_array}
|
||||
{/loop}
|
||||
|
||||
Else Block Explicit{~n}
|
||||
==================={~n}
|
||||
{#loop}
|
||||
{#empty_array:explicit}
|
||||
MAIN {$idx}: {person.name} has a pet {pet} but not a {some_global}{~n}
|
||||
{:else}
|
||||
ELSE {$idx}: {person.name} has a pet {pet} but not a {some_global}{~n}
|
||||
{/empty_array}
|
||||
{/loop}
|
||||
|
||||
{! What context is set when the explicit context path does not exist? !}
|
||||
Failed Explicit Regular{~n}
|
||||
======================={~n}
|
||||
{#loop}
|
||||
{#person}
|
||||
{$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{/person}
|
||||
{/loop}
|
||||
|
||||
Failed Explicit Explicit{~n}
|
||||
========================{~n}
|
||||
{#loop}
|
||||
{#person:foobar}
|
||||
{$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{/person}
|
||||
{/loop}
|
||||
|
||||
{! What context is set when the regular path and explicit context path does not exist? !}
|
||||
Failed Everything Regular{~n}
|
||||
========================={~n}
|
||||
BEFORE {.|js}{~n}
|
||||
{#foo}
|
||||
MAIN {.|js}{~n}
|
||||
{:else}
|
||||
ELSE {.|js}{~n}
|
||||
{/foo}
|
||||
|
||||
Failed Everything Explicit{~n}
|
||||
=========================={~n}
|
||||
{#foo:bar}
|
||||
MAIN {.|js}{~n}
|
||||
{:else}
|
||||
ELSE {.|js}{~n}
|
||||
{/foo}
|
||||
|
||||
{! What context is set when the regular context path does not exist? !}
|
||||
Failed Regular Path Regular{~n}
|
||||
==========================={~n}
|
||||
{#loop}
|
||||
{#foo}
|
||||
MAIN {$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{:else}
|
||||
ELSE {$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{/foo}
|
||||
{/loop}
|
||||
|
||||
Failed Regular Path Explicit{~n}
|
||||
============================{~n}
|
||||
{#loop}
|
||||
{#foo:explicit}
|
||||
MAIN {$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{:else}
|
||||
ELSE {$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{/foo}
|
||||
{/loop}
|
||||
|
||||
{! What context is set when the explicit path is falsey? !}
|
||||
Falsey Explicit Path Regular{~n}
|
||||
============================{~n}
|
||||
{#loop}
|
||||
{#foo}
|
||||
MAIN {$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{:else}
|
||||
ELSE {$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{/foo}
|
||||
{/loop}
|
||||
|
||||
Falsey Explicit Path Explicit{~n}
|
||||
============================={~n}
|
||||
{#loop}
|
||||
{#foo:empty_array}
|
||||
MAIN {$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{:else}
|
||||
ELSE {$idx}: {name} has a pet {pet} but not a {some_global}{~n}
|
||||
{.|js}{~n}
|
||||
{/foo}
|
||||
{/loop}
|
||||
|
@ -9,6 +9,7 @@ pub use parser::Filter;
|
||||
pub use parser::KVPair;
|
||||
pub use parser::OwnedLiteral;
|
||||
pub use parser::PartialNameElement;
|
||||
pub use parser::Path;
|
||||
pub use parser::RValue;
|
||||
pub use parser::Special;
|
||||
pub use parser::Template;
|
||||
|
@ -3,6 +3,7 @@ use crate::parser::Body;
|
||||
use crate::parser::DustTag;
|
||||
use crate::parser::KVPair;
|
||||
use crate::parser::PartialNameElement;
|
||||
use crate::parser::Path;
|
||||
use crate::parser::RValue;
|
||||
use crate::parser::Special;
|
||||
use crate::parser::Template;
|
||||
@ -551,6 +552,61 @@ impl<'a> DustRenderer<'a> {
|
||||
}
|
||||
final_filters
|
||||
}
|
||||
|
||||
/// Generate a new breadcrumbs object
|
||||
///
|
||||
/// This function generates a new breadcrumbs object based on the
|
||||
/// new context information provided.
|
||||
///
|
||||
/// explicit_context is for contexts specified with a `:path`
|
||||
/// inside a dust tag.
|
||||
///
|
||||
/// injected_context is for any generated context. This includes
|
||||
/// both parameters on a tag and also the handling of $idx and
|
||||
/// $len.
|
||||
///
|
||||
/// New context element is the element is an element to append to
|
||||
/// the end, generally for use in section tags which walk to a new
|
||||
/// context.
|
||||
///
|
||||
/// If explicit_context is not None, then the final breadcrumb stack will be:
|
||||
///
|
||||
/// ```
|
||||
/// breadcrumbs
|
||||
/// injected_context
|
||||
/// new_context_element
|
||||
/// ```
|
||||
///
|
||||
/// However, if explicit_context is not None, then the old
|
||||
/// breadcrumbs are omitted, leading to the new breadcrumb stack
|
||||
/// as:
|
||||
///
|
||||
/// ```
|
||||
/// injected_context
|
||||
/// explicit_context
|
||||
/// new_context_element
|
||||
/// ```
|
||||
fn new_breadcrumbs<'b>(
|
||||
breadcrumbs: &'b Vec<&'b dyn ContextElement>,
|
||||
injected_context: Option<&'b dyn ContextElement>,
|
||||
explicit_context: &Option<Path<'b>>,
|
||||
new_context_element: Option<&'b dyn ContextElement>,
|
||||
) -> Vec<&'b dyn ContextElement> {
|
||||
let mut new_stack = match explicit_context {
|
||||
Some(_) => Vec::with_capacity(3),
|
||||
None => breadcrumbs.clone(),
|
||||
};
|
||||
injected_context.map(|ctx| new_stack.push(ctx));
|
||||
explicit_context.as_ref().map(|path| {
|
||||
walk_path(breadcrumbs, &path.keys).map(|val| {
|
||||
if val.is_truthy() {
|
||||
new_stack.push(val)
|
||||
}
|
||||
});
|
||||
});
|
||||
new_context_element.map(|ctx| new_stack.push(ctx));
|
||||
new_stack
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -42,6 +42,12 @@ where
|
||||
B: Borrow<dyn ContextElement + 'a>,
|
||||
P: Borrow<str>,
|
||||
{
|
||||
if breadcrumbs.is_empty() {
|
||||
// This happens when you use a section with an explicit
|
||||
// context path, where both the path and the explicit context
|
||||
// path fail, leaving you with absolutely no context.
|
||||
return Err(WalkError::CantWalk);
|
||||
}
|
||||
if path.is_empty() {
|
||||
return Ok(breadcrumbs
|
||||
.last()
|
||||
|
Loading…
x
Reference in New Issue
Block a user