public void TestIndentedIncludes() { var template = Template.Parse(@" {{ include 'header' }} {{ include 'multilines' }} Test1 {{ include 'nested_templates_with_indent' }} Test2 "); var context = new TemplateContext(); context.TemplateLoader = new CustomTemplateLoader(); context.IndentWithInclude = true; var text = template.Render(context).Replace("\r\n", "\n"); var expectedText = @" This is a header Line 1 Line 2 Line 3 Test1 Line 1 Line 2 Line 3 Test2 ".Replace("\r\n", "\n"); TextAssert.AreEqual(expectedText, text); }
public void TestDynamicVariable() { var context = new TemplateContext { TryGetVariable = (TemplateContext templateContext, SourceSpan span, ScriptVariable variable, out object value) => { value = null; if (variable.Name == "myvar") { value = "yes"; return(true); } return(false); } }; { var template = Template.Parse("Test with a dynamic {{ myvar }}"); context.Evaluate(template.Page); var result = context.Output.ToString(); TextAssert.AreEqual("Test with a dynamic yes", result); } { // Test StrictVariables var template = Template.Parse("Test with a dynamic {{ myvar2 }}"); context.StrictVariables = true; var exception = Assert.Throws <ScriptRuntimeException>(() => context.Evaluate(template.Page)); var result = exception.ToString(); var check = "The variable or function `myvar2` was not found"; Assert.True(result.Contains(check), $"The exception string `{result}` does not contain the expected value"); } }
public void TestDynamicMember() { var template = Template.Parse("Test with a dynamic {{ a.myvar }}"); var globalObject = new ScriptObject(); globalObject.SetValue("a", new ScriptObject(), true); var context = new TemplateContext { TryGetMember = (TemplateContext localContext, SourceSpan span, object target, string member, out object value) => { value = null; if (member == "myvar") { value = "yes"; return(true); } return(false); } }; context.PushGlobal(globalObject); context.Evaluate(template.Page); var result = context.Output.ToString(); TextAssert.AreEqual("Test with a dynamic yes", result); }
public void TestFunctionWithTemplateContextAndObjectParams() { { var parsedTemplate = Template.ParseLiquid("{{ 'yoyo' | t }}"); Assert.False(parsedTemplate.HasErrors); var scriptObject = new ScriptObject(); scriptObject.Import(typeof(MyPipeFunctions)); var context = new TemplateContext(); context.PushGlobal(scriptObject); var result = parsedTemplate.Render(context); TextAssert.AreEqual("yoyo", result); } { var parsedTemplate = Template.ParseLiquid("{{ 'yoyo' | t 1 2 3}}"); Assert.False(parsedTemplate.HasErrors); var scriptObject = new ScriptObject(); scriptObject.Import(typeof(MyPipeFunctions)); var context = new TemplateContext(); context.PushGlobal(scriptObject); var result = parsedTemplate.Render(context); TextAssert.AreEqual("yoyo1,2,3", result); } }
public void TestIndentedNestedIncludes() { var context = new TemplateContext { TemplateLoader = new LoaderIndentedNestedIncludes(), IndentWithInclude = true }; var template = Template.Parse(@"Test {{include 'test' ~}} {{include 'test' ~}} "); var result = template.Render(context).Replace("\r\n", "\n"); TextAssert.AreEqual(@"Test AA BB CC DD EE FF DD EE FF AA BB CC DD EE FF DD EE FF ".Replace("\r\n", "\n"), result); }
public void TestFrontMatter() { var options = new LexerOptions() { Mode = ScriptMode.FrontMatterAndContent }; var input = @"+++ variable = 1 name = 'yes' +++ This is after the frontmatter: {{ name }} {{ variable + 1 }}"; input = input.Replace("\r\n", "\n"); var template = ParseTemplate(input, options); // Make sure that we have a front matter Assert.NotNull(template.Page.FrontMatter); var context = new TemplateContext(); // Evaluate front-matter var frontResult = context.Evaluate(template.Page.FrontMatter); Assert.Null(frontResult); // Evaluate page-content context.Evaluate(template.Page); var pageResult = context.Output.ToString(); TextAssert.AreEqual("This is after the frontmatter: yes\n2", pageResult); }
public void TestLocalVariableReturned() { var text = @"{{ func hello1 $hello = 'hello1' ret $hello end func hello2 $hello = 'hello2' ret [ $hello ] end func hello3 $hello = 'hello3' ret { hello: $hello } end func hello4 ret { hello: 'hello4' } end ~}} hello1: {{ hello1 }} hello2: {{ hello2 }} hello3: {{ hello3 }} hello4: {{ hello4 }}"; var template = Template.Parse(text); var result = template.Render().Replace("\r\n", "\n"); TextAssert.AreEqual(@"hello1: hello1 hello2: [""hello2""] hello3: {hello: ""hello3""} hello4: {hello: ""hello4""}".Replace("\r\n", "\n"), result); }
public void TestIndent2() { var input = @" {{data}}"; var template = Template.Parse(input); var result = template.Render(new { data = "test\ntest2" }); result = TextAssert.Normalize(result); TextAssert.AreEqual(" test\n test2", result); }
public void TestNullableArgument() { var template = Template.Parse("{{ tester 'input1' 1 }}"); var context = new TemplateContext(); var testerObj = new ScriptObjectWithNullable(); context.PushGlobal(testerObj); var result = template.Render(context); TextAssert.AreEqual("input1 Value: 1", result); }
public void TestFunctionArrayEachAndFunctionCall() { var template = Template.Parse(@"{{ func f; ret $0 + 1; end [1, 2, 3] | array.each @f }} EOL"); var result = template.Render(); TextAssert.AreEqual("[2, 3, 4] EOL", result); }
public void TestLoopWithInclude() { var context = new TemplateContext() { TemplateLoader = new LoaderLoopWithInclude() }; var template = Template.Parse(@"{{ for my_loop_variable in 1..3; include 'test'; end; }}"); var result = template.Render(context); TextAssert.AreEqual("123", result); }
public void TestIncludeNamedArguments() { var template = Template.Parse(@"{{ include 'named_arguments' this_arg: 5 }}"); var context = new TemplateContext(); context.TemplateLoader = new CustomTemplateLoader(); var text = template.Render(context).Replace("\r\n", "\n"); var expected = @"5"; TextAssert.AreEqual(expected, text); }
public void TestPipeAndFunction() { var template = Template.Parse(@" {{- func format_number ret $0 | math.format '0.00' | string.replace '.' '' end -}} {{ 123 | format_number -}} "); var result = template.Render(); TextAssert.AreEqual("12300", result); }
public void Test(TestFilePath testFilePath) { var inputName = testFilePath.FilePath; var baseDir = Path.GetFullPath(Path.Combine(BaseDirectory, RelativeBasePath)); var inputFile = Path.Combine(baseDir, inputName); var inputText = File.ReadAllText(inputFile); var expectedOutputFile = Path.ChangeExtension(inputFile, OutputEndFileExtension); Assert.True(File.Exists(expectedOutputFile), $"Expecting output result file [{expectedOutputFile}] for input file [{inputName}]"); var expectedOutputText = File.ReadAllText(expectedOutputFile, Encoding.UTF8); var template = Template.Parse(inputText, "text"); var result = string.Empty; if (template.HasErrors) { for (int i = 0; i < template.Messages.Count; i++) { var message = template.Messages[i]; if (i > 0) { result += "\n"; } result += message; } } else { Assert.NotNull(template.Page); try { result = template.Render(); } catch (ScriptRuntimeException exception) { result = GetReason(exception); } } Console.WriteLine("Result"); Console.WriteLine("======================================"); Console.WriteLine(result); Console.WriteLine("Expected"); Console.WriteLine("======================================"); Console.WriteLine(expectedOutputText); TextAssert.AreEqual(expectedOutputText, result); }
public void TestJekyllInclude() { var input = "{% include /this/is/a/test.htm %}"; var template = Template.ParseLiquid(input, lexerOptions: new LexerOptions() { EnableIncludeImplicitString = true, Lang = ScriptLang.Liquid }); var context = new TemplateContext { TemplateLoader = new LiquidCustomTemplateLoader() }; var result = template.Render(context); TextAssert.AreEqual("/this/is/a/test.htm", result); }
public void TestQueryableOffset() { var context = new TemplateContext(); context.CurrentGlobal.Import("data", new Func <IQueryable <int> >(() => Enumerable.Range(0, 10).AsQueryable())); var template = Template.Parse(@"{{ for item in data offset:2 item end }}"); var result = template.Render(context); TextAssert.AreEqual("23456789", result); }
public void TestQueryableRIndex() { var context = new TemplateContext(); context.CurrentGlobal.Import("data", new Func <IQueryable <int> >(() => Enumerable.Range(0, 5).AsQueryable())); var template = Template.Parse(@"{{ for item in data for.rindex end }}"); var result = template.Render(context); TextAssert.AreEqual("43210", result); }
public void TestQueryableChanged() { var context = new TemplateContext(); context.CurrentGlobal.Import("data", new Func <IQueryable <int> >(() => new[] { 0, 0, 1, 1, 2 }.AsQueryable())); var template = Template.Parse(@"{{ for item in data for.changed end }}"); var result = template.Render(context); TextAssert.AreEqual("truefalsetruefalsetrue", result); }
public void TestIndentSkippedWithGreedyOnPreviousLine() { var input = @"{{ a_multi_line_value = ""test1\ntest2\ntest3\n"" -}} {{ a_multi_line_value }}Hello "; var template = Template.Parse(input); var result = template.Render(); result = TextAssert.Normalize(result); TextAssert.AreEqual(TextAssert.Normalize(@"test1 test2 test3 Hello "), result); }
public void TestEosWithEnd2() { var templateText = @" {{- foo = (do; ret 'fo'; end) + (do; ret 'o'; end) -}} {{foo}}"; var template = Template.Parse(templateText); var templateText2 = template.ToText(); var template2 = Template.Parse(templateText2); var templateText3 = template2.ToText(); Console.WriteLine(templateText3); TextAssert.AreEqual(templateText2, templateText3); TextAssert.AreEqual(template.Render(), template2.Render()); }
public void TestQueryableLast() { var context = new TemplateContext(); context.CurrentGlobal.Import("data", new Func <IQueryable <int> >(() => Enumerable.Range(0, 5).AsQueryable())); var template = Template.Parse(@"{{ for item in data for.last end }}"); var result = template.Render(context); // last will always be false with iqueryable TextAssert.AreEqual("falsefalsefalsefalsetrue", result); }
public void InvalidPipe() { var parsedTemplate = Template.ParseLiquid("{{ 22.00 | a | b | string.upcase }}"); Assert.False(parsedTemplate.HasErrors); var scriptObject = new ScriptObject(); scriptObject.Import(typeof(MyPipeFunctions)); var context = new TemplateContext(); context.PushGlobal(scriptObject); var result = parsedTemplate.Render(context); TextAssert.AreEqual("22AB", result); }
public void TestPipeAndFunctionAndLoop() { var template = Template.Parse(@" {{- func format_number ret $0 | math.format '0.00' | string.replace '.' '' end -}} {{ for $i in 1..3 temp_variable = $i | format_number end -}} {{ temp_variable -}} "); var result = template.Render(); TextAssert.AreEqual("300", result); }
public void TestIndentedIncludes2() { var template = Template.Parse(@"Test {{ include 'header' }} "); var context = new TemplateContext(); context.TemplateLoader = new CustomTemplateLoader(); context.IndentWithInclude = true; var text = template.Render(context).Replace("\r\n", "\n"); var expected = @"Test This is a header ".Replace("\r\n", "\n"); TextAssert.AreEqual(expected, text); }
public void TestQueryableLoopLimit() { var context = new TemplateContext { LoopLimit = 5 }; context.CurrentGlobal.Import("data", new Func <IQueryable <int> >(() => Enumerable.Range(0, 10).AsQueryable())); var template = Template.Parse(@"{{ for item in data item end }}"); var exception = Assert.Throws <ScriptRuntimeException>(() => template.Render(context)); TextAssert.AreEqual("<input>(2,1) : error : Exceeding number of iteration limit `5` for loop statement.", exception.Message); }
public void TestDynamicVariable() { var template = Template.Parse("Test with a dynamic {{ myvar }}"); var context = new TemplateContext { TryGetVariable = variable => { Assert.AreEqual("myvar", variable.Name); return("yes"); } }; context.Evaluate(template.Page); var result = context.Output.ToString(); TextAssert.AreEqual("Test with a dynamic yes", result); }
public void TestQueryableLoopLimitQueryableDisable() { var context = new TemplateContext { LoopLimit = 5, LoopLimitQueryable = 0, }; context.CurrentGlobal.Import("data", new Func <IQueryable <int> >(() => Enumerable.Range(0, 10).AsQueryable())); var template = Template.Parse(@"{{ for item in data item end }}"); var result = template.Render(context); TextAssert.AreEqual("0123456789", result); }
public void TestPropertyInheritance() { var scriptObject = new ScriptObject { { "a", new MyObject { PropertyA = "ClassA" } }, { "b", new MyObject2 { PropertyA = "ClassB", PropertyC = "ClassB-PropC" } } }; var context = new TemplateContext(); context.PushGlobal(scriptObject); var result = Template.Parse("{{a.property_a}}-{{b.property_a}}-{{b.property_c}}").Render(context); TextAssert.AreEqual("ClassA-ClassB-ClassB-PropC", result); }
public void TestEosWithEnd() { var templateText = @" {{- func foo if b -}} bar {{- end end -}}{{foo}}"; var template = Template.Parse(templateText); var templateText2 = template.ToText(); var template2 = Template.Parse(templateText2); var templateText3 = template2.ToText(); TextAssert.AreEqual(templateText2, templateText3); TextAssert.AreEqual(template.Render(), template2.Render()); }
public void TestLoopVariable() { var template = Template.Parse(@" {{- for x in [1,2,3,4,5] y = x end -}} x and y = {{ x }} and {{ y }} {{~ for y in [6,7,8,9,0] z = y end ~}} y and z = {{ y }} and {{ z -}} "); var expected = @"x and y = and 5 y and z = 5 and 0"; var tc = new TemplateContext(); var result = template.Render(tc); TextAssert.AreEqual(expected, result); }