public void Can_parse_template_with_only_variable() { var fragments = SharpPageUtils.ParseTemplatePage("{{ filter }}"); Assert.That(fragments.Count, Is.EqualTo(1)); Assert.That(((PageVariableFragment)fragments[0]).Binding, Is.EqualTo("filter")); }
public void Can_parse_template_with_multiple_filters_and_multiple_args() { var fragments = SharpPageUtils.ParseTemplatePage("<h1>{{ title | filter1 | filter2(1) | filter3(1,2.2,'a',\"b\",true) }}</h1>"); Assert.That(fragments.Count, Is.EqualTo(3)); var strFragment1 = fragments[0] as PageStringFragment; var varFragment2 = fragments[1] as PageVariableFragment; var strFragment3 = fragments[2] as PageStringFragment; Assert.That(strFragment1.Value.ToString(), Is.EqualTo("<h1>")); Assert.That(varFragment2.OriginalText.ToString(), Is.EqualTo("{{ title | filter1 | filter2(1) | filter3(1,2.2,'a',\"b\",true) }}")); Assert.That(varFragment2.Binding, Is.EqualTo("title")); Assert.That(varFragment2.FilterExpressions.Length, Is.EqualTo(3)); Assert.That(varFragment2.FilterExpressions[0].Name, Is.EqualTo("filter1")); Assert.That(varFragment2.FilterExpressions[0].Arguments.Length, Is.EqualTo(0)); Assert.That(varFragment2.FilterExpressions[1].Name, Is.EqualTo("filter2")); Assert.That(varFragment2.FilterExpressions[1].Arguments.Length, Is.EqualTo(1)); Assert.That(varFragment2.FilterExpressions[1].Arguments[0], Is.EqualTo(new JsLiteral(1))); Assert.That(varFragment2.FilterExpressions[2].Name, Is.EqualTo("filter3")); Assert.That(varFragment2.FilterExpressions[2].Arguments.Length, Is.EqualTo(5)); Assert.That(varFragment2.FilterExpressions[2].Arguments[0], Is.EqualTo(new JsLiteral(1))); Assert.That(varFragment2.FilterExpressions[2].Arguments[1], Is.EqualTo(new JsLiteral(2.2))); Assert.That(varFragment2.FilterExpressions[2].Arguments[2], Is.EqualTo(new JsLiteral("a"))); Assert.That(varFragment2.FilterExpressions[2].Arguments[3], Is.EqualTo(new JsLiteral("b"))); Assert.That(varFragment2.FilterExpressions[2].Arguments[4], Is.EqualTo(JsLiteral.True)); Assert.That(strFragment3.Value.ToString(), Is.EqualTo("</h1>")); }
public void Can_parse_template_with_multiple_variables_and_filters() { var fragments = SharpPageUtils.ParseTemplatePage("<h1>{{ title | filter1 }}</h1>\n<p>{{ content | filter2(a) }}</p>"); Assert.That(fragments.Count, Is.EqualTo(5)); var strFragment1 = fragments[0] as PageStringFragment; var varFragment2 = fragments[1] as PageVariableFragment; var strFragment3 = fragments[2] as PageStringFragment; var varFragment4 = fragments[3] as PageVariableFragment; var strFragment5 = fragments[4] as PageStringFragment; Assert.That(strFragment1.Value.ToString(), Is.EqualTo("<h1>")); Assert.That(varFragment2.OriginalText.ToString(), Is.EqualTo("{{ title | filter1 }}")); Assert.That(varFragment2.Binding, Is.EqualTo("title")); Assert.That(varFragment2.FilterExpressions.Length, Is.EqualTo(1)); Assert.That(varFragment2.FilterExpressions[0].Name, Is.EqualTo("filter1")); Assert.That(varFragment2.FilterExpressions[0].Arguments.Length, Is.EqualTo(0)); Assert.That(strFragment3.Value.ToString(), Is.EqualTo("</h1>\n<p>")); Assert.That(varFragment4.OriginalText.ToString(), Is.EqualTo("{{ content | filter2(a) }}")); Assert.That(varFragment4.Binding, Is.EqualTo("content")); Assert.That(varFragment4.FilterExpressions.Length, Is.EqualTo(1)); Assert.That(varFragment4.FilterExpressions[0].Name, Is.EqualTo("filter2")); Assert.That(varFragment4.FilterExpressions[0].Arguments.Length, Is.EqualTo(1)); Assert.That(varFragment4.FilterExpressions[0].Arguments[0], Is.EqualTo(new JsIdentifier("a"))); Assert.That(strFragment5.Value.ToString(), Is.EqualTo("</p>")); }
public void Can_parse_template_with_filter_without_whitespace() { var fragments = SharpPageUtils.ParseTemplatePage("<h1>{{title}}</h1>"); Assert.That(fragments.Count, Is.EqualTo(3)); var strFragment1 = fragments[0] as PageStringFragment; var varFragment2 = fragments[1] as PageVariableFragment; var strFragment3 = fragments[2] as PageStringFragment; Assert.That(strFragment1.Value.ToString(), Is.EqualTo("<h1>")); Assert.That(varFragment2.Binding, Is.EqualTo("title")); Assert.That(varFragment2.FilterExpressions.Length, Is.EqualTo(0)); fragments = SharpPageUtils.ParseTemplatePage("<h1>{{title|filter}}</h1>"); Assert.That(fragments.Count, Is.EqualTo(3)); strFragment1 = fragments[0] as PageStringFragment; varFragment2 = fragments[1] as PageVariableFragment; strFragment3 = fragments[2] as PageStringFragment; Assert.That(strFragment1.Value.ToString(), Is.EqualTo("<h1>")); Assert.That(varFragment2.OriginalText.ToString(), Is.EqualTo("{{title|filter}}")); Assert.That(varFragment2.Binding, Is.EqualTo("title")); Assert.That(varFragment2.FilterExpressions.Length, Is.EqualTo(1)); Assert.That(varFragment2.FilterExpressions[0].Name, Is.EqualTo("filter")); Assert.That(varFragment2.FilterExpressions[0].Arguments.Length, Is.EqualTo(0)); Assert.That(strFragment3.Value.ToString(), Is.EqualTo("</h1>")); }
public void Can_parse_filter_with_different_arg_types() { var fragments = SharpPageUtils.ParseTemplatePage("{{ array(['a',1,'c']) }}"); var varFragment = (PageVariableFragment)fragments[0]; Assert.That(varFragment.OriginalText.ToString(), Is.EqualTo("{{ array(['a',1,'c']) }}")); Assert.That(varFragment.InitialExpression.Name, Is.EqualTo("array")); Assert.That(varFragment.InitialExpression.Arguments.Length, Is.EqualTo(1)); }
public void Can_parse_templates_within_literals() { JsToken token; "'<li>{{it}}</li>'".ParseJsExpression(out token); Assert.That(token, Is.EqualTo(new JsLiteral("<li>{{it}}</li>"))); var fragments = SharpPageUtils.ParseTemplatePage("<ul>{{ '<li>{{it}}</li>' }}</ul>"); Assert.That(fragments.Count, Is.EqualTo(3)); }
public void Can_parse_template_with_no_vars() { Assert.That(SharpPageUtils.ParseTemplatePage("").Count, Is.EqualTo(0)); var fragments = SharpPageUtils.ParseTemplatePage("<h1>title</h1>"); Assert.That(fragments.Count, Is.EqualTo(1)); var strFragment = fragments[0] as PageStringFragment; Assert.That(strFragment.Value.ToString(), Is.EqualTo("<h1>title</h1>")); }
public void Can_parse_template_with_arg_and_multiple_filters() { var fragments = SharpPageUtils.ParseTemplatePage("{{ ' - {{it}}' | forEach(items) | markdown }}"); var varFragment = fragments[0] as PageVariableFragment; Assert.That(varFragment.OriginalText.ToString(), Is.EqualTo("{{ ' - {{it}}' | forEach(items) | markdown }}")); Assert.That(varFragment.FilterExpressions.Length, Is.EqualTo(2)); Assert.That(varFragment.FilterExpressions[0].Name, Is.EqualTo("forEach")); Assert.That(varFragment.FilterExpressions[0].Arguments.Length, Is.EqualTo(1)); Assert.That(varFragment.FilterExpressions[0].Arguments[0], Is.EqualTo(new JsIdentifier("items"))); Assert.That(varFragment.FilterExpressions[1].Name, Is.EqualTo("markdown")); }
public void Can_use_cleaner_whitespace_sensitive_syntax_for_string_arguments() { var fragments1 = SharpPageUtils.ParseTemplatePage( @"{{ products | where: it.UnitsInStock = 0 | select: { it.productName | raw } is sold out!\n }}"); var fragments2 = SharpPageUtils.ParseTemplatePage( @"{{ products | where: it.UnitsInStock = 0 | select: { it.productName | raw } is sold out!\n }}"); // i.e. is rewritten and is equivalent to: var fragments3 = SharpPageUtils.ParseTemplatePage( @"{{ products | where(′it.UnitsInStock = 0′) | select(′{{ it.productName | raw }} is sold out!\n′)}}"); Assert.That(fragments3.Count, Is.EqualTo(1)); Assert.That(fragments1.Count, Is.EqualTo(1)); var varFragment1 = fragments1[0] as PageVariableFragment; Assert.That(varFragment1.FilterExpressions[0].Name, Is.EqualTo("where")); Assert.That(varFragment1.FilterExpressions[0].Arguments.Length, Is.EqualTo(1)); Assert.That(varFragment1.FilterExpressions[0].Arguments[0], Is.EqualTo( new JsLiteral("it.UnitsInStock = 0") )); Assert.That(varFragment1.FilterExpressions[1].Name, Is.EqualTo("select")); Assert.That(varFragment1.FilterExpressions[1].Arguments.Length, Is.EqualTo(1)); Assert.That(varFragment1.FilterExpressions[1].Arguments[0], Is.EqualTo( new JsLiteral("{{ it.productName | raw }} is sold out!\\n") )); foreach (var fragments in new[] { fragments2, fragments3 }) { var varFragment = fragments[0] as PageVariableFragment; Assert.That(varFragment.FilterExpressions[0].Name, Is.EqualTo(varFragment1.FilterExpressions[0].Name)); Assert.That(varFragment.FilterExpressions[0].Arguments.Length, Is.EqualTo(varFragment1.FilterExpressions[0].Arguments.Length)); Assert.That(varFragment.FilterExpressions[0].Arguments[0], Is.EqualTo(varFragment1.FilterExpressions[0].Arguments[0])); Assert.That(varFragment.FilterExpressions[1].Name, Is.EqualTo(varFragment1.FilterExpressions[1].Name)); Assert.That(varFragment.FilterExpressions[1].Arguments.Length, Is.EqualTo(varFragment1.FilterExpressions[1].Arguments.Length)); Assert.That(varFragment.FilterExpressions[1].Arguments[0], Is.EqualTo(varFragment1.FilterExpressions[1].Arguments[0])); } }
public void Does_parse_Raw_block_body_as_string() { var fragments = SharpPageUtils.ParseTemplatePage("BEFORE {{#raw}} Hi, {{ {{ name }} }} {{/raw}} AFTER"); Assert.That(fragments.Count, Is.EqualTo(3)); Assert.That(((PageStringFragment)fragments[0]).Value.ToString(), Is.EqualTo("BEFORE ")); var statement = fragments[1] as PageBlockFragment; Assert.That(statement, Is.Not.Null); Assert.That(statement.Name, Is.EqualTo("raw")); Assert.That(statement.Argument.ToString(), Is.EqualTo("")); Assert.That(statement.Body.Length, Is.EqualTo(1)); Assert.That(((PageStringFragment)statement.Body[0]).Value.ToString(), Is.EqualTo(" Hi, {{ {{ name }} }} ")); Assert.That(((PageStringFragment)fragments[2]).Value.ToString(), Is.EqualTo(" AFTER")); }
public void Can_parse_pages_starting_with_values() { var fragments = SharpPageUtils.ParseTemplatePage( @"{{ [c.CustomerId, o.OrderId, o.OrderDate] | jsv }}\n"); var varFragment = (PageVariableFragment)fragments[0]; Assert.That(varFragment.Expression, Is.EqualTo(new JsArrayExpression( new JsMemberExpression(new JsIdentifier("c"), new JsIdentifier("CustomerId")), new JsMemberExpression(new JsIdentifier("o"), new JsIdentifier("OrderId")), new JsMemberExpression(new JsIdentifier("o"), new JsIdentifier("OrderDate")) ))); Assert.That(varFragment.OriginalText.ToString(), Is.EqualTo("{{ [c.CustomerId, o.OrderId, o.OrderDate] | jsv }}")); var newLine = (PageStringFragment)fragments[1]; Assert.That(newLine.Value.ToString(), Is.EqualTo("\\n")); }
public void Does_parse_template_with_if_else_statement() { var fragments = SharpPageUtils.ParseTemplatePage("BEFORE {{#if a < b}}YES{{else}}NO{{/if}} AFTER"); Assert.That(fragments.Count, Is.EqualTo(3)); Assert.That(((PageStringFragment)fragments[0]).Value.ToString(), Is.EqualTo("BEFORE ")); var statement = fragments[1] as PageBlockFragment; Assert.That(statement, Is.Not.Null); Assert.That(statement.Name, Is.EqualTo("if")); Assert.That(statement.Argument.ToString(), Is.EqualTo("a < b")); Assert.That(((PageStringFragment)statement.Body[0]).Value.ToString(), Is.EqualTo("YES")); Assert.That(statement.ElseBlocks[0].Argument.ToString(), Is.EqualTo("")); Assert.That(((PageStringFragment)statement.ElseBlocks[0].Body[0]).Value.ToString(), Is.EqualTo("NO")); Assert.That(((PageStringFragment)fragments[2]).Value.ToString(), Is.EqualTo(" AFTER")); }
public void Does_parse_template_with_Block_Statement() { var fragments = SharpPageUtils.ParseTemplatePage("BEFORE {{#bold}} Hi, {{name}}! {{/bold}} AFTER"); Assert.That(fragments.Count, Is.EqualTo(3)); Assert.That(((PageStringFragment)fragments[0]).Value.ToString(), Is.EqualTo("BEFORE ")); var statement = fragments[1] as PageBlockFragment; Assert.That(statement, Is.Not.Null); Assert.That(statement.Name, Is.EqualTo("bold")); Assert.That(statement.Argument.ToString(), Is.EqualTo("")); Assert.That(((PageStringFragment)statement.Body[0]).Value.ToString(), Is.EqualTo(" Hi, ")); Assert.That(((PageVariableFragment)statement.Body[1]).Binding, Is.EqualTo("name")); Assert.That(((PageStringFragment)statement.Body[2]).Value.ToString(), Is.EqualTo("! ")); Assert.That(((PageStringFragment)fragments[2]).Value.ToString(), Is.EqualTo(" AFTER")); }
public void Can_detect_invalid_syntax() { try { var fragments = SharpPageUtils.ParseTemplatePage("{{ arg | filter(' 1) }}"); Assert.Fail("should throw"); } catch (ArgumentException e) { e.Message.Print(); } try { var fragments = SharpPageUtils.ParseTemplatePage("square = {{ 'square-partial | partial({ ten }) }}"); Assert.Fail("should throw"); } catch (ArgumentException e) { e.Message.Print(); } try { var fragments = SharpPageUtils.ParseTemplatePage("{{ arg | filter({ unterminated:1) }}"); Assert.Fail("should throw"); } catch (ArgumentException e) { e.Message.Print(); } try { var fragments = SharpPageUtils.ParseTemplatePage("{{ arg | filter([ 1) }}"); Assert.Fail("should throw"); } catch (ArgumentException e) { e.Message.Print(); } }
public void Does_remove_new_line_between_var_literals() { var fragments = SharpPageUtils.ParseTemplatePage("{{ 'foo' | assignTo: bar }}\n{{ bar }}"); Assert.That(fragments.Count, Is.EqualTo(2)); fragments = SharpPageUtils.ParseTemplatePage("{{ 'foo' | assignTo: bar }}\r\n{{ bar }}"); Assert.That(fragments.Count, Is.EqualTo(2)); fragments = SharpPageUtils.ParseTemplatePage("{{ ['foo'] | do: assign('bar', it) }}\n{{ bar }}"); Assert.That(fragments.Count, Is.EqualTo(2)); fragments = SharpPageUtils.ParseTemplatePage("{{ do: assign('bar', 'foo') }}\n{{ bar }}"); Assert.That(fragments.Count, Is.EqualTo(2)); fragments = SharpPageUtils.ParseTemplatePage("{{ 10 | times | do: assign('bar', 'foo') }}\n{{ bar }}"); Assert.That(fragments.Count, Is.EqualTo(2)); fragments = SharpPageUtils.ParseTemplatePage("{{ 10 | times | do: assign('bar', 'foo') }}\nbar"); Assert.That(fragments.Count, Is.EqualTo(2)); var stringFragment = (PageStringFragment)fragments[1]; Assert.That(stringFragment.Value.ToString(), Is.EqualTo("bar")); }
public Action <ScriptScopeContext, object, object> GetAssignExpression(Type targetType, ReadOnlyMemory <char> expression) { if (targetType == null) { throw new ArgumentNullException(nameof(targetType)); } if (expression.IsNullOrWhiteSpace()) { throw new ArgumentNullException(nameof(expression)); } var key = targetType.FullName + ':' + expression; if (AssignExpressionCache.TryGetValue(key, out var fn)) { return(fn); } AssignExpressionCache[key] = fn = SharpPageUtils.CompileAssign(targetType, expression); return(fn); }
public async Task <SharpPage> Load() { string contents; using (var stream = File.OpenRead()) { contents = await stream.ReadToEndAsync(); } foreach (var preprocessor in Context.Preprocessors) { contents = preprocessor(contents); } var lastModified = File.LastModified; var fileContents = contents.AsMemory(); var pageVars = new Dictionary <string, object>(); var pos = 0; var bodyContents = fileContents; fileContents.AdvancePastWhitespace().TryReadLine(out ReadOnlyMemory <char> line, ref pos); if (line.StartsWith(Format.ArgsPrefix)) { while (fileContents.TryReadLine(out line, ref pos)) { if (line.Trim().Length == 0) { continue; } if (line.StartsWith(Format.ArgsSuffix)) { break; } var colonPos = line.IndexOf(':'); var spacePos = line.IndexOf(' '); var bracePos = line.IndexOf('{'); var sep = colonPos >= 0 ? ':' : ' '; if (bracePos > 0 && spacePos > 0 && colonPos > spacePos) { sep = ' '; } line.SplitOnFirst(sep, out var first, out var last); pageVars[first.Trim().ToString()] = !last.IsEmpty ? last.Trim().ToString() : ""; } //When page has variables body starts from first non whitespace after variables end var argsSuffixPos = line.LastIndexOf(Format.ArgsSuffix); if (argsSuffixPos >= 0) { //Start back from the end of the ArgsSuffix pos -= line.Length - argsSuffixPos - Format.ArgsSuffix.Length; } bodyContents = fileContents.SafeSlice(pos).AdvancePastWhitespace(); } var pageFragments = pageVars.TryGetValue("ignore", out object ignore) && ("page".Equals(ignore.ToString()) || "template".Equals(ignore.ToString())) ? new List <PageFragment> { new PageStringFragment(bodyContents) } : SharpPageUtils.ParseTemplatePage(bodyContents); foreach (var fragment in pageFragments) { if (fragment is PageVariableFragment var && var.Binding == ScriptConstants.Page) { IsLayout = true; break; } } lock (semaphore) { LastModified = lastModified; LastModifiedCheck = DateTime.UtcNow; FileContents = fileContents; Args = pageVars; BodyContents = bodyContents; PageFragments = pageFragments; HasInit = true; LayoutPage = Format.ResolveLayout(this); } if (LayoutPage != null) { if (!LayoutPage.HasInit) { await LayoutPage.Load(); } else { if (Context.DebugMode || Context.CheckForModifiedPagesAfter != null && DateTime.UtcNow - LayoutPage.LastModifiedCheck >= Context.CheckForModifiedPagesAfter.Value) { LayoutPage.File.Refresh(); LayoutPage.LastModifiedCheck = DateTime.UtcNow; if (LayoutPage.File.LastModified != LayoutPage.LastModified) { await LayoutPage.Load(); } } } } return(this); }