Permalink
Browse files

Added support for "unless" attribute and special node for use instead…

… of negating if statements
  • Loading branch information...
1 parent ef48a7c commit ddd19511d50bf0ce26da6414a6ce05935e196680 @RobertTheGrey RobertTheGrey committed Jun 1, 2012
Showing with 275 additions and 8 deletions.
  1. +1 −0 src/Spark.JsTests/CodeConstructsTests.html
  2. +8 −0 src/Spark.JsTests/Views/CodeConstructs/_Conditionals.spark
  3. +18 −0 src/Spark.Python.Tests/PythonViewCompilerTests.cs
  4. +3 −0 src/Spark.Python/Compiler/ChunkVisitors/GeneratedCodeVisitor.cs
  5. +18 −0 src/Spark.Ruby.Tests/RubyViewCompilerTests.cs
  6. +3 −0 src/Spark.Ruby/Compiler/ChunkVisitors/GeneratedCodeVisitor.cs
  7. +38 −0 src/Spark.Tests/Compiler/CSharpViewCompilerTester.cs
  8. +38 −0 src/Spark.Tests/Compiler/VisualBasicViewCompilerTester.cs
  9. +3 −1 src/Spark.Tests/PrefixSupportTester.cs
  10. +5 −0 src/Spark.Tests/Spark.Tests.Views/Home/UnlessAttributeWorksOnSpecialNodes.spark
  11. +8 −0 src/Spark.Tests/Spark.Tests.Views/Home/unlessattribute.spark
  12. +12 −0 src/Spark.Tests/Spark.Tests.Views/Home/unlesselement.spark
  13. +8 −0 src/Spark.Tests/Spark.Tests.Views/Prefix/conditional-attributes.spark
  14. +10 −0 src/Spark.Tests/Spark.Tests.csproj
  15. +48 −1 src/Spark.Tests/SparkViewFactoryTester.cs
  16. +17 −0 src/Spark.Tests/Visitors/ConditionalAttributeVisitorTester.cs
  17. +10 −2 src/Spark/Compiler/CSharp/ChunkVisitors/GeneratedCodeVisitor.cs
  18. +2 −1 src/Spark/Compiler/Chunk.cs
  19. +7 −0 src/Spark/Compiler/Javascript/ChunkVisitors/JavascriptGeneratedCodeVisitor.cs
  20. +11 −0 src/Spark/Compiler/NodeVisitors/ChunkBuilderVisitor.cs
  21. +2 −2 src/Spark/Compiler/NodeVisitors/ConditionalAttributeVisitor.cs
  22. +1 −1 src/Spark/Compiler/NodeVisitors/SpecialNodeVisitor.cs
  23. +1 −0 src/Spark/Compiler/NodeVisitors/WhitespaceCleanerVisitor.cs
  24. +3 −0 src/Spark/Compiler/VisualBasic/ChunkVisitors/GeneratedCodeVisitor.cs
@@ -20,6 +20,7 @@
assertContains("ok1", contents);
assertContains("ok2", contents);
assertContains("ok3", contents);
+ assertContains("ok4", contents);
}
function testIteration()
@@ -16,5 +16,13 @@
<s:else/>
ok3
</s:test>
+
+ <p s:unless="true">
+ unless fail
+ </p>
+
+ <p s:unless="false">
+ ok4
+ </p>
</div>
@@ -362,6 +362,24 @@ public void ElseBlockFollowsIf()
}
[Test]
+ public void ConditionalChunkUnlessNegates()
+ {
+ var condition1 = new ConditionalChunk { Condition = "x != 12", Type = ConditionalType.Unless };
+ condition1.Body.Add(new SendLiteralChunk { Text = "ok1" });
+ var condition2 = new ConditionalChunk { Condition = "x == 12", Type = ConditionalType.Unless };
+ condition2.Body.Add(new SendLiteralChunk { Text = "fail" });
+ var chunks = Chunks(
+ new LocalVariableChunk { Name = "x", Value = "12" },
+ new SendLiteralChunk { Text = "a" },
+ condition1,
+ condition2,
+ new SendLiteralChunk { Text = "b" });
+ _compiler.CompileView(chunks, chunks);
+ var contents = ExecuteView();
+ Assert.AreEqual("aok1b", contents);
+ }
+
+ [Test]
public void ChainingElseIfNestsProperly()
{
var condition1 = new ConditionalChunk { Type = ConditionalType.If, Condition = "x == 1" };
@@ -196,6 +196,9 @@ protected override void Visit(ConditionalChunk chunk)
case ConditionalType.Once:
_source.Write("if Once(").Write(chunk.Condition).WriteLine("):");
break;
+ case ConditionalType.Unless:
+ _source.Write("if not ").Write(chunk.Condition).WriteLine(":");
+ break;
default:
throw new CompilerException(string.Format("Unknown ConditionalChunk type {0}", chunk.Type));
}
@@ -360,6 +360,24 @@ public void ElseBlockFollowsIf()
}
[Test]
+ public void ConditionalChunkUnlessNegates()
+ {
+ var condition1 = new ConditionalChunk { Condition = "x != 12", Type = ConditionalType.Unless };
+ condition1.Body.Add(new SendLiteralChunk { Text = "ok1" });
+ var condition2 = new ConditionalChunk { Condition = "x == 12", Type = ConditionalType.Unless };
+ condition2.Body.Add(new SendLiteralChunk { Text = "fail" });
+ var chunks = Chunks(
+ new LocalVariableChunk { Name = "x", Value = "12" },
+ new SendLiteralChunk { Text = "a" },
+ condition1,
+ condition2,
+ new SendLiteralChunk { Text = "b" });
+ _compiler.CompileView(chunks, chunks);
+ var contents = ExecuteView();
+ Assert.AreEqual("aok1b", contents);
+ }
+
+ [Test]
public void ChainingElseIfNestsProperly()
{
var condition1 = new ConditionalChunk { Type = ConditionalType.If, Condition = "x == 1" };
@@ -199,6 +199,9 @@ protected override void Visit(ConditionalChunk chunk)
case ConditionalType.Once:
_source.Write("if once(").Write(chunk.Condition).WriteLine(")");
break;
+ case ConditionalType.Unless:
+ _source.Write("unless ").WriteLine(chunk.Condition);
+ break;
default:
throw new CompilerException(string.Format("Unknown ConditionalChunk type {0}", chunk.Type));
}
@@ -220,6 +220,44 @@ public void IfElseFalseCondition()
}
[Test]
+ public void UnlessTrueCondition()
+ {
+ var compiler = new CSharpViewCompiler { BaseClass = "Spark.SparkViewBase" };
+
+ var trueChunks = new Chunk[] { new SendLiteralChunk { Text = "wastrue" } };
+
+ DoCompileView(compiler, new Chunk[]
+ {
+ new SendLiteralChunk {Text = "<p>"},
+ new LocalVariableChunk{Name="arg", Value="5"},
+ new ConditionalChunk{Type=ConditionalType.Unless, Condition="arg==5", Body=trueChunks},
+ new SendLiteralChunk {Text = "</p>"}
+ });
+ var instance = compiler.CreateInstance();
+ var contents = instance.RenderView();
+ Assert.AreEqual("<p></p>", contents);
+ }
+
+ [Test]
+ public void UnlessFalseCondition()
+ {
+ var compiler = new CSharpViewCompiler { BaseClass = "Spark.SparkViewBase" };
+
+ var trueChunks = new Chunk[] { new SendLiteralChunk { Text = "wastrue" } };
+
+ DoCompileView(compiler, new Chunk[]
+ {
+ new SendLiteralChunk {Text = "<p>"},
+ new LocalVariableChunk{Name="arg", Value="5"},
+ new ConditionalChunk{Type=ConditionalType.Unless, Condition="arg==6", Body=trueChunks},
+ new SendLiteralChunk {Text = "</p>"}
+ });
+ var instance = compiler.CreateInstance();
+ var contents = instance.RenderView();
+ Assert.AreEqual("<p>wastrue</p>", contents);
+ }
+
+ [Test]
public void LenientSilentNullDoesNotCauseWarningCS0168()
{
var compiler = new CSharpViewCompiler()
@@ -310,6 +310,44 @@ public void IfElseFalseCondition()
}
[Test]
+ public void UnlessTrueCondition()
+ {
+ var compiler = new VisualBasicViewCompiler { BaseClass = "Spark.AbstractSparkView" };
+
+ var trueChunks = new Chunk[] { new SendLiteralChunk { Text = "wastrue" } };
+
+ DoCompileView(compiler, new Chunk[]
+ {
+ new SendLiteralChunk {Text = "<p>"},
+ new LocalVariableChunk{Name="arg", Value="5"},
+ new ConditionalChunk{Type=ConditionalType.Unless, Condition="arg=5", Body=trueChunks},
+ new SendLiteralChunk {Text = "</p>"}
+ });
+ var instance = compiler.CreateInstance();
+ var contents = instance.RenderView();
+ Assert.AreEqual("<p></p>", contents);
+ }
+
+ [Test]
+ public void UnlessFalseCondition()
+ {
+ var compiler = new VisualBasicViewCompiler { BaseClass = "Spark.AbstractSparkView" };
+
+ var trueChunks = new Chunk[] { new SendLiteralChunk { Text = "wastrue" } };
+
+ DoCompileView(compiler, new Chunk[]
+ {
+ new SendLiteralChunk {Text = "<p>"},
+ new LocalVariableChunk{Name="arg", Value="5"},
+ new ConditionalChunk{Type=ConditionalType.Unless, Condition="arg=6", Body=trueChunks},
+ new SendLiteralChunk {Text = "</p>"}
+ });
+ var instance = compiler.CreateInstance();
+ var contents = instance.RenderView();
+ Assert.AreEqual("<p>wastrue</p>", contents);
+ }
+
+ [Test]
public void StrictNullUsesException()
{
var compiler = new VisualBasicViewCompiler()
@@ -108,12 +108,14 @@ public void ConditionalAttributes()
ContainsInOrder(output.ToString(),
"ok1",
"ok2",
- "ok3");
+ "ok3",
+ "ok4");
Assert.IsFalse(output.ToString().Contains("fail"));
Assert.IsFalse(output.ToString().Contains("if"));
Assert.IsFalse(output.ToString().Contains("else"));
Assert.IsFalse(output.ToString().Contains("condition"));
+ Assert.IsFalse(output.ToString().Contains("unless fail"));
}
[Test]
@@ -0,0 +1,5 @@
+<content name="Hello" each="var name in new[]{'alpha', 'beta', 'gamma'}" unless="name == 'beta'">
+ <p>name-${nameIndex}-${name}</p>
+</content>
+<use content="Hello"/>
+<SimpleValue each="var foo in new[] {'one','two','three'}" unless="foo == 'two'"/>
@@ -0,0 +1,8 @@
+<div>
+ <var arg="5"/>
+
+ <p unless="arg==5">argis5</p>
+
+ <p unless="arg==6">argisnot6</p>
+
+</div>
@@ -0,0 +1,12 @@
+<div>
+ <var arg="5"/>
+
+ <unless condition="arg==5">
+ <p>argis5</p>
+ </unless>
+
+ <unless condition="arg==6">
+ <p>argisnot6</p>
+ </unless>
+
+</div>
@@ -16,5 +16,13 @@
<s:else/>
ok3
</s:test>
+
+ <p s:unless="true">
+ unless fail
+ </p>
+
+ <p s:unless="false">
+ ok4
+ </p>
</div>
@@ -177,6 +177,15 @@
<None Include="Spark.Tests.Views\Home\addviewdatadifferenttypes.spark">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
+ <None Include="Spark.Tests.Views\Home\unlessattribute.spark">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ <None Include="Spark.Tests.Views\Home\unlesselement.spark">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ <None Include="Spark.Tests.Views\Home\UnlessAttributeWorksOnSpecialNodes.spark">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
<None Include="Spark.Tests.Views\Home\ShadeElementsMayStackOnOneLine.shade">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@@ -351,6 +360,7 @@
</None>
<None Include="Spark.Tests.Views\Home\ConditionalAttributeDelimitedBySpaces.spark">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <SubType>Designer</SubType>
</None>
<None Include="Spark.Tests.Views\Home\eachattribute-whitespace.spark">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
@@ -244,6 +244,35 @@ public void IfElseAttributes()
Assert.That(content.Contains("<p>argisstillnot6</p>"));
}
+ [Test]
+ public void UnlessElements()
+ {
+ mocks.ReplayAll();
+ var viewContext = MakeViewContext("unlesselement", null);
+ factory.RenderView(viewContext);
+ mocks.VerifyAll();
+
+ string content = sb.ToString();
+ Assert.That(!content.Contains("<unless"));
+
+ Assert.That(content.Contains("<p>argisnot6</p>"));
+ Assert.That(!content.Contains("<p>argis5</p>"));
+ }
+
+ [Test]
+ public void UnlessAttributes()
+ {
+ mocks.ReplayAll();
+ var viewContext = MakeViewContext("unlessattribute", null);
+ factory.RenderView(viewContext);
+ mocks.VerifyAll();
+
+ string content = sb.ToString();
+ Assert.That(!content.Contains("<unless"));
+
+ Assert.That(content.Contains("<p>argisnot6</p>"));
+ Assert.That(!content.Contains("<p>argis5</p>"));
+ }
[Test]
public void ChainingElseIfElement()
@@ -1022,6 +1051,25 @@ public void IfAttributeWorksOnSpecialNodes()
}
[Test]
+ public void UnlessAttributeWorksOnSpecialNodes()
+ {
+ mocks.ReplayAll();
+ var viewContext = MakeViewContext("UnlessAttributeWorksOnSpecialNodes", null);
+ factory.RenderView(viewContext);
+ mocks.VerifyAll();
+ string content = sb.ToString();
+
+ Assert.That(content, Contains.InOrder(
+ "<p>name-0-alpha</p>",
+ "<p>name-2-gamma</p>",
+ "<span>one</span>",
+ "<span>three</span>"));
+
+ Assert.IsFalse(content.Contains("beta"));
+ Assert.IsFalse(content.Contains("two"));
+ }
+
+ [Test]
public void OnceAttributeWorksOnSpecialNodes()
{
mocks.ReplayAll();
@@ -1093,7 +1141,6 @@ public void RecursivePartialsThrowCompilerException()
Throws.TypeOf<CompilerException>());
}
-
[Test]
public void NestedPartialsCanBackRenderUpAndReRenderDown()
{
@@ -40,6 +40,23 @@ public void DetectIfAttribute()
}
[Test]
+ public void DetectUnlessAttribute()
+ {
+ var grammar = new MarkupGrammar();
+ string input = "<div unless=\"true\">hello</div>";
+ var nodes = grammar.Nodes(new Position(new SourceContext(input))).Value;
+ var visitor = new ConditionalAttributeVisitor(new VisitorContext());
+ visitor.Accept(nodes);
+
+ Assert.AreEqual(1, visitor.Nodes.Count);
+ Assert.IsAssignableFrom(typeof(SpecialNode), visitor.Nodes[0]);
+
+ var unlessNode = visitor.Nodes[0] as SpecialNode;
+ Assert.IsNotNull(unlessNode);
+ Assert.AreEqual("unless", unlessNode.Element.Name);
+ }
+
+ [Test]
public void ChainConditionalAttribute()
{
var grammar = new MarkupGrammar();
@@ -439,6 +439,14 @@ protected override void Visit(ConditionalChunk chunk)
.WriteLine("))");
}
break;
+ case ConditionalType.Unless:
+ {
+ CodeIndent(chunk)
+ .Write("if (!(")
+ .WriteCode(chunk.Condition)
+ .WriteLine("))");
+ }
+ break;
default:
throw new CompilerException("Unexpected conditional type " + chunk.Type);
}
@@ -464,7 +472,7 @@ protected override void Visit(CacheChunk chunk)
_source
.WriteLine("try");
-
+
AppendOpenBrace();
Accept(chunk.Body);
AppendCloseBrace();
@@ -487,7 +495,7 @@ protected override void Visit(MarkdownChunk chunk)
AppendCloseBrace();
}
-
+
}
}
Oops, something went wrong.

0 comments on commit ddd1951

Please sign in to comment.