diff --git a/src/ManiaTemplates/Exceptions/CurlyBraceCountMismatchException.cs b/src/ManiaTemplates/Exceptions/CurlyBraceCountMismatchException.cs
new file mode 100644
index 0000000..74998af
--- /dev/null
+++ b/src/ManiaTemplates/Exceptions/CurlyBraceCountMismatchException.cs
@@ -0,0 +1,16 @@
+namespace ManiaTemplates.Exceptions;
+
+public class CurlyBraceCountMismatchException : Exception
+{
+ public CurlyBraceCountMismatchException()
+ {
+ }
+
+ public CurlyBraceCountMismatchException(string message) : base(message)
+ {
+ }
+
+ public CurlyBraceCountMismatchException(string message, Exception inner) : base(message, inner)
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/ManiaTemplates/Exceptions/EmptyNodeAttributeException.cs b/src/ManiaTemplates/Exceptions/EmptyNodeAttributeException.cs
new file mode 100644
index 0000000..e5fccfa
--- /dev/null
+++ b/src/ManiaTemplates/Exceptions/EmptyNodeAttributeException.cs
@@ -0,0 +1,16 @@
+namespace ManiaTemplates.Exceptions;
+
+public class EmptyNodeAttributeException : Exception
+{
+ public EmptyNodeAttributeException()
+ {
+ }
+
+ public EmptyNodeAttributeException(string message) : base(message)
+ {
+ }
+
+ public EmptyNodeAttributeException(string message, Exception inner) : base(message, inner)
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/ManiaTemplates/Exceptions/InterpolationRecursionException.cs b/src/ManiaTemplates/Exceptions/InterpolationRecursionException.cs
new file mode 100644
index 0000000..9ef3bb0
--- /dev/null
+++ b/src/ManiaTemplates/Exceptions/InterpolationRecursionException.cs
@@ -0,0 +1,16 @@
+namespace ManiaTemplates.Exceptions;
+
+public class InterpolationRecursionException : Exception
+{
+ public InterpolationRecursionException()
+ {
+ }
+
+ public InterpolationRecursionException(string message) : base(message)
+ {
+ }
+
+ public InterpolationRecursionException(string message, Exception inner) : base(message, inner)
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/ManiaTemplates/Lib/MtTransformer.cs b/src/ManiaTemplates/Lib/MtTransformer.cs
index 26e326d..244d0c3 100644
--- a/src/ManiaTemplates/Lib/MtTransformer.cs
+++ b/src/ManiaTemplates/Lib/MtTransformer.cs
@@ -57,7 +57,9 @@ public string BuildManialink(MtComponent rootComponent, string className, int ve
var body = ProcessNode(
XmlStringToNode(rootComponent.TemplateContent),
_engine.BaseMtComponents.Overload(rootComponent.ImportedComponents),
- rootContext
+ rootContext,
+ parentComponent: rootComponent,
+ isRootNode: true
);
var template = new Snippet
@@ -86,7 +88,7 @@ public string BuildManialink(MtComponent rootComponent, string className, int ve
///
private string CreateDoNothingMethod()
{
- return _maniaTemplateLanguage.FeatureBlock(@"string DoNothing(){return """";}").ToString();
+ return _maniaTemplateLanguage.FeatureBlock("""string DoNothing(){ return ""; }""").ToString();
}
///
@@ -119,7 +121,7 @@ private string CreateBodyRenderMethod(string body, MtDataContext context, MtComp
bodyRenderMethod.AppendLine($"var __data = {renderBodyArguments};");
//Root mania script block
- string rootScriptBlock = "";
+ var rootScriptBlock = "";
if (rootComponent.Scripts.Count > 0)
{
rootScriptBlock = CreateManiaScriptBlock(rootComponent);
@@ -234,12 +236,12 @@ private string CreateSlotRenderMethod(MtComponent component, int scope, MtDataCo
if (context.ParentContext != null)
{
- output.AppendLine(CreateLocalVariablesFromContext(context.ParentContext));
+ output.AppendLine(CreateLocalVariablesFromContext(context.ParentContext, parentComponent?.Properties.Keys));
variablesInherited.AddRange(context.ParentContext.Keys);
}
output
- .AppendLine(CreateLocalVariablesFromContext(context, variablesInherited))
+ .AppendLine(CreateLocalVariablesFromContext(context, parentComponent?.Properties.Keys))
.AppendLine(_maniaTemplateLanguage.FeatureBlockEnd())
.AppendLine(slotContent)
.AppendLine(_maniaTemplateLanguage.FeatureBlockStart())
@@ -270,7 +272,7 @@ private static string CreateLocalVariablesFromContext(MtDataContext context,
/// Process a ManiaTemplate node.
///
private string ProcessNode(XmlNode node, MtComponentMap availableMtComponents, MtDataContext context,
- MtComponent? parentComponent = null)
+ MtComponent? parentComponent = null, bool isRootNode = false)
{
Snippet snippet = new();
@@ -312,7 +314,8 @@ private string ProcessNode(XmlNode node, MtComponentMap availableMtComponents, M
component
),
slotContents,
- parentComponent
+ parentComponent,
+ isRootNode
);
subSnippet.AppendLine(_maniaTemplateLanguage.FeatureBlockStart())
@@ -345,7 +348,8 @@ private string ProcessNode(XmlNode node, MtComponentMap availableMtComponents, M
if (hasChildren)
{
subSnippet.AppendLine(1,
- ProcessNode(childNode, availableMtComponents, currentContext));
+ ProcessNode(childNode, availableMtComponents, currentContext,
+ parentComponent: parentComponent));
subSnippet.AppendLine(CreateXmlClosingTag(tag));
}
@@ -384,8 +388,15 @@ private Dictionary GetSlotContentsBySlotName(XmlNode componentNo
continue;
}
+ //Get the name from the slot attribute, or default if not found.
var slotName = childNode.Attributes?["slot"]?.Value.ToLower() ?? "default";
+ if (slotName.Trim().Length == 0)
+ {
+ throw new EmptyNodeAttributeException(
+ $"There's a template tag with empty slot name in <{componentNode.Name}>>.");
+ }
+
if (slotName == "default")
{
//Do not strip contents for default slot from node
@@ -420,7 +431,8 @@ private string ProcessComponentNode(
MtComponentAttributes attributeList,
string componentBody,
IReadOnlyDictionary slotContents,
- MtComponent? parentComponent = null
+ MtComponent? parentComponent = null,
+ bool isRootNode = false
)
{
foreach (var slotName in component.Slots)
@@ -527,7 +539,7 @@ private string ProcessComponentNode(
renderComponentCall.Append(
$", __slotRenderer_{parentSlotName}: __slotRenderer_{parentSlotName}");
}
-
+
foreach (var propertyName in parentComponent.Properties.Keys)
{
renderComponentCall.Append($",{propertyName}: {propertyName}");
@@ -537,11 +549,10 @@ private string ProcessComponentNode(
{
foreach (var parentSlotName in component.Slots)
{
- renderComponentCall.Append(
- $", __slotRenderer_{parentSlotName}: () => DoNothing()");
+ renderComponentCall.Append($", __slotRenderer_{parentSlotName}: () => DoNothing()");
}
}
-
+
renderComponentCall.Append(')');
i++;
@@ -554,7 +565,7 @@ private string ProcessComponentNode(
return renderComponentCall.ToString();
}
-
+
///
/// Creates the method which renders the contents of a component.
///
@@ -775,7 +786,7 @@ private string CreateManiaScriptDirectivesBlock()
}
///
- /// Checks the attribute list for if-condition and returns it, else null.
+ /// Checks the attribute list for if-condition and if found removes & returns it, else null.
///
private string? GetIfConditionFromNodeAttributes(MtComponentAttributes attributeList)
{
@@ -783,7 +794,7 @@ private string CreateManiaScriptDirectivesBlock()
}
///
- /// Checks the attribute list for name and returns it, else "default".
+ /// Checks the attribute list for name and if found removes & returns it, else "default".
///
private string GetNameFromNodeAttributes(MtComponentAttributes attributeList)
{
@@ -922,7 +933,7 @@ private static string CreateContextClassProperties(MtDataContext context)
///
/// Parses the attributes of a XmlNode to an MtComponentAttributes-instance.
///
- private static MtComponentAttributes GetXmlNodeAttributes(XmlNode node)
+ public static MtComponentAttributes GetXmlNodeAttributes(XmlNode node)
{
var attributeList = new MtComponentAttributes();
if (node.Attributes == null) return attributeList;
@@ -940,6 +951,8 @@ private static MtComponentAttributes GetXmlNodeAttributes(XmlNode node)
///
private string BuildManiaScripts(MtComponent rootComponent)
{
+ //TODO: check if method can be removed
+
var maniaScripts = rootComponent.Scripts.ToDictionary(script => script.ContentHash());
foreach (var (key, value) in _maniaScripts)
{
@@ -1005,7 +1018,7 @@ private static MtDataContext GetContextFromComponent(MtComponent component, stri
/// Returns C# code representation of the type.
///
/// The type.
- private static string GetFormattedName(Type type)
+ public static string GetFormattedName(Type type)
{
if (type.IsSubclassOf(typeof(DynamicObject)))
{
@@ -1081,7 +1094,7 @@ public static string WrapStringInQuotes(string str)
/// name = Shown in in-game debugger.
/// version = Version for the markup language of Trackmania.
///
- private static string ManiaLinkStart(string name, int version = 3, string? displayLayer = null)
+ public static string ManiaLinkStart(string name, int version = 3, string? displayLayer = null)
{
var layer = "";
if (displayLayer != null)
@@ -1103,7 +1116,7 @@ private static string ManiaLinkEnd()
///
/// Creates a xml opening tag for the given string and attribute list.
///
- private string CreateXmlOpeningTag(string tag, MtComponentAttributes attributeList, bool hasChildren)
+ public string CreateXmlOpeningTag(string tag, MtComponentAttributes attributeList, bool hasChildren)
{
var output = $"<{tag}";
@@ -1132,7 +1145,7 @@ private static string CreateXmlClosingTag(string tag)
///
/// Converts any valid XML-string into an XmlNode-element.
///
- private static XmlNode XmlStringToNode(string content)
+ public static XmlNode XmlStringToNode(string content)
{
var doc = new XmlDocument();
doc.LoadXml($"{content}");
@@ -1145,6 +1158,9 @@ private static XmlNode XmlStringToNode(string content)
///
public static string ReplaceCurlyBraces(string value, Func curlyContentWrapper)
{
+ CheckForCurlyBraceCountMismatch(value);
+ CheckInterpolationRecursion(value);
+
var matches = TemplateInterpolationRegex.Match(value);
var output = value;
@@ -1161,10 +1177,59 @@ public static string ReplaceCurlyBraces(string value, Func curly
return output;
}
+ ///
+ /// Checks whether double interpolation exists ({{ {{ a }} {{ b }} }}) and throws exception if so.
+ ///
+ public static void CheckInterpolationRecursion(string value)
+ {
+ var openCurlyBraces = 0;
+ foreach (var character in value.ToCharArray())
+ {
+ if (character == '{')
+ {
+ openCurlyBraces++;
+
+ if (openCurlyBraces >= 4)
+ {
+ throw new InterpolationRecursionException(
+ $"Double interpolation found in: {value}. You must not use double curly braces inside other double curly braces.");
+ }
+ }
+ else if (character == '}')
+ {
+ openCurlyBraces--;
+ }
+ }
+ }
+
+ ///
+ /// Checks whether double interpolation exists ({{ {{ a }} {{ b }} }}) and throws exception if so.
+ ///
+ public static void CheckForCurlyBraceCountMismatch(string value)
+ {
+ var openCurlyBraces = 0;
+ foreach (var character in value.ToCharArray())
+ {
+ if (character == '{')
+ {
+ openCurlyBraces++;
+ }
+ else if (character == '}')
+ {
+ openCurlyBraces--;
+ }
+ }
+
+ if (openCurlyBraces != 0)
+ {
+ throw new CurlyBraceCountMismatchException($"Found curly brace count mismatch in: {value}.");
+ }
+ }
+
///
/// Joins consecutive feature blocks to reduce generated code.
///
- private static string JoinFeatureBlocks(string manialink)
+ public static string JoinFeatureBlocks(string manialink)
{
var match = TemplateFeatureControlRegex.Match(manialink);
var output = new Snippet();
diff --git a/tests/ManiaTemplates.Tests/IntegrationTests/ManialinkEngineTest.cs b/tests/ManiaTemplates.Tests/IntegrationTests/ManialinkEngineTest.cs
index 6ffa376..486156a 100644
--- a/tests/ManiaTemplates.Tests/IntegrationTests/ManialinkEngineTest.cs
+++ b/tests/ManiaTemplates.Tests/IntegrationTests/ManialinkEngineTest.cs
@@ -88,17 +88,20 @@ await Assert.ThrowsAsync(() =>
[Fact]
public async void Should_Render_Component_Without_Content_For_Slot()
{
- var slotRecursionOuterTwoTemplate = await File.ReadAllTextAsync("IntegrationTests/templates/slot-recursion-outer-two.mt");
- var slotRecursionOuterTemplate = await File.ReadAllTextAsync("IntegrationTests/templates/slot-recursion-outer.mt");
- var slotRecursionInnerTemplate = await File.ReadAllTextAsync("IntegrationTests/templates/slot-recursion-inner.mt");
+ var slotRecursionOuterTwoTemplate =
+ await File.ReadAllTextAsync("IntegrationTests/templates/slot-recursion-outer-two.mt");
+ var slotRecursionOuterTemplate =
+ await File.ReadAllTextAsync("IntegrationTests/templates/slot-recursion-outer.mt");
+ var slotRecursionInnerTemplate =
+ await File.ReadAllTextAsync("IntegrationTests/templates/slot-recursion-inner.mt");
var expected = await File.ReadAllTextAsync("IntegrationTests/expected/single-slot-unfilled.xml");
var assemblies = new[] { typeof(ManiaTemplateEngine).Assembly, typeof(ComplexDataType).Assembly };
-
+
_maniaTemplateEngine.AddTemplateFromString("SlotRecursionOuterTwo", slotRecursionOuterTwoTemplate);
_maniaTemplateEngine.AddTemplateFromString("SlotRecursionOuter", slotRecursionOuterTemplate);
_maniaTemplateEngine.AddTemplateFromString("SlotRecursionInner", slotRecursionInnerTemplate);
-
- var template = _maniaTemplateEngine.RenderAsync("SlotRecursionInner", new{}, assemblies).Result;
+
+ var template = _maniaTemplateEngine.RenderAsync("SlotRecursionInner", new { }, assemblies).Result;
Assert.Equal(expected, template, ignoreLineEndingDifferences: true);
}
@@ -110,15 +113,32 @@ public async void Should_Pass_Properties_To_Components_And_Slots()
var testComponentTemplate = await File.ReadAllTextAsync("IntegrationTests/templates/component.mt");
var expected = await File.ReadAllTextAsync("IntegrationTests/expected/property-test.xml");
var assemblies = new[] { typeof(ManiaTemplateEngine).Assembly, typeof(ComplexDataType).Assembly };
-
+
_maniaTemplateEngine.AddTemplateFromString("PropertyTest", propertyTestTemplate);
_maniaTemplateEngine.AddTemplateFromString("Wrapper", testWrapperTemplate);
_maniaTemplateEngine.AddTemplateFromString("TestComponent", testComponentTemplate);
-
+
var template = _maniaTemplateEngine.RenderAsync("PropertyTest", new
{
testVariable = "integration"
}, assemblies).Result;
Assert.Equal(expected, template, ignoreLineEndingDifferences: true);
}
+
+ [Fact]
+ public async void Should_Fill_All_Slots()
+ {
+ var baseTemplate = await File.ReadAllTextAsync("IntegrationTests/templates/slots/base.mt");
+ var containerTemplate = await File.ReadAllTextAsync("IntegrationTests/templates/slots/container.mt");
+ var windowTemplate = await File.ReadAllTextAsync("IntegrationTests/templates/slots/window.mt");
+ var expected = await File.ReadAllTextAsync("IntegrationTests/expected/slots/manialink.xml");
+ var assemblies = new[] { typeof(ManiaTemplateEngine).Assembly, typeof(ComplexDataType).Assembly };
+
+ _maniaTemplateEngine.AddTemplateFromString("Base", baseTemplate);
+ _maniaTemplateEngine.AddTemplateFromString("Container", containerTemplate);
+ _maniaTemplateEngine.AddTemplateFromString("Window", windowTemplate);
+
+ var template = _maniaTemplateEngine.RenderAsync("Base", new { }, assemblies).Result;
+ Assert.Equal(expected, template, ignoreLineEndingDifferences: true);
+ }
}
\ No newline at end of file
diff --git a/tests/ManiaTemplates.Tests/IntegrationTests/expected/slots/manialink.xml b/tests/ManiaTemplates.Tests/IntegrationTests/expected/slots/manialink.xml
new file mode 100644
index 0000000..9bb5746
--- /dev/null
+++ b/tests/ManiaTemplates.Tests/IntegrationTests/expected/slots/manialink.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/ManiaTemplates.Tests/IntegrationTests/templates/slots/base.mt b/tests/ManiaTemplates.Tests/IntegrationTests/templates/slots/base.mt
new file mode 100644
index 0000000..f190a0b
--- /dev/null
+++ b/tests/ManiaTemplates.Tests/IntegrationTests/templates/slots/base.mt
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/ManiaTemplates.Tests/IntegrationTests/templates/slots/container.mt b/tests/ManiaTemplates.Tests/IntegrationTests/templates/slots/container.mt
new file mode 100644
index 0000000..005b411
--- /dev/null
+++ b/tests/ManiaTemplates.Tests/IntegrationTests/templates/slots/container.mt
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/ManiaTemplates.Tests/IntegrationTests/templates/slots/window.mt b/tests/ManiaTemplates.Tests/IntegrationTests/templates/slots/window.mt
new file mode 100644
index 0000000..5a9a4c6
--- /dev/null
+++ b/tests/ManiaTemplates.Tests/IntegrationTests/templates/slots/window.mt
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/ManiaTemplates.Tests/Lib/MtTransformerTest.cs b/tests/ManiaTemplates.Tests/Lib/MtTransformerTest.cs
index 445376e..ea61d45 100644
--- a/tests/ManiaTemplates.Tests/Lib/MtTransformerTest.cs
+++ b/tests/ManiaTemplates.Tests/Lib/MtTransformerTest.cs
@@ -1,6 +1,8 @@
using System.Reflection;
using System.Text.RegularExpressions;
+using System.Xml;
using ManiaTemplates.Components;
+using ManiaTemplates.Exceptions;
using ManiaTemplates.Languages;
using ManiaTemplates.Lib;
using Xunit.Abstractions;
@@ -13,6 +15,7 @@ public class MtTransformerTest
private readonly MtTransformer _transformer;
private readonly ManiaTemplateEngine _maniaTemplateEngine = new();
private readonly Regex _hashCodePattern = new("[0-9]{6,10}");
+
private readonly MtComponent _testComponent = new()
{
Namespaces = new() { "namespace" },
@@ -131,7 +134,25 @@ public void Should_Import_Components_Recursively()
}
[Fact]
- public void Should_Replace_Curly_Braces_Correctly()
+ public void Should_Throw_Interpolation_Recursion_Exception()
+ {
+ Assert.Throws(() =>
+ MtTransformer.CheckInterpolationRecursion("{{ {{ a }} {{ b }} }}"));
+ Assert.Throws(() =>
+ MtTransformer.CheckInterpolationRecursion("{{ {{ b }} }}"));
+ }
+
+ [Fact]
+ public void Should_Throw_Curly_Brace_Count_Mismatch_Exception()
+ {
+ Assert.Throws(() => MtTransformer.CheckForCurlyBraceCountMismatch("{{ { }}"));
+ Assert.Throws(() => MtTransformer.CheckForCurlyBraceCountMismatch("{{ } }}"));
+ Assert.Throws(() => MtTransformer.CheckForCurlyBraceCountMismatch("{"));
+ Assert.Throws(() => MtTransformer.CheckForCurlyBraceCountMismatch("}}"));
+ }
+
+ [Fact]
+ public void Should_Replace_Curly_Braces()
{
Assert.Equal("abcd", MtTransformer.ReplaceCurlyBraces("{{a}}{{ b }}{{c }}{{ d}}", s => s));
Assert.Equal("x y z", MtTransformer.ReplaceCurlyBraces("{{x}} {{ y }} {{z }}", s => s));
@@ -144,5 +165,69 @@ public void Should_Replace_Curly_Braces_Correctly()
public void Should_Wrap_Strings_In_Quotes()
{
Assert.Equal(@"$""unit test""", MtTransformer.WrapStringInQuotes("unit test"));
+ Assert.Equal(@"$""""", MtTransformer.WrapStringInQuotes(""));
+ }
+
+ [Fact]
+ public void Should_Join_Feature_Blocks()
+ {
+ Assert.Equal("<#+\n unittest \n#>",
+ MtTransformer.JoinFeatureBlocks("<#+#><#+\n #> <#+ unittest \n#><#+ \n\n\n#>"));
+ }
+
+ [Fact]
+ public void Should_Convert_String_To_Xml_Node()
+ {
+ var node = MtTransformer.XmlStringToNode("test");
+ Assert.IsAssignableFrom(node);
+ Assert.Equal("test", node.InnerText);
+ Assert.Equal("test", node.InnerXml);
+ Assert.Equal("test", node.OuterXml);
+ }
+
+ [Fact]
+ public void Should_Create_Xml_Opening_Tag()
+ {
+ var attributeList = new MtComponentAttributes();
+ Assert.Equal("", _transformer.CreateXmlOpeningTag("test", attributeList, false));
+ Assert.Equal("", _transformer.CreateXmlOpeningTag("test", attributeList, true));
+
+ attributeList["prop"] = "value";
+ Assert.Equal("""""", _transformer.CreateXmlOpeningTag("test", attributeList, false));
+ Assert.Equal("""""", _transformer.CreateXmlOpeningTag("test", attributeList, true));
+ }
+
+ [Fact]
+ public void Should_Create_ManiaLink_Opening_Tag()
+ {
+ Assert.Equal("""""",
+ MtTransformer.ManiaLinkStart("Test", 99));
+ Assert.Equal("""""",
+ MtTransformer.ManiaLinkStart("Test", 99, "SomeLayer"));
+ }
+
+ [Fact]
+ public void Should_Convert_Xml_Node_Arguments_To_MtComponentAttributes_Instance()
+ {
+ var node = MtTransformer.XmlStringToNode("""testContent""");
+ if (node.FirstChild == null) return;
+
+ var attributes = MtTransformer.GetXmlNodeAttributes(node.FirstChild);
+ Assert.Equal(2, attributes.Count);
+ Assert.Equal("test1", attributes["arg1"]);
+ Assert.Equal("test2", attributes["arg2"]);
+ }
+
+ [Fact]
+ public void Should_Detect_Correct_Type_String_For_CSharp_Scripting()
+ {
+ Assert.Equal("int", MtTransformer.GetFormattedName(0.GetType()));
+ Assert.Equal("double", MtTransformer.GetFormattedName(0.0.GetType()));
+ Assert.Equal("string", MtTransformer.GetFormattedName("test".GetType()));
+ Assert.Equal("System.Collections.Generic.List",
+ MtTransformer.GetFormattedName(new List().GetType()));
+ Assert.Equal("System.Collections.Generic.HashSet",
+ MtTransformer.GetFormattedName(new HashSet().GetType()));
+ Assert.Equal("dynamic", MtTransformer.GetFormattedName(new TestDynamicObject().GetType()));
}
}
\ No newline at end of file
diff --git a/tests/ManiaTemplates.Tests/Lib/TestDynamicObject.cs b/tests/ManiaTemplates.Tests/Lib/TestDynamicObject.cs
new file mode 100644
index 0000000..471cbe1
--- /dev/null
+++ b/tests/ManiaTemplates.Tests/Lib/TestDynamicObject.cs
@@ -0,0 +1,7 @@
+using System.Dynamic;
+
+namespace ManiaTemplates.Tests.Lib;
+
+public class TestDynamicObject : DynamicObject
+{
+}
\ No newline at end of file
diff --git a/tests/ManiaTemplates.Tests/Lib/expected.tt b/tests/ManiaTemplates.Tests/Lib/expected.tt
index f49dc93..596dd8e 100644
--- a/tests/ManiaTemplates.Tests/Lib/expected.tt
+++ b/tests/ManiaTemplates.Tests/Lib/expected.tt
@@ -32,18 +32,18 @@ i = data.i;
}
List __insertedOneTimeManiaScripts = new List();
List __maniaScriptRenderMethods = new List();
-string DoNothing(){return "";}
+string DoNothing(){ return ""; }
void RenderBody() {
var __data = new CRoot { numbers = numbers,enabled = enabled };
var __outerIndex1 = 0;
foreach (int i in numbers) {
var __index = __outerIndex1;
if (enabled) {
-Render_Component_MtContext2(__data: __data, x: (20 * __index), __slotRenderer_default: () => Render_Slot_3_default(__data: new CRoot_ForEachLoop1(__data){__index = __index, i = i}, __slotRenderer_default: () => DoNothing()));
+Render_Component_MtContext2(__data: __data, x: (20 * __index), __slotRenderer_default: () => Render_Slot_3_default(__data: new CRoot_ForEachLoop1(__data){__index = __index, i = i},numbers: numbers,enabled: enabled));
}
__outerIndex1++;
}
-Render_Component_MtContext2(__data: __data, __slotRenderer_default: () => Render_Slot_4_default(__data: __data, __slotRenderer_default: () => DoNothing()));
+Render_Component_MtContext2(__data: __data, __slotRenderer_default: () => Render_Slot_4_default(__data: __data,numbers: numbers,enabled: enabled));
foreach(var maniaScriptRenderMethod in __maniaScriptRenderMethods){ maniaScriptRenderMethod(); }
#>
<#+
}
-void Render_Slot_3_default(CRoot_ForEachLoop1 __data,Action __slotRenderer_default) {
-var numbers = __data.numbers;
-var enabled = __data.enabled;
+void Render_Slot_3_default(CRoot_ForEachLoop1 __data,List numbers,boolean enabled = true) {
var __index = __data.__index;
var i = __data.i;
var __outerIndex7 = 0;
@@ -115,9 +113,7 @@ Render_Component_MtContext6(__data: __data, arg3: (new test()));
<#+
}
-void Render_Slot_4_default(CRoot __data,Action __slotRenderer_default) {
-var numbers = __data.numbers;
-var enabled = __data.enabled;
+void Render_Slot_4_default(CRoot __data,List numbers,boolean enabled = true) {
Render_Component_MtContext2(__data: __data, __slotRenderer_default: () => Render_Slot_8_default(__data: __data, __slotRenderer_default: () => DoNothing()));
}
#>
\ No newline at end of file