Permalink
Browse files

Support for Compiled Templates.

Adding NUnit tests that call the official mustache specs (https://github.com/mustache/spec).

Also pulled in newtonsoft.JSON.

Compiled recursive templates will require more thought.  Strategy will probably be to
>> 1. Compile the templates into a separate block that is jumped to, as they are referenced.
>> 2. Jump into those blocks when evaluated.
>> 3. Do the max recursion check there also."
  • Loading branch information...
1 parent e080864 commit 6f0cc1a6416802cd50d3fa007ac1429bad7b5649 @jonwingfield jonwingfield committed Jun 23, 2013
Showing with 59,861 additions and 28 deletions.
  1. BIN Lib/JsonClassGenerator/System.Data.Entity.Design.PluralizationServices.dll
  2. BIN Lib/JsonClassGenerator/Xamasoft.JsonClassGenerator.dll
  3. BIN Lib/JsonClassGenerator/Xamasoft.JsonClassGenerator.pdb
  4. +287 −0 Nustache.Core.Tests/Compiled_Templates_Support.cs
  5. +180 −0 Nustache.Core.Tests/Describe_Compiled_Template_Data_Types.cs
  6. +53 −0 Nustache.Core.Tests/Describe_Compound_Expression_Enumerator.cs
  7. +44 −0 Nustache.Core.Tests/Mustache_Spec/Generate_Classes_from_JSON.cs
  8. +127 −0 Nustache.Core.Tests/Mustache_Spec/MustacheSpec.cs
  9. +105 −0 Nustache.Core.Tests/Mustache_Spec/Official_Specs.cs
  10. +3 −0 Nustache.Core.Tests/Mustache_Spec/examples/Generated Code!!.txt
  11. +198 −0 Nustache.Core.Tests/Mustache_Spec/examples/JsonClassHelper.cs
  12. +102 −0 Nustache.Core.Tests/Mustache_Spec/examples/delimiters.cs
  13. +548 −0 Nustache.Core.Tests/Mustache_Spec/examples/interpolation.cs
  14. +336 −0 Nustache.Core.Tests/Mustache_Spec/examples/inverted.cs
  15. +100 −0 Nustache.Core.Tests/Mustache_Spec/examples/partials.cs
  16. +442 −0 Nustache.Core.Tests/Mustache_Spec/examples/sections.cs
  17. +28 −1 Nustache.Core.Tests/Nustache.Core.Tests.csproj
  18. +4 −0 Nustache.Core.Tests/packages.config
  19. +31 −0 Nustache.Core/Block.cs
  20. +19 −0 Nustache.Core/Compilation/CompilationException.cs
  21. +73 −0 Nustache.Core/Compilation/CompoundExpression.cs
  22. +216 −0 Nustache.Core/CompileContext.cs
  23. +7 −0 Nustache.Core/EndSection.cs
  24. +16 −1 Nustache.Core/InvertedBlock.cs
  25. +7 −0 Nustache.Core/LiteralText.cs
  26. +5 −1 Nustache.Core/Nustache.Core.csproj
  27. +4 −0 Nustache.Core/Part.cs
  28. +27 −0 Nustache.Core/Section.cs
  29. +40 −0 Nustache.Core/Template.cs
  30. +7 −0 Nustache.Core/TemplateInclude.cs
  31. +60 −0 Nustache.Core/ValueGetter.cs
  32. +115 −24 Nustache.Core/ValueGetterFactory.cs
  33. +19 −0 Nustache.Core/VariableReference.cs
  34. +1 −0 TODO.txt
  35. +3 −0 nustache/app.config
  36. +2 −1 nustache/nustache.csproj
  37. BIN packages/Newtonsoft.Json.5.0.6/lib/net20/Newtonsoft.Json.dll
  38. +8,893 −0 packages/Newtonsoft.Json.5.0.6/lib/net20/Newtonsoft.Json.xml
  39. BIN packages/Newtonsoft.Json.5.0.6/lib/net35/Newtonsoft.Json.dll
  40. +8,030 −0 packages/Newtonsoft.Json.5.0.6/lib/net35/Newtonsoft.Json.xml
  41. BIN packages/Newtonsoft.Json.5.0.6/lib/net40/Newtonsoft.Json.dll
  42. +8,305 −0 packages/Newtonsoft.Json.5.0.6/lib/net40/Newtonsoft.Json.xml
  43. BIN packages/Newtonsoft.Json.5.0.6/lib/net45/Newtonsoft.Json.dll
  44. +8,305 −0 packages/Newtonsoft.Json.5.0.6/lib/net45/Newtonsoft.Json.xml
  45. BIN packages/Newtonsoft.Json.5.0.6/lib/netcore45/Newtonsoft.Json.dll
  46. +7,829 −0 packages/Newtonsoft.Json.5.0.6/lib/netcore45/Newtonsoft.Json.xml
  47. BIN packages/Newtonsoft.Json.5.0.6/lib/portable-net40+sl4+wp7+win8/Newtonsoft.Json.dll
  48. +7,457 −0 packages/Newtonsoft.Json.5.0.6/lib/portable-net40+sl4+wp7+win8/Newtonsoft.Json.xml
  49. BIN packages/Newtonsoft.Json.5.0.6/lib/portable-net45+wp80+win8/Newtonsoft.Json.dll
  50. +7,829 −0 packages/Newtonsoft.Json.5.0.6/lib/portable-net45+wp80+win8/Newtonsoft.Json.xml
  51. +4 −0 packages/repositories.config
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,287 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using System.IO;
+using Nustache.Core.Compilation;
+
+namespace Nustache.Core.Tests
+{
+ public class TestObject
+ {
+ public string TestString { get; set; }
+ public bool TestBool { get; set; }
+ public SubObject Sub { get; set; }
+ public List<SubObject> Items { get; set; }
+ public string[] Strings { get; set; }
+ public string OuterOnly { get; set; }
+ }
+
+ public class SubObject
+ {
+ public string SubText { get; set; }
+ public bool TestBool { get; set; }
+
+ public SubObject Sub { get; set; }
+ }
+
+ [TestFixture]
+ public class Compiled_Templates_Support
+ {
+ [Test]
+ public void Literals()
+ {
+ var template = Template("This is plain text");
+ var compiled = template.Compile<object>(null);
+ Assert.AreEqual("This is plain text", compiled(null));
+ }
+
+ [Test]
+ public void Comments()
+ {
+ var template = Template("This is {{!comment}}plain text");
+ var compiled = template.Compile<object>(null);
+ Assert.AreEqual("This is plain text", compiled(null));
+ }
+
+ [Test]
+ public void Variables()
+ {
+ var template = Template("A template with {{TestString}} and {{TestBool}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { TestString = "Hello", TestBool = true });
+ Assert.AreEqual("A template with Hello and True", result);
+ }
+
+ [Test]
+ public void Html_Escaping()
+ {
+ var template = Template("A template with {{TestString}} and {{TestBool}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { TestString = "<Hello> \"", TestBool = true });
+ Assert.AreEqual("A template with &lt;Hello&gt; &quot; and True", result);
+ }
+
+ [Test]
+ public void Nested_Templates()
+ {
+ var template = Template("A template with {{#Sub}} {{SubText}} here {{/Sub}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { Sub = new SubObject { SubText = "Blah" } });
+ Assert.AreEqual("A template with Blah here ", result);
+ }
+
+ [Test]
+ public void Null_Nested_Template()
+ {
+ var template = Template("A template with {{#Sub}} {{SubText}} here {{/Sub}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { Sub = null });
+ Assert.AreEqual("A template with ", result);
+ }
+
+ [Test]
+ public void Dotted_Variable_Names()
+ {
+ var template = Template("A template with {{Sub.SubText}} here");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { Sub = new SubObject { SubText = "Blah" } });
+ Assert.AreEqual("A template with Blah here", result);
+ }
+
+ [Test]
+ public void Boolean_Sections()
+ {
+ var template = Template("A template with {{#TestBool}}data here{{/TestBool}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { TestBool = false });
+ Assert.AreEqual("A template with ", result);
+ }
+
+ [Test]
+ public void Boolean_Nested_Sections()
+ {
+ var template = Template("A template with {{#Sub.TestBool}}data here{{/Sub.TestBool}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { Sub = new SubObject { TestBool = false } });
+ Assert.AreEqual("A template with ", result);
+ }
+
+ [Test]
+ public void Enumerable_Sections()
+ {
+ var template = Template("A template with{{#Items}} {{SubText}} {{/Items}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject
+ {
+ Items = new List<SubObject>
+ {
+ new SubObject { SubText = "a" },
+ new SubObject { SubText = "b" },
+ new SubObject { SubText = "c" },
+ }
+ });
+ Assert.AreEqual("A template with a b c ", result);
+ }
+
+ [Test]
+ public void Null_Enumerable_Values()
+ {
+ var template = Template("A template with{{#Items}} {{SubText}} {{/Items}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { Items = null });
+ Assert.AreEqual("A template with", result);
+ }
+
+ [Test]
+ public void Multiple_Levels_of_Enumerable_Sections()
+ {
+ var template = Template(
+ @"A template with
+
+{{#Items}}
+
+{{SubText}}
+{{#Sub}}
+{{TestBool}}{{SubText}}
+ {{#Sub}}
+{{SubText}}
+ {{/Sub}}
+{{/Sub}}
+
+{{/Items}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject
+ {
+ Items = new List<SubObject>
+ {
+ new SubObject { SubText = "a" },
+ new SubObject { Sub = new SubObject {
+ SubText = "Blah",
+ TestBool = true,
+ Sub = new SubObject {
+ SubText = "Third",
+ TestBool = false,
+ }
+ } },
+ new SubObject { SubText = "c" },
+ }
+ });
+ Assert.AreEqual("A template witha TrueBlahThirdc ", result.Replace("\r\n", ""));
+ }
+
+ [Test]
+ public void Null_Values()
+ {
+ var template = Template("A template with {{TestString}} and {{TestBool}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { TestString = null });
+ Assert.AreEqual("A template with and False", result);
+ }
+
+ [Test]
+ public void Inverted_Sections_that_Keep_Outer_Context()
+ {
+ var template = Template("A template with {{#Sub}}Failed{{/Sub}}{{^Sub}}{{TestBool}}{{/Sub}} trailing");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { Sub = null, TestBool = true });
+ Assert.AreEqual("A template with True trailing", result);
+ }
+
+ [Test]
+ public void Nested_Inverted_Sections()
+ {
+ var template = Template("Value is {{^Sub.Sub.TestBool}}Here{{/Sub.Sub.TestBool}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { Sub = new SubObject { Sub = new SubObject { TestBool = false } } });
+ Assert.AreEqual("Value is Here", result);
+ }
+
+ [Test]
+ public void Combined_Inverted_Sections()
+ {
+ var template = Template("{{#Sub.Sub}}Here{{^TestBool}}, but is it?{{/TestBool}}{{/Sub.Sub}}");
+ var compiled = template.Compile<TestObject>(null);
+ var data = new TestObject { Sub = new SubObject { Sub = new SubObject { TestBool = false } } };
+ var result = compiled(data);
+ Assert.AreEqual("Here, but is it?", result);
+ }
+
+ [Test]
+ public void Partials()
+ {
+ var template = Template("{{>text}} after partial");
+ var compiled = template.Compile<TestObject>(name =>
+ name == "text" ? Template("{{TestString}} {{#Sub.TestBool}}I am in you{{/Sub.TestBool}}") : null);
+ var result = compiled(new TestObject { TestString = "a", Sub = new SubObject { TestBool = true } });
+ Assert.AreEqual("a I am in you after partial", result);
+ }
+
+ [Test]
+ public void Internal_Templates_AKA_Inline_Partials()
+ {
+ var template = Template(
+@"{{<text}}in partial {{Sub.SubText}} {{/text}}
+
+{{>text}} after partial
+");
+
+ var compiled = template.Compile<TestObject>(null);
+
+ var result = compiled(new TestObject { Sub = new SubObject { SubText = "Byaaah" } });
+ Assert.AreEqual("in partial Byaaah after partial", result.Replace("\r\n", ""));
+ }
+
+ [Test]
+ public void Missing_Partials()
+ {
+ var template = Template("{{>text}} after partial");
+ var compiled = template.Compile<TestObject>(name => null);
+ var result = compiled(null);
+ Assert.AreEqual(" after partial", result);
+ }
+
+ [Test]
+ public void Implicit_Iterators()
+ {
+ var template = Template("A template with{{#Strings}} {{.}} {{/Strings}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject
+ {
+ Strings = new [] { "a", "b", "c" },
+ });
+ Assert.AreEqual("A template with a b c ", result);
+ }
+
+ [Test]
+ public void Nested_Sections_with_outer_context_available()
+ {
+ var template = Template("A template with {{#Sub}} {{OuterOnly}} here {{/Sub}}");
+ var compiled = template.Compile<TestObject>(null);
+ var result = compiled(new TestObject { Sub = new SubObject(), OuterOnly = "Blah" });
+ Assert.AreEqual("A template with Blah here ", result);
+ }
+
+ [Test, ExpectedException(ExpectedException=typeof(CompilationException),
+ ExpectedMessage="Could not find TestString1\nOn object: TestObject")]
+ public void Missing_Properties()
+ {
+ var template = Template("A template with {{TestString1}} and {{TestBool}}");
+ var compiled = template.Compile<TestObject>(null);
+ compiled(new TestObject { TestString = "Hello", TestBool = true });
+ }
+
+ private Func<T, string> Compiled<T>(string text) where T : class
+ {
+ return Template(text).Compile<T>(null);
+ }
+
+ private Template Template(string text)
+ {
+ var template = new Template();
+ template.Load(new StringReader(text));
+ return template;
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit 6f0cc1a

Please sign in to comment.