Beispiel #1
0
        public void Should_combine_single_substitutions_and_each_substitutions()
        {
            var input = @"<html><head></head><body><ul>@Each.Users;<li>Hello @Current;, @Model.Name; says hello!</li>@EndEach;</ul></body></html>";
            var model = new
            {
                Name  = "Nancy",
                Users = new List <string>()
                {
                    "Bob", "Jim", "Bill"
                }
            };
            var output = Parse(input, model.GetType());

            AssertSyntaxTree(output,
                             SyntaxTree.WriteString("<html><head></head><body><ul>"),
                             SyntaxTree.Iterate(
                                 SyntaxTreeExpression.Property(model.GetType(), "Users"),
                                 SyntaxTree.Block(
                                     SyntaxTree.WriteString("<li>Hello "),
                                     SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string), ExpressionScope.CurrentModelOnStack)),
                                     SyntaxTree.WriteString(", "),
                                     SyntaxTree.WriteExpression(SyntaxTreeExpression.Property(model.GetType(), "Name", ExpressionScope.RootModel)),
                                     SyntaxTree.WriteString(" says hello!</li>")
                                     )
                                 ),
                             SyntaxTree.WriteString("</ul></body></html>")
                             );
        }
Beispiel #2
0
        public static ExpressionNode Parse(HandlebarsParserState state, HandlebarsBlockStack blockStack, SourceLocation location, string expression, IMemberLocator memberLocator = null)
        {
            int recursionLevel = 0;

            memberLocator = memberLocator ?? MemberLocator.Default;

            expression = expression.Trim();

            if (expression == "this")
            {
                return(SyntaxTreeExpression.Self(blockStack.GetCurrentModelType(), location));
            }
            if (expression.StartsWith("../"))
            {
                var blockNode = blockStack.FirstNode();
                while (expression.StartsWith("../"))
                {
                    var parentBlockNode = blockStack.GetParentNode(blockNode);
                    if (parentBlockNode != null)
                    {
                        blockNode  = parentBlockNode;
                        expression = expression.Substring(3);
                        location   = location.MoveIndex(3);
                    }
                    recursionLevel++;
                }
                return(ParseAgainstModel(blockStack.GetCurrentModelType(blockNode), expression, ExpressionScope.ModelOfParentScope, recursionLevel, memberLocator, location));
            }

            return(ParseAgainstModel(blockStack.GetCurrentModelType(), expression, ExpressionScope.CurrentModelOnStack, recursionLevel, memberLocator, location));
        }
Beispiel #3
0
        public void Should_parse_if_block_with_explicit_model_reference()
        {
            var input = @"<html><head></head><body>@If.Model.HasUsers;<ul>@Each.Users;<li>Hello @Current;, @Model.Name; says hello!</li>@EndEach;</ul>@EndIf;</body></html>";
            var model = new FakeModel("Nancy", new List <string>()
            {
                "Bob", "Jim", "Bill"
            });
            var output = Parse(input, model.GetType());

            AssertSyntaxTree(output,
                             SyntaxTree.WriteString("<html><head></head><body>"),
                             SyntaxTree.Conditional(
                                 SyntaxTreeExpression.Property(model.GetType(), "HasUsers", ExpressionScope.RootModel),
                                 SyntaxTree.Block(
                                     SyntaxTree.WriteString("<ul>"),
                                     SyntaxTree.Iterate(
                                         SyntaxTreeExpression.Property(model.GetType(), "Users"),
                                         SyntaxTree.Block(
                                             SyntaxTree.WriteString("<li>Hello "),
                                             SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string))),
                                             SyntaxTree.WriteString(", "),
                                             SyntaxTree.WriteExpression(SyntaxTreeExpression.Property(model.GetType(), "Name", ExpressionScope.RootModel)),
                                             SyntaxTree.WriteString(" says hello!</li>")
                                             )
                                         ),
                                     SyntaxTree.WriteString("</ul>")
                                     )
                                 ),
                             SyntaxTree.WriteString("</body></html>")
                             );
        }
Beispiel #4
0
        private static void HandlePartial(HandlebarsParserState state)
        {
            var partialTemplateName = state.CurrentToken.Content.Substring(1).Trim();
            var self = SyntaxTreeExpression.Self(state.BlockStack.GetCurrentModelType());

            state.AddNodeToCurrentBlock(SyntaxTree.Include(partialTemplateName, self));
        }
Beispiel #5
0
        public void Should_return_true_for_ifhascollection_when_if_model_has_a_collection_with_items_but_no_bool()
        {
            var input = @"<html><head></head><body>@If.HasUsers;<ul>@Each.Users;<li>Hello @Current;, @Model.Name; says hello!</li>@EndEach;</ul>@EndIf;</body></html>";
            var model = new { Users = new List <string>()
                              {
                                  "Bob", "Jim", "Bill"
                              }, Name = "Nancy" };
            var output = Parse(input, model.GetType());

            AssertSyntaxTree(
                output,
                SyntaxTree.WriteString("<html><head></head><body>"),
                SyntaxTree.Conditional(
                    SyntaxTreeExpression.HasItems(SyntaxTreeExpression.Property(model.GetType(), "Users")),
                    SyntaxTree.Block(
                        SyntaxTree.WriteString("<ul>"),
                        SyntaxTree.Iterate(
                            SyntaxTreeExpression.Property(model.GetType(), "Users"),
                            SyntaxTree.Block(
                                SyntaxTree.WriteString("<li>Hello "),
                                SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string))),
                                SyntaxTree.WriteString(", "),
                                SyntaxTree.WriteExpression(SyntaxTreeExpression.Property(model.GetType(), "Name", ExpressionScope.RootModel)),
                                SyntaxTree.WriteString(" says hello!</li>")
                                )
                            ),
                        SyntaxTree.WriteString("</ul>")
                        )
                    ),
                SyntaxTree.WriteString("</body></html>")
                );
        }
Beispiel #6
0
        public void Should_not_render_block_when_ifnot_statements_returns_true()
        {
            var input = @"<html><head></head><body>@IfNot.HasUsers;<p>No users found!</p>@EndIf;<ul>@Each.Users;<li>Hello @Current;, @Model.Name; says hello!</li>@EndEach;</ul></body></html>";
            var model = new FakeModel("Nancy", new List <string>()
            {
                "Bob", "Jim", "Bill"
            });
            var output = Parse(input, model.GetType());

            AssertSyntaxTree(output,
                             SyntaxTree.WriteString("<html><head></head><body>"),
                             SyntaxTree.Conditional(
                                 SyntaxTreeExpression.Property(model.GetType(), "HasUsers"),
                                 SyntaxTree.Block(),
                                 SyntaxTree.Block(
                                     SyntaxTree.WriteString("<p>No users found!</p>")
                                     )
                                 ),
                             SyntaxTree.WriteString("<ul>"),
                             SyntaxTree.Iterate(
                                 SyntaxTreeExpression.Property(model.GetType(), "Users"),
                                 SyntaxTree.Block(
                                     SyntaxTree.WriteString("<li>Hello "),
                                     SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string))),
                                     SyntaxTree.WriteString(", "),
                                     SyntaxTree.WriteExpression(SyntaxTreeExpression.Property(model.GetType(), "Name", ExpressionScope.RootModel)),
                                     SyntaxTree.WriteString(" says hello!</li>")
                                     )
                                 ),
                             SyntaxTree.WriteString("</ul></body></html>")
                             );
        }
Beispiel #7
0
        public void Should_parse_current_keyword_as_self_expression()
        {
            var model  = new { };
            var result = SuperSimpleExpressionParser.Parse(CreateScopes(model.GetType()), "Current");

            result.ShouldDeepEqual(SyntaxTreeExpression.Self(model.GetType()));
        }
Beispiel #8
0
        public void Should_parse_model_keywords_as_self_expression_scoped_to_root()
        {
            var model  = new { };
            var result = SuperSimpleExpressionParser.Parse(CreateScopes(model.GetType()), "Model");

            result.ShouldDeepEqual(SyntaxTreeExpression.Self(model.GetType(), ExpressionScope.RootModel));
        }
Beispiel #9
0
        public static ExpressionNode Parse(LinkedList <SuperSimpleTemplateParserScope> scopes, string originalExpression)
        {
            var expression = originalExpression.Trim();

            if (expression == "Model")
            {
                return(SyntaxTreeExpression.Self(scopes.Last.Value.ModelType, ExpressionScope.RootModel));
            }
            if (expression == "Current")
            {
                return(SyntaxTreeExpression.Self(scopes.First.Value.ModelType, ExpressionScope.CurrentModelOnStack));
            }

            var chosenScope     = scopes.First.Value;
            var expressionScope = ExpressionScope.CurrentModelOnStack;

            if (expression.StartsWith("Current."))
            {
                expression = expression.Substring(8);
            }
            else if (expression.StartsWith("Model."))
            {
                expression      = expression.Substring(6);
                chosenScope     = scopes.Last.Value;
                expressionScope = ExpressionScope.RootModel;
            }

            return(ParseAgainstModel(originalExpression, expression, chosenScope, expressionScope));
        }
Beispiel #10
0
        public void Should_be_able_to_write_from_parent_scope_model()
        {
            var model = new Model <string>
            {
                Name      = "Root",
                SubModels = new[] {
                    new SubModel <string> {
                        Name = "1", Strings = new [] { "A", "B" }
                    },
                    new SubModel <string> {
                        Name = "2", Strings = new [] { "C", "D" }
                    }
                }
            };
            var template = SyntaxTree.Block(
                SyntaxTree.Iterate(
                    SyntaxTreeExpression.Property(model.GetType(), "SubModels", ExpressionScope.RootModel),
                    SyntaxTree.Block(
                        SyntaxTree.Iterate(
                            SyntaxTreeExpression.Property(model.Sub.GetType(), "Strings", ExpressionScope.CurrentModelOnStack),
                            SyntaxTree.Block(
                                SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string), ExpressionScope.CurrentModelOnStack)),
                                SyntaxTree.WriteExpression(SyntaxTreeExpression.Property(model.Sub.GetType(), "Name", ExpressionScope.ModelOfParentScope)),
                                SyntaxTree.WriteExpression(SyntaxTreeExpression.Property(model.GetType(), "Name", ExpressionScope.RootModel))
                                )
                            )
                        )
                    )
                );
            var result = ExecuteTemplate(template, model);

            Assert.That(result, Is.EqualTo("A1RootB1RootC2RootD2Root"));
        }
        public void Should_trim_whitespace_from_previous_literal()
        {
            var template = Parse("Hello \r\n{{~this}}", typeof(string));

            AssertSyntaxTree(
                template,
                SyntaxTree.WriteString("Hello"),
                SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string)), true)
                );
        }
Beispiel #12
0
        private static void HandleEachOverSelf(SuperSimpleTemplateParserState state)
        {
            var each = SyntaxTree.Iterate(
                SyntaxTreeExpression.Self(state.CurrentTypeInScope()),
                SyntaxTree.Block()
                );

            state.AddNodeToCurrentBlock(each);
            state.PushNewScope(each.Body, each.ItemType);
        }
        public void Should_trim_whitespace_from_next_literal()
        {
            var template = Parse("Hello {{this~}}\r\n!", typeof(string));

            AssertSyntaxTree(
                template,
                SyntaxTree.WriteString("Hello "),
                SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string)), true),
                SyntaxTree.WriteString("!")
                );
        }
Beispiel #14
0
        public void Should_parse_partial_syntax()
        {
            var model    = new { };
            var template = Parse("Hello {{> person }}", model.GetType());

            AssertSyntaxTree(
                template,
                SyntaxTree.WriteString("Hello "),
                SyntaxTree.Include("person", SyntaxTreeExpression.Self(model.GetType()))
                );
        }
Beispiel #15
0
        private static void HandlePartial(SuperSimpleTemplateParserState state)
        {
            var            details    = state.ParseCurrentTokenNameAndModelExpression();
            ExpressionNode expression = SyntaxTreeExpression.Self(state.CurrentTypeInScope());

            if (!String.IsNullOrEmpty(details.Model))
            {
                expression = state.ParseExpression(details.Model);
            }
            state.AddNodeToCurrentBlock(SyntaxTree.Include(details.Name, expression));
        }
Beispiel #16
0
        public void Should_replace_primitive_model_with_value()
        {
            var input  = @"<html><head></head><body>Hello there @Model;</body></html>";
            var output = Parse(input, typeof(string));

            AssertSyntaxTree(output,
                             SyntaxTree.WriteString("<html><head></head><body>Hello there "),
                             SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string), ExpressionScope.RootModel)),
                             SyntaxTree.WriteString("</body></html>")
                             );
        }
Beispiel #17
0
        public void Should_parse_basic_partials()
        {
            var input  = @"<html><head></head><body>@Partial['testing'];</body></html>";
            var result = Parse(input, typeof(object));

            AssertSyntaxTree(
                result,
                SyntaxTree.WriteString("<html><head></head><body>"),
                SyntaxTree.Include("testing", SyntaxTreeExpression.Self(typeof(object))),
                SyntaxTree.WriteString("</body></html>")
                );
        }
Beispiel #18
0
        public void Should_parse_each_block()
        {
            var result = Parse("{{#each Items }}{{ this }}{{/each}}", typeof(TestModel));

            AssertSyntaxTree(result,
                             SyntaxTree.Iterate(
                                 SyntaxTreeExpression.Property(typeof(TestModel), "Items"),
                                 SyntaxTree.Block(
                                     SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string)), true)
                                     )
                                 )
                             );
        }
Beispiel #19
0
        public void Should_throw_if_unable_to_load_template()
        {
            var model    = new { Name = "Joe" };
            var template = SyntaxTree.Block(
                SyntaxTree.WriteString("Hello "),
                SyntaxTree.Include("person", SyntaxTreeExpression.Self(model.GetType()))
                );

            Assert.Throws <VeilCompilerException>(() =>
            {
                ExecuteTemplate(template, model);
            });
        }
Beispiel #20
0
        public void Should_be_able_to_output_value_types_from_collections()
        {
            var model    = new { Items = new[] { "1", "2", "3", "4" } };
            var template = SyntaxTree.Block(SyntaxTree.Iterate(
                                                SyntaxTreeExpression.Property(model.GetType(), "Items"),
                                                SyntaxTree.Block(
                                                    SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string)))
                                                    )
                                                ));

            var result = ExecuteTemplate(template, model);

            Assert.Equal("1234", result);
        }
Beispiel #21
0
        public void Should_be_able_to_reference_parent_scope_from_within_each_block()
        {
            var result = Parse("{{#each Items }}{{ ../Prefix }}{{ this }}{{/each}}", typeof(TestModel));

            AssertSyntaxTree(result,
                             SyntaxTree.Iterate(
                                 SyntaxTreeExpression.Property(typeof(TestModel), "Items"),
                                 SyntaxTree.Block(
                                     SyntaxTree.WriteExpression(SyntaxTreeExpression.Property(typeof(TestModel), "Prefix", ExpressionScope.ModelOfParentScope), true),
                                     SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string)), true)
                                     )
                                 )
                             );
        }
Beispiel #22
0
        public static ExpressionNode Parse(HandlebarsBlockStack blockStack, string expression)
        {
            expression = expression.Trim();

            if (expression == "this")
            {
                return(SyntaxTreeExpression.Self(blockStack.GetCurrentModelType(), ExpressionScope.CurrentModelOnStack));
            }
            if (expression.StartsWith("../"))
            {
                return(ParseAgainstModel(blockStack.GetParentModelType(), expression.Substring(3), ExpressionScope.ModelOfParentScope));
            }

            return(ParseAgainstModel(blockStack.GetCurrentModelType(), expression, ExpressionScope.CurrentModelOnStack));
        }
Beispiel #23
0
        public void Should_be_able_to_iterate_items_from_an_untyped_model()
        {
            var model = new Dictionary <string, object>();

            model.Add("Items", new string[] { "1", "2" });
            var template = SyntaxTree.Block(SyntaxTree.Iterate(
                                                SyntaxTreeExpression.LateBound("Items"),
                                                SyntaxTree.Block(
                                                    SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(object)))
                                                    )
                                                ));

            var result = ExecuteTemplate(template, model);

            Assert.Equal("12", result);
        }
Beispiel #24
0
        public void Should_render_include_with_same_model()
        {
            var model = new { Name = "Joe" };

            RegisterTemplate("person", SyntaxTree.Block(
                                 SyntaxTree.WriteExpression(SyntaxTreeExpression.Property(model.GetType(), "Name"))
                                 ));
            var template = SyntaxTree.Block(
                SyntaxTree.WriteString("Hello "),
                SyntaxTree.Include("person", SyntaxTreeExpression.Self(model.GetType()))
                );

            var result = ExecuteTemplate(template, model);

            Assert.That(result, Is.EqualTo("Hello Joe"));
        }
Beispiel #25
0
        public void Should_support_this_inside_with_block()
        {
            var model    = new { User = "" };
            var template = Parse("Hello {{#with User}}{{this}}{{/with}}", model.GetType());

            AssertSyntaxTree(
                template,
                SyntaxTree.WriteString("Hello "),
                SyntaxTree.ScopeNode(
                    SyntaxTreeExpression.Property(model.GetType(), "User"),
                    SyntaxTree.Block(
                        SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(model.User.GetType()), true)
                        )
                    )
                );
        }
Beispiel #26
0
        public void Should_render_include_with_untyped_model()
        {
            var model = new Dictionary <string, object>();

            model.Add("Name", "Joe");

            RegisterTemplate("person", SyntaxTree.Block(
                                 SyntaxTree.WriteExpression(SyntaxTreeExpression.LateBound("Name"))
                                 ));
            var template = SyntaxTree.Block(
                SyntaxTree.WriteString("Hello "),
                SyntaxTree.Include("person", SyntaxTreeExpression.Self(model.GetType()))
                );

            var result = ExecuteTemplate(template, model);

            Assert.That(result, Is.EqualTo("Hello Joe"));
        }
Beispiel #27
0
        public void Should_handle_conditional_on_root_scope()
        {
            var model    = new { RootConditional = true, Values = new[] { 1, 2, 3 } };
            var template = SyntaxTree.Block(
                SyntaxTree.Iterate(
                    SyntaxTreeExpression.Property(model.GetType(), "Values"),
                    SyntaxTree.Block(
                        SyntaxTree.Conditional(
                            SyntaxTreeExpression.Property(model.GetType(), "RootConditional", ExpressionScope.RootModel),
                            SyntaxTree.Block(SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(int))))
                            )
                        )
                    )
                );
            var result = this.ExecuteTemplate(template, model);

            Assert.Equal("123", result);
        }
Beispiel #28
0
        public void Should_allow_each_without_a_variable_and_iterate_over_the_model_if_it_is_enumerable(string input)
        {
            var model = new List <string>()
            {
                "Bob", "Jim", "Bill"
            };
            var output = Parse(input, model.GetType());

            AssertSyntaxTree(
                output,
                SyntaxTree.WriteString("<html><head></head><body><ul>"),
                SyntaxTree.Iterate(
                    SyntaxTreeExpression.Self(model.GetType()),
                    SyntaxTree.Block(
                        SyntaxTree.WriteString("<li>Hello "),
                        SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string))),
                        SyntaxTree.WriteString("</li>")
                        )
                    ),
                SyntaxTree.WriteString("</ul></body></html>")
                );
        }
Beispiel #29
0
        public void Should_allow_each_statements_to_work_over_multiple_lines()
        {
            var input = "<html>\n\t<head>\n\t</head>\n\t<body>\n\t\t<ul>@Each.Users;\n\t\t\t<li>@Current;</li>@EndEach;\n\t\t</ul>\n\t</body>\n</html>";
            var model = new { Users = new List <string>()
                              {
                                  "Bob", "Jim", "Bill"
                              } };
            var output = Parse(input, model.GetType());

            AssertSyntaxTree(output,
                             SyntaxTree.WriteString("<html>\n\t<head>\n\t</head>\n\t<body>\n\t\t<ul>"),
                             SyntaxTree.Iterate(
                                 SyntaxTreeExpression.Property(model.GetType(), "Users"),
                                 SyntaxTree.Block(
                                     SyntaxTree.WriteString("\n\t\t\t<li>"),
                                     SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string))),
                                     SyntaxTree.WriteString("</li>")
                                     )
                                 ),
                             SyntaxTree.WriteString("\n\t\t</ul>\n\t</body>\n</html>")
                             );
        }
Beispiel #30
0
        public void Should_support_implicit_model_reference_for_each_block()
        {
            var input = @"<html><head></head><body><ul>@Each.Users;<li>@Current;</li>@EndEach;</ul></body></html>";
            var model = new { Users = new List <string>()
                              {
                                  "Bob", "Jim", "Bill"
                              } };
            var output = Parse(input, model.GetType());

            AssertSyntaxTree(output,
                             SyntaxTree.WriteString("<html><head></head><body><ul>"),
                             SyntaxTree.Iterate(
                                 SyntaxTreeExpression.Property(model.GetType(), "Users"),
                                 SyntaxTree.Block(
                                     SyntaxTree.WriteString("<li>"),
                                     SyntaxTree.WriteExpression(SyntaxTreeExpression.Self(typeof(string), ExpressionScope.CurrentModelOnStack)),
                                     SyntaxTree.WriteString("</li>")
                                     )
                                 ),
                             SyntaxTree.WriteString("</ul></body></html>")
                             );
        }