public void ExpandedTokensCustomRenderingIsUsed() { var baseTemplate = "Hello, {{{ @title }}}!!!"; var titleData = "Mr. User"; var expectedCustomToken = "1234"; var tokenExpander = new TokenExpander { RegEx = new Regex("{{{ @title }}}"), Renderer = (tokenString, queue, options, inferredModel) => { return((builder, context) => { builder.Append(expectedCustomToken); }); }, ExpandTokens = (s, baseOptions) => Tokenizer.Tokenize(titleData, new ParsingOptions()), Precedence = Precedence.Medium }; var model = new Dictionary <string, object>(); var parsingOptions = new ParsingOptions { TokenExpanders = new[] { tokenExpander } }; var result = Parser.Parse(baseTemplate, parsingOptions)(model); Assert.Equal($"Hello, {expectedCustomToken}Mr. User!!!", result); }
public void TokenExpanderPrecedenceIsRespected() { var baseTemplate = "Hello, {{{ title }}}!!!"; var titleData = "Mr. User"; var tokenExpander = new TokenExpander { RegEx = new Regex("{{{ title }}}"), ExpandTokens = (s, baseOptions) => Tokenizer.Tokenize(titleData, new ParsingOptions()), Precedence = Precedence.Low }; var model = new Dictionary <string, object> { ["title"] = "Mr. Bob" }; var parsingOptions = new ParsingOptions { TokenExpanders = new[] { tokenExpander } }; var result = Parser.Parse(baseTemplate, parsingOptions)(model); // Because we used Low Precedence, the token was evaluated as an Unescaped value and it was taken from the model. Assert.Equal($"Hello, Mr. Bob!!!", result); // Testing with Medium Precedence. It should use our token expander this time. tokenExpander.Precedence = Precedence.Medium; result = Parser.Parse(baseTemplate, parsingOptions)(model); Assert.Equal($"Hello, Mr. User!!!", result); }
public void Should_expand_utc_date_tokens() { const string input = "/my/path/{UtcDate:yyyy}/{UtcDate:MM}{Date:dd}"; var result = TokenExpander.Expand(input); var dt = DateTime.UtcNow; result.ShouldBe($"/my/path/{dt:yyyy}/{dt:MM}{dt:dd}"); }
public void TokenExpandersPropagateParseErrorsWithProperCharacterLocation() { var baseTemplate = "Welcome to our website!\r\nHello, {{{ @title }}} {{##each}}!!!"; var titleData = "Mr. {{## userId }}"; var titleSourceName = "Title"; var baseSourceName = "TestBase"; var tokenExpander = new TokenExpander { RegEx = new Regex("{{{ @title }}}"), ExpandTokens = (s, baseOptions) => Tokenizer.Tokenize(titleData, new ParsingOptions { SourceName = titleSourceName }), Precedence = Precedence.Medium }; var model = new Dictionary <string, object>(); var parsingOptions = new ParsingOptions { SourceName = baseSourceName, TokenExpanders = new[] { tokenExpander } }; // Checking to see that an exception does indeed throw Assert.Throws(typeof(AggregateException), () => Parser.Parse(baseTemplate, parsingOptions)(model)); try { Parser.Parse(baseTemplate, parsingOptions)(model); } catch (AggregateException e) { var baseTemplateErrorsCount = e.InnerExceptions.Count(ex => { var parseException = ex as IndexedParseException; return(parseException?.SourceName == baseSourceName && parseException?.LineNumber == 2); }); var titleTemplateErrorsCount = e.InnerExceptions.Count(ex => { var parseException = ex as IndexedParseException; return(parseException?.SourceName == titleSourceName && parseException?.LineNumber == 1 && parseException?.CharacterOnLine == 5); }); Assert.Equal(2, e.InnerExceptions.Count); Assert.Equal(1, baseTemplateErrorsCount); Assert.Equal(1, titleTemplateErrorsCount); } }
public void Should_log_unsupported_tokens() { var messages = new List <string>(); SelfLog.Enable(x => messages.Add(x)); const string input = "/my/path/{Myergen:yyyy}/{Meh:MM}"; var result = TokenExpander.Expand(input); // Result should be the unchanged input result.ShouldBe(input); // Ensure we wrote diagnostic logs messages.Count.ShouldBe(2); messages.ShouldAllBe(x => x.Contains("Unsupported token")); messages.ShouldContain(x => x.EndsWith("Myergen")); messages.ShouldContain(x => x.EndsWith("Meh")); }
public void ExpandedTokensShouldProcessComplexVariableStructures() { var baseTemplate = @"{{#each Company.ceo.products}}{{{ @content }}}{{/each}}"; var contentData = "<li>{{ name }} and {{version}} and has a CEO: {{../../last_name}}</li>"; var model = new Dictionary <string, object>(); var company = new Dictionary <string, object>(); model["Company"] = company; var ceo = new Dictionary <string, object>(); company["ceo"] = ceo; ceo["last_name"] = "Smith"; var products = Enumerable .Range(0, 3) .Select(k => new Dictionary <string, object> { ["name"] = "name " + k, ["version"] = "version " + k }) .ToArray(); ceo["products"] = products; var tokenExpander = new TokenExpander { RegEx = new Regex("{{{ @content }}}"), ExpandTokens = (s, baseOptions) => Tokenizer.Tokenize(contentData, new ParsingOptions()), Precedence = Precedence.Medium }; var parsingOptions = new ParsingOptions { TokenExpanders = new[] { tokenExpander } }; var result = Parser.Parse(baseTemplate, parsingOptions)(model); Assert.Equal("<li>name 0 and version 0 and has a CEO: Smith</li>" + "<li>name 1 and version 1 and has a CEO: Smith</li>" + "<li>name 2 and version 2 and has a CEO: Smith</li>", result); }
public void ExpandedTokensShouldBeRenderedByDefault() { var baseTemplate = "Hello, {{{ @title }}}!!!"; var titleData = "Mr. User"; var tokenExpander = new TokenExpander { RegEx = new Regex("{{{ @title }}}"), ExpandTokens = (s, baseOptions) => Tokenizer.Tokenize(titleData, new ParsingOptions()), Precedence = Precedence.Medium }; var model = new Dictionary <string, object>(); var parsingOptions = new ParsingOptions { TokenExpanders = new[] { tokenExpander } }; var result = Parser.Parse(baseTemplate, parsingOptions)(model); // The custom token will not be rendered by default. Assert.Equal("Hello, Mr. User!!!", result); }
public void ParserCanInferVariablesUsedInExpandedTokens() { var baseTemplate = "Welcome to our website!\r\nHello, {{{ @title }}}!!!"; var titleData = "Mr. {{ userId }}"; var tokenExpander = new TokenExpander { RegEx = new Regex("{{{ @title }}}"), ExpandTokens = (s, baseOptions) => Tokenizer.Tokenize(titleData, new ParsingOptions()), Precedence = Precedence.Medium }; var parsingOptions = new ParsingOptions { TokenExpanders = new[] { tokenExpander } }; var results = Parser.ParseWithModelInference(baseTemplate, parsingOptions); var expected = @"{""userId"" : ""userId_Value""}".EliminateWhitespace(); var actual = SerializeInferredModel(results.InferredModel).EliminateWhitespace(); Assert.Equal(expected, actual); }
public void ExpandedTokensShouldProcessVariables() { var baseTemplate = "Hello, {{{ @title }}}!!!"; var titleData = "Mr. {{ userId }}"; var tokenExpander = new TokenExpander { RegEx = new Regex("{{{ @title }}}"), ExpandTokens = (s, baseOptions) => Tokenizer.Tokenize(titleData, new ParsingOptions()), Precedence = Precedence.Medium }; var expectedName = "Ralph"; var model = new Dictionary <string, object> { ["userId"] = expectedName }; var parsingOptions = new ParsingOptions { TokenExpanders = new[] { tokenExpander } }; var result = Parser.Parse(baseTemplate, parsingOptions)(model); Assert.Equal($"Hello, Mr. {expectedName}!!!", result); }