public void It_Can_Render_LambdaTags_WithContext() { const string result = "1 Bar"; var settings = new RendererSettingsBuilder().BuildSettings(); var context = new Context( new { lambda = new Func <dynamic, string, object>((dyn, str) => $"1 {dyn.bar}"), bar = "Bar" }, settings, settings.RenderSettings); var stringRenderer = new StringRender(StreamWriter, settings.RendererPipeline); var sectionTokenRenderer = new SectionTokenRenderer(); sectionTokenRenderer.Write( stringRenderer, new SectionToken { SectionName = "lambda", Children = new List <MustacheToken> { } }, context); StreamWriter.Flush(); MemStream.Position = 0; var sr = new StreamReader(MemStream); var myStr = sr.ReadToEnd(); Assert.Equal(result, myStr); }
public void It_Can_Render_LambdaTags_UsingOriginalTemplate() { const string result = "<b>a b c Bar d e f</b>"; var settings = new RendererSettingsBuilder().BuildSettings(); var context = new Context( new { lambda = new Func <string, object>(str => $"<b>{str}</b>"), bar = "Bar" }, settings, settings.RenderSettings); var stringRenderer = new StringRender(StreamWriter, settings.RendererPipeline); var sectionTokenRenderer = new SectionTokenRenderer(); sectionTokenRenderer.Write( stringRenderer, new SectionToken { SectionName = "lambda", SectionContent = new StringSlice("a b c {{bar}} d e f") }, context); StreamWriter.Flush(); MemStream.Position = 0; var sr = new StreamReader(MemStream); var myStr = sr.ReadToEnd(); Assert.Equal(result, myStr); }
public void ItShouldCallHelperWhenExistsWithArgumentFromParent() { var writer = new StringWriter(); var settings = new RendererSettingsBuilder().BuildSettings(); var renderSettings = new RenderSettings(); var stringRenderer = new StringRender(writer, settings.RendererPipeline); var helpers = ImmutableDictionary.CreateBuilder <string, HelperRef>(); var helper = new Func <HelperContext, int, int, string>((helperContext, count, count2) => { return($"<{count}-{count2}>"); }); helpers.Add("MyHelper", new HelperRef(helper)); var tagRenderer = new HelperTagRenderer(helpers.ToImmutable()); var token = new HelperToken { Name = "MyHelper", Args = ImmutableArray.Create(new HelperArgument("Count"), new HelperArgument("Count2")) }; var context = new Context(new { Count = 10 }, settings, renderSettings) .Push(new { Count2 = 20 }); tagRenderer.Write(stringRenderer, token, context); var res = writer.ToString(); Assert.Equal("<10-20>", res); }
/// <inheritdoc/> protected override void Write(StringRender renderer, InterpolationToken obj, Context context) { var value = context.Lookup(obj.Content.ToString()); var functionValueDynamic = value as Func <dynamic, object>; var functionValue = value as Func <object>; if (functionValueDynamic != null || functionValue != null) { object functionResult = functionValueDynamic != null?functionValueDynamic.Invoke(context.View) : functionValue.Invoke(); var resultString = ConvertToStringInCulture(functionResult, context.RenderSettings.CultureInfo); if (resultString.Contains("{{")) { renderer.Render(context.RendererSettings.Parser.Parse(resultString), context); return; } value = resultString; } if (!context.RenderSettings.SkipHtmlEncoding && obj.EscapeResult && value != null) { value = context.RendererSettings.EncodingFuction(ConvertToStringInCulture(value, context.RenderSettings.CultureInfo)); } if (obj.Indent > 0) { renderer.Write(' ', obj.Indent); } renderer.Write(ConvertToStringInCulture(value, context.RenderSettings.CultureInfo)); }
public void ItShouldApplyTheCultureOfTheRenderer() { var writer = new StringWriter(); var settings = new RendererSettingsBuilder().BuildSettings(); var renderSettings = new RenderSettings { CultureInfo = new CultureInfo("ru-RU") }; var stringRenderer = new StringRender(writer, settings.RendererPipeline); var helpers = ImmutableDictionary.CreateBuilder <string, HelperRef>(); var helper = new Func <HelperContext, decimal>((helperContext) => { return(helperContext.Lookup <decimal>("Count")); }); helpers.Add("MyHelper", new HelperRef(helper)); var tagRenderer = new HelperTagRenderer(helpers.ToImmutable()); var token = new HelperToken { Name = "MyHelper", Args = ImmutableArray <HelperArgument> .Empty }; var context = new Context(new { Count = 1.21m }, settings, renderSettings); tagRenderer.Write(stringRenderer, token, context); var res = writer.ToString(); Assert.Equal("1,21", res); }
public void ItShouldRenderAllowHelpersWithNoArguments() { var writer = new StringWriter(); var settings = new RendererSettingsBuilder().BuildSettings(); var renderSettings = new RenderSettings(); var stringRenderer = new StringRender(writer, settings.RendererPipeline); var helpers = ImmutableDictionary.CreateBuilder <string, HelperRef>(); var helper = new Func <HelperContext, string>((helperContext) => { return($"<{helperContext.Lookup<int>("Count")}>"); }); helpers.Add("MyHelper", new HelperRef(helper)); var tagRenderer = new HelperTagRenderer(helpers.ToImmutable()); var token = new HelperToken { Name = "MyHelper", Args = ImmutableArray <HelperArgument> .Empty }; var context = new Context(new { Count = 10 }, settings, renderSettings); tagRenderer.Write(stringRenderer, token, context); var res = writer.ToString(); Assert.Equal("<10>", res); }
public void ItShouldHandleNullReturnFromHelper() { var writer = new StringWriter(); var settings = new RendererSettingsBuilder().BuildSettings(); var renderSettings = new RenderSettings(); var stringRenderer = new StringRender(writer, settings.RendererPipeline); var helpers = ImmutableDictionary.CreateBuilder <string, HelperRef>(); var helper = new Func <HelperContext, object>((helperContext) => { return(null); }); helpers.Add("MyHelper", new HelperRef(helper)); var tagRenderer = new HelperTagRenderer(helpers.ToImmutable()); var token = new HelperToken { Name = "MyHelper", Args = ImmutableArray <HelperArgument> .Empty }; var context = new Context(new { Count = 1.21m }, settings, renderSettings); tagRenderer.Write(stringRenderer, token, context); var res = writer.ToString(); Assert.Equal("", res); }
public void ItShouldRenderWhenTypesNotMatchCanBeConverted() { var writer = new StringWriter(); var settings = new RendererSettingsBuilder().BuildSettings(); var renderSettings = new RenderSettings(); var stringRenderer = new StringRender(writer, settings.RendererPipeline); var helpers = ImmutableDictionary.CreateBuilder <string, HelperRef>(); var helper = new Func <HelperContext, int, string>((helperContext, count) => { return($"<{count}>"); }); helpers.Add("MyHelper", new HelperRef(helper)); var tagRenderer = new HelperTagRenderer(helpers.ToImmutable()); var token = new HelperToken { Name = "MyHelper", Args = ImmutableArray.Create(new HelperArgument("Count")) }; var context = new Context(new { Count = "10" }, settings, renderSettings); tagRenderer.Write(stringRenderer, token, context); var res = writer.ToString(); Assert.Equal("<10>", res); }
public void It_Ignores_Tags_It_Cant_Find() { const string result = ""; var setingsBuilder = new RendererSettingsBuilder(); setingsBuilder.SetPartialTemplateLoader(new DictionaryLoader(new Dictionary<string, string>() { { "bar", "{{bar}}" } })); var settings = setingsBuilder.BuildSettings(); var context = new Context( new { bar = "Bar" }, settings, settings.RenderSettings); var stringRenderer = new StringRender(StreamWriter, settings.RendererPipeline); var partialTokenRenderer = new PartialTokenRenderer(); partialTokenRenderer.Write( stringRenderer, new PartialToken { Content = new StringSlice("foo"), }, context); StreamWriter.Flush(); MemStream.Position = 0; var sr = new StreamReader(MemStream); var myStr = sr.ReadToEnd(); Assert.Equal(result, myStr); }
/// <inheritdoc/> protected override async Task WriteAsync(StringRender renderer, InterpolationToken obj, Context context) { var value = context.Lookup(obj.Content.ToString()); var functionValueDynamic = value as Func <dynamic, object>; var functionValue = value as Func <object>; if (functionValueDynamic != null || functionValue != null) { object functionResult = functionValueDynamic != null?functionValueDynamic.Invoke(context.View) : functionValue.Invoke(); var resultString = functionResult.ToString(); if (resultString.Contains("{{")) { await renderer.RenderAsync(context.RendererSettings.Parser.Parse(resultString), context); return; } value = resultString; } if (obj.EscapeResult && value != null) { value = WebUtility.HtmlEncode(value.ToString()); } if (obj.Indent > 0) { renderer.Write(' ', obj.Indent); } renderer.Write(value?.ToString()); }
public void It_Can_Render_InterpolationTag_Escaped_SimpleValue() { const string result = "A & B"; var settings = new RendererSettingsBuilder().BuildSettings(); var context = new Context( new { foo = "A & B" }, settings, settings.RenderSettings); var stringRenderer = new StringRender(StreamWriter, settings.RendererPipeline); var interpolationTokenRenderer = new InterpolationTokenRenderer(); interpolationTokenRenderer.Write( stringRenderer, new InterpolationToken { Content = new StringSlice("foo"), EscapeResult = true, }, context); StreamWriter.Flush(); MemStream.Position = 0; var sr = new StreamReader(MemStream); var myStr = sr.ReadToEnd(); Assert.Equal(result, myStr); }
public void It_Can_Render_InterpolationTag_Lambda_Tag() { const string result = "Bar"; var settings = new RendererSettingsBuilder().BuildSettings(); var context = new Context( new { foo = new Func <string>(() => "{{bar}}"), bar = "Bar" }, settings, settings.RenderSettings); var stringRenderer = new StringRender(StreamWriter, settings.RendererPipeline); var interpolationTokenRenderer = new InterpolationTokenRenderer(); interpolationTokenRenderer.Write( stringRenderer, new InterpolationToken { Content = new StringSlice("foo"), EscapeResult = true, }, context); StreamWriter.Flush(); MemStream.Position = 0; var sr = new StreamReader(MemStream); var myStr = sr.ReadToEnd(); Assert.Equal(result, myStr); }
public void It_Can_Render_LiteralTags() { StringSlice content = new StringSlice("I'm a literal tag"); var settings = new RendererSettingsBuilder().BuildSettings(); var context = new Context( new { }, settings, settings.RenderSettings); var stringRenderer = new StringRender(StreamWriter, settings.RendererPipeline); var rawTokenRenderer = new LiteralTokenRenderer(); rawTokenRenderer.Write( stringRenderer, new LiteralToken() { Content = new[] { content } }, context); StreamWriter.Flush(); MemStream.Position = 0; var sr = new StreamReader(MemStream); var myStr = sr.ReadToEnd(); Assert.Equal(content.ToString(), myStr); }
/// <inheritdoc/> public string Render(string template, object view, IDictionary <string, string> partials, RenderSettings settings) { var loadedTemplate = RendererSettings.TemplateLoader.Load(template); if (loadedTemplate == null) { throw new UnknownTemplateException("No template was found with the name '" + template + "'"); } var document = RendererSettings.Parser.Parse(loadedTemplate, RendererSettings.DefaultTags, pipeline: RendererSettings.ParserPipeline); var textwriter = new StringWriter(); var renderer = new StringRender(textwriter, RendererSettings.RendererPipeline, RendererSettings.MaxRecursionDepth); var partialsLoader = RendererSettings.PartialTemplateLoader; if (partials != null && partials.Keys.Count > 0) { partialsLoader = new CompositeLoader(new DictionaryLoader(partials), RendererSettings.PartialTemplateLoader); } renderer.Render(document, new Context(view, RendererSettings, partialsLoader, settings ?? RendererSettings.RenderSettings)); renderer.Writer.Flush(); return(((StringWriter)renderer.Writer).ToString()); }
public void It_Renders_Inverted_Tags_When_Falsey_Bool() { const string result = "I'm false"; var settings = new RendererSettingsBuilder().BuildSettings(); var context = new Context( new { check = false }, settings, settings.RenderSettings); var stringRenderer = new StringRender(StreamWriter, settings.RendererPipeline); var sectionTokenRenderer = new InvertedSectionTokenRenderer(); sectionTokenRenderer.Write( stringRenderer, new InvertedSectionToken { SectionName = "check", Children = new List<MustacheToken> { new LiteralToken { Content = new[] { new StringSlice("I'm false") } } } }, context); StreamWriter.Flush(); MemStream.Position = 0; var sr = new StreamReader(MemStream); var myStr = sr.ReadToEnd(); Assert.Equal(result, myStr); }
public void ItShouldRenderNothingWhenHelperDoesntExist() { var writer = new StringWriter(); var settings = new RendererSettingsBuilder().BuildSettings(); var renderSettings = new RenderSettings(); var stringRenderer = new StringRender(writer, settings.RendererPipeline); var helpers = ImmutableDictionary.Create <string, HelperRef>(); var tagRenderer = new HelperTagRenderer(helpers); var token = new HelperToken { Name = "MyHelper", Args = ImmutableArray <HelperArgument> .Empty }; var context = new Context(new { Count = 10 }, settings, renderSettings); tagRenderer.Write(stringRenderer, token, context); var res = writer.ToString(); Assert.Equal("", res); }
/// <inheritdoc/> protected override async Task WriteAsync(StringRender renderer, SectionToken obj, Context context) { var value = context.Lookup(obj.SectionName); if (!context.IsTruthyValue(value)) { return; } if (value is IEnumerable && !context.RendererSettings.SectionBlacklistTypes.Any(x => x.IsInstanceOfType(value))) { var arrayValue = value as IEnumerable; foreach (var v in arrayValue) { await renderer.RenderAsync(obj, context.Push(v)); } } else if (value is IEnumerator) { var enumeratorValue = value as IEnumerator; while (enumeratorValue.MoveNext()) { await renderer.RenderAsync(obj, context.Push(enumeratorValue.Current)); } enumeratorValue.Reset(); } else if (LambdaTypes.Contains(value.GetType())) { var sectionContent = obj.SectionContent.ToString(); switch (value) { case Func <dynamic, string, object> func: value = func(context.View, sectionContent); break; case Func <string, object> func: value = func(sectionContent); break; case Func <dynamic, string, Func <string, string>, object> func: value = func(context.View, sectionContent, RenderInContext(context, obj.Tags)); break; case Func <string, Func <string, string>, object> func: value = func(sectionContent, RenderInContext(context, obj.Tags)); break; } var valueString = value?.ToString() ?? string.Empty; renderer.Render(context.RendererSettings.Parser.Parse(value.ToString(), obj.Tags), context); } else if (value is IDictionary || value != null) { await renderer.RenderAsync(obj, context.Push(value)); } }
/// <inheritdoc/> protected override async Task WriteAsync(StringRender renderer, InvertedSectionToken obj, Context context) { var value = context.Lookup(obj.SectionName); if (!context.IsTruthyValue(value)) { await renderer.RenderAsync(obj, context); } }
/// <inheritdoc/> protected override void Write(StringRender renderer, InvertedSectionToken obj, Context context) { var value = context.Lookup(obj.SectionName); if (!context.IsTruthyValue(value)) { renderer.Render(obj, context); } }
protected override void Write(StringRender renderer, HelperToken obj, Context context) { if (renderer is null) { throw new ArgumentNullException(nameof(renderer)); } if (obj is null) { throw new ArgumentNullException(nameof(obj)); } if (context is null) { throw new ArgumentNullException(nameof(context)); } if (_helperCache.TryGetValue(obj.Name, out var helper)) { var helperContext = new HelperContext(context); var args = obj.Args; var argumentTypes = helper.ArgumentTypes; if ((argumentTypes.Length - 1) == args.Length) { var arr = new object[args.Length + 1]; arr[0] = helperContext; for (var i = 0; i < args.Length; i++) { var arg = args[i].ShouldAttemptContextLoad ? context.Lookup(args[i].Value) : args[i].Value; arg = TryConvertTypeIfRequired(arg, args[i].Value, argumentTypes[i + 1]); if (arg is null) { return; } arr[i + 1] = arg; } var result = helper.Delegate.Method.Invoke(helper.Delegate.Target, arr); if (result is string str) { renderer.Write(str); } else if (result is object) { renderer.Write(Convert.ToString(result, context.RenderSettings.CultureInfo)); } } } }
public void It_Can_Render_IEnumerables_As_Lists() { const string result = "1 Bar\n2 Bar\n3 Bar\n4 Bar\n"; var settings = new RendererSettingsBuilder().BuildSettings(); var context = new Context( new { list = new[] { new { a = 1 }, new { a = 2 }, new { a = 3 }, new { a = 4 } }, bar = "Bar" }, settings, settings.RenderSettings); var stringRenderer = new StringRender(StreamWriter, settings.RendererPipeline); var sectionTokenRenderer = new SectionTokenRenderer(); sectionTokenRenderer.Write( stringRenderer, new SectionToken { SectionName = "list", Children = new List <MustacheToken> { new InterpolationToken { Content = new StringSlice("a") }, new LiteralToken { Content = new [] { new StringSlice(" ") } }, new InterpolationToken { Content = new StringSlice("bar") }, new LiteralToken { Content = new [] { new StringSlice("\n") } }, } }, context); StreamWriter.Flush(); MemStream.Position = 0; var sr = new StreamReader(MemStream); var myStr = sr.ReadToEnd(); Assert.Equal(result, myStr); }
/// <inheritdoc/> protected override void Write(StringRender renderer, LiteralToken obj, Context context) { for (var i = 0; i < obj.Content.Length; i++) { var item = obj.Content[i]; if (obj.Indent > 0 && !item.IsEmptyOrWhitespace()) { renderer.Write(' ', obj.Indent); } renderer.Write(ref item); } }
/// <inheritdoc/> protected override void Write(StringRender renderer, PartialToken obj, Context context) { var partialName = obj.Content; string template = null; if (context.PartialLoader != null) { template = context.PartialLoader.Load(partialName.ToString()); } if (template != null) { renderer.Render(context.RendererSettings.Parser.Parse(template, lineIndent: obj.LineIndent), context); } }
/// <inheritdoc/> protected override async Task WriteAsync(StringRender renderer, PartialToken obj, Context context) { var partialName = obj.Content; string template = null; if (context.PartialLoader != null) { template = await context.PartialLoader.LoadAsync(partialName.ToString()); } if (template != null) { await renderer.RenderAsync(context.RendererSettings.Parser.Parse(template, lineIndent: obj.LineIndent), context); } }
/// <inheritdoc /> protected override void Write(StringRender renderer, InterpolationToken obj, Context context) { var content = obj.Content.ToString(); string format = null; var pos = content.IndexOf(':'); if (pos > 0) { format = content.Substring(pos + 1); content = content.Substring(0, pos); } var value = context.Lookup(content); var functionValueDynamic = value as Func <dynamic, object>; var functionValue = value as Func <object>; if (functionValueDynamic != null || functionValue != null) { object functionResult = functionValueDynamic != null?functionValueDynamic.Invoke(context.View) : functionValue.Invoke(); var resultString = functionResult.ToString(); if (resultString.Contains("{{")) { renderer.Render(context.RendererSettings.Parser.Parse(resultString), context); return; } value = resultString; } var formattedValue = ApplyFormat(value, format); if (!context.RenderSettings.SkipHtmlEncoding && obj.EscapeResult && value != null) { formattedValue = WebUtility.HtmlEncode(formattedValue); } if (obj.Indent > 0) { renderer.Write(' ', obj.Indent); } renderer.Write(formattedValue); }
public void It_Can_Render_IEnumerators() { const string result = "a b c d e f g "; var settings = new RendererSettingsBuilder().BuildSettings(); // Get Enumerator doesn't exist on string (netstandard 1.3) // will be added back in netstandard 2.0 var enumerator = "abcdefg".ToCharArray().GetEnumerator(); var context = new Context( new { list = enumerator, bar = "Bar" }, settings, settings.RenderSettings); var stringRenderer = new StringRender(StreamWriter, settings.RendererPipeline); var sectionTokenRenderer = new SectionTokenRenderer(); sectionTokenRenderer.Write( stringRenderer, new SectionToken { SectionName = "list", Children = new List <MustacheToken> { new InterpolationToken { Content = new StringSlice(".") }, new LiteralToken { Content = new [] { new StringSlice(" ") } }, } }, context); StreamWriter.Flush(); MemStream.Position = 0; var sr = new StreamReader(MemStream); var myStr = sr.ReadToEnd(); Assert.Equal(result, myStr); }
/// <inheritdoc/> protected override async Task WriteAsync(StringRender renderer, SectionToken obj, Context context) { var value = context.Lookup(obj.SectionName); if (!context.IsTruthyValue(value)) { return; } if (value is IEnumerable && !context.RendererSettings.SectionBlacklistTypes.Any(x => x.IsInstanceOfType(value))) { var arrayValue = value as IEnumerable; foreach (var v in arrayValue) { await renderer.RenderAsync(obj, context.Push(v)); } } else if (value is IEnumerator) { var enumeratorValue = value as IEnumerator; while (enumeratorValue.MoveNext()) { await renderer.RenderAsync(obj, context.Push(enumeratorValue.Current)); } enumeratorValue.Reset(); } else if (value is Func <dynamic, string, object> || value is Func <string, object> ) { var functionDynamicValue = value as Func <dynamic, string, object>; var functionStringValue = value as Func <string, object>; var sectionContent = obj.SectionContent; value = functionDynamicValue != null ? functionDynamicValue.Invoke(context.View, sectionContent.ToString()) : functionStringValue.Invoke(sectionContent.ToString()); await renderer.RenderAsync(context.RendererSettings.Parser.Parse(value.ToString(), obj.Tags), context); } else if (value is IDictionary || value != null) { await renderer.RenderAsync(obj, context.Push(value)); } }
private Func <string, string> RenderInContext(Context context, Classes.Tags tags) { return((str) => { if (!str.Contains(tags.StartTag)) { return str; } using var writer = new StringWriter(); var blockRenderer = new StringRender(writer, context.RendererSettings.RendererPipeline); var parsed = context.RendererSettings.Parser.Parse(str, tags); blockRenderer.Render(parsed, context); return writer.ToString(); }); }
private Func <string, Task <string> > RenderInContextAsync(Context context, Classes.Tags tags) { return(async(str) => { if (!str.Contains(tags.StartTag)) { return str; } using var writer = new StringWriter(); var blockRenderer = new StringRender(writer, context.RendererSettings.RendererPipeline); var parsed = context.RendererSettings.Parser.Parse(str, tags); await blockRenderer.RenderAsync(parsed, context).ConfigureAwait(false); return writer.ToString(); }); }
public void It_Can_Render_LambdaTags_WithoutContext() { const string result = "1"; var settings = new RendererSettingsBuilder().BuildSettings(); var context = new Context( new { lambda = new Func <string, object>((str) => 1), bar = "Bar" }, settings, settings.RenderSettings); var stringRenderer = new StringRender(StreamWriter, settings.RendererPipeline); var sectionTokenRenderer = new SectionTokenRenderer(); sectionTokenRenderer.Write( stringRenderer, new SectionToken { SectionName = "lambda", Children = new List <MustacheToken> { new InterpolationToken { Content = new StringSlice(".") }, new LiteralToken { Content = new [] { new StringSlice(" ") } }, } }, context); StreamWriter.Flush(); MemStream.Position = 0; var sr = new StreamReader(MemStream); var myStr = sr.ReadToEnd(); Assert.Equal(result, myStr); }