From c3fe7b47afe995258d13002803e0439d03d6f110 Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Sun, 3 May 2020 16:49:34 -0400 Subject: [PATCH] Added a test for backtracking. DustJS appears to not do any backtracking. --- js/test_cases/walk_up/README.md | 24 ++++++++++++++++++++++++ js/test_cases/walk_up/input1.json | 4 ++-- js/test_cases/walk_up/main.dust | 3 ++- src/renderer/renderer.rs | 17 ++++++++++++++++- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/js/test_cases/walk_up/README.md b/js/test_cases/walk_up/README.md index 7099d95..3f9a4b5 100644 --- a/js/test_cases/walk_up/README.md +++ b/js/test_cases/walk_up/README.md @@ -30,6 +30,9 @@ After walk "foo": {"foo":{"f1":"f","f2":"ff"},"bar":{"b1":"b","b2":"bb"}} ``` +Scoping +------- + This appears to be using dynamic scoping instead of lexical scoping. For example, in lexical scoping a read of "b1" would fail after that final walk because you're inside the "foo" context which does not have any "b1" in or above it, however, since this is using dynamic scoping its using the invocations to build a scope tree rather than their original position. Itermediate scopes appear to not be added. For example: @@ -64,3 +67,24 @@ After walk globals.things ``` So if we were on the "Dave" iteration in people and I attempted to read "item" it would not find a value despite "item" being a key in the lexical context above `globals.things`. + +Backtracking +------------ + +Item resolution appears to be greedy. For example if we have: +```js +{ + "clothes": { + "shirt": "t-shirt", + "pants": "jeans" + }, + "alice": { + "clothes": { + "shirt": "tank top" + } + }, + "bob": {}, +} +``` + +If we walked into `alice` and then attempted to read `clothes.pants` it will return nothing because `alice` has a `clothes` block but no `pants` element inside that. However, if we walked into `bob` and attempted to read `clothes.pants` it would return `jeans` because `bob` does not have a `clothes` block so it would walk up to the global `clothes` block. diff --git a/js/test_cases/walk_up/input1.json b/js/test_cases/walk_up/input1.json index e1d0c8f..889e443 100644 --- a/js/test_cases/walk_up/input1.json +++ b/js/test_cases/walk_up/input1.json @@ -10,10 +10,10 @@ ], "deep_globals": { "item": "pencil", - "things": {"color": "purple"} + "things": {"color": "purple", "deeper_item": {"style": "number 2"}} }, "deep_people": [ {"name": "Dave"}, - {"name": "Emily", "item": "pen"} + {"name": "Emily", "item": "pen", "deeper_item": {"style": "ballpoint", "material": "plastic"}} ] } diff --git a/js/test_cases/walk_up/main.dust b/js/test_cases/walk_up/main.dust index b143107..efdcfad 100644 --- a/js/test_cases/walk_up/main.dust +++ b/js/test_cases/walk_up/main.dust @@ -7,6 +7,7 @@ Testing walking after entering a parent context {#globals}job: {job}, email: {em Doing a deep walk to see if intermediate steps are added to the dynamic context.{~n} {#deep_people} {#deep_globals.things} -{name} has a {color} {item}{~n} +{name} has a {color} {item} which is {deeper_item.style} and made out of {deeper_item.material} {/deep_globals.things} +but everyone shares one that is {deeper_item.style} and made out of {deeper_item.material}{~n} {/deep_people} diff --git a/src/renderer/renderer.rs b/src/renderer/renderer.rs index d260408..cd48c5d 100644 --- a/src/renderer/renderer.rs +++ b/src/renderer/renderer.rs @@ -178,7 +178,7 @@ impl<'a> DustRenderer<'a> { } } -fn walk_path<'a>( +fn new_walk_path<'a>( context: &'a dyn ContextElement, path: &Vec<&str>, breadcrumbs: Vec<&'a dyn ContextElement>, @@ -192,6 +192,21 @@ fn walk_path<'a>( Ok(output) } +// TODO: rename walk_path_from_single_level +/// Attempts to walk a path from only 1 level in the context breadcrumbs +fn walk_path<'a>( + context: &'a dyn ContextElement, + path: &Vec<&str>, +) -> Result<&'a dyn ContextElement, RenderError<'a>> { + let mut output = context; + + for elem in path.iter() { + output = output.walk(elem)?; + } + + Ok(output) +} + #[cfg(test)] mod tests { use super::*;