Пример #1
0
        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);
        }
Пример #2
0
        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}");
        }
Пример #4
0
        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"));
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);
        }