diff --git a/src/ManiaTemplates/Lib/MtTransformer.cs b/src/ManiaTemplates/Lib/MtTransformer.cs index 888414a..812e9ab 100644 --- a/src/ManiaTemplates/Lib/MtTransformer.cs +++ b/src/ManiaTemplates/Lib/MtTransformer.cs @@ -219,10 +219,13 @@ private string CreateSlotRenderMethod(MtComponent component, int scope, MtDataCo { $"{context} __data" }; - + //add slot render methods AppendSlotRenderArgumentsToList(methodArguments, parentComponent ?? component); + //add component properties as arguments + AppendComponentPropertiesToMethodArgumentsList(parentComponent ?? component, methodArguments); + var output = new StringBuilder(_maniaTemplateLanguage.FeatureBlockStart()) .AppendLine("void " + CreateMethodCall(methodName, string.Join(',', methodArguments), "") + " {"); @@ -430,8 +433,14 @@ private string ProcessComponentNode( Scope = scope, Context = currentContext, Name = slotName, - RenderMethodT4 = CreateSlotRenderMethod(component, scope, currentContext, slotName, slotContent, - parentComponent) + RenderMethodT4 = CreateSlotRenderMethod( + component, + scope, + currentContext, + slotName, + slotContent, + parentComponent + ) }); } @@ -446,13 +455,11 @@ private string ProcessComponentNode( //Create render call var renderComponentCall = new StringBuilder(renderMethodName).Append("(__data: __data"); - - //Pass available arguments - var renderArguments = new List - { - "" - }; + //Create available arguments + var renderArguments = new List { "" }; + + //Attach attributes to render method call foreach (var (attributeName, attributeValue) in attributeList) { if (component.Properties.TryGetValue(attributeName, out var value)) @@ -517,6 +524,11 @@ private string ProcessComponentNode( renderComponentCall.Append( $", __slotRenderer_{parentSlotName}: __slotRenderer_{parentSlotName}"); } + + foreach (var propertyName in parentComponent.Properties.Keys) + { + renderComponentCall.Append($",{propertyName}: {propertyName}"); + } } else { @@ -526,8 +538,8 @@ private string ProcessComponentNode( $", __slotRenderer_{parentSlotName}: () => DoNothing()"); } } - - renderComponentCall.Append(")"); + + renderComponentCall.Append(')'); i++; } @@ -539,7 +551,7 @@ private string ProcessComponentNode( return renderComponentCall.ToString(); } - + /// /// Creates the method which renders the contents of a component. /// @@ -559,19 +571,14 @@ private string CreateComponentRenderMethod(MtComponent component, string renderM //add slot render methods AppendSlotRenderArgumentsToList(arguments, component); - //add method arguments with defaults - arguments.AddRange(component.Properties.Values.OrderBy(property => property.Default != null).Select(property => - property.Default == null - ? $"{property.Type} {property.Name}" - : $"{property.Type} {property.Name} = {(WrapIfString(property, property.Default))}")); + //add component properties as arguments with defaults + AppendComponentPropertiesToMethodArgumentsList(component, arguments); //close method arguments renderMethod.Append(string.Join(", ", arguments)) .AppendLine(") {") - .AppendLine(_maniaTemplateLanguage.FeatureBlockEnd()); - - //insert body - renderMethod.AppendLine(componentBody); + .AppendLine(_maniaTemplateLanguage.FeatureBlockEnd()) + .AppendLine(componentBody); //insert mania scripts if (component.Scripts.Count > 0) @@ -598,6 +605,17 @@ private string CreateComponentRenderMethod(MtComponent component, string renderM .ToString(); } + /// + /// Takes all available properties of a component and adds them to the given list of method arguments. + /// + private static void AppendComponentPropertiesToMethodArgumentsList(MtComponent component, List arguments) + { + arguments.AddRange(component.Properties.Values.OrderBy(property => property.Default != null) + .Select(property => property.Default == null + ? $"{property.Type} {property.Name}" + : $"{property.Type} {property.Name} = {(WrapIfString(property, property.Default))}")); + } + /// /// Takes all available slots of a component and app ends the slot render arguments to the given list. /// @@ -1048,7 +1066,7 @@ private static bool IsStringType(MtComponentProperty property) /// /// Wraps a string in quotes. /// - private static string WrapStringInQuotes(string str) + public static string WrapStringInQuotes(string str) { return $@"$""{str}"""; } @@ -1122,7 +1140,7 @@ private static XmlNode XmlStringToNode(string content) /// /// Takes the contents of double curly braces in a string and wraps them into something else. The second Argument takes a string-argument and returns the newly wrapped string. /// - private static string ReplaceCurlyBraces(string value, Func curlyContentWrapper) + public static string ReplaceCurlyBraces(string value, Func curlyContentWrapper) { var matches = TemplateInterpolationRegex.Match(value); var output = value; diff --git a/tests/ManiaTemplates.Tests/IntegrationTests/ManialinkEngineTest.cs b/tests/ManiaTemplates.Tests/IntegrationTests/ManialinkEngineTest.cs index f9c46a3..6ffa376 100644 --- a/tests/ManiaTemplates.Tests/IntegrationTests/ManialinkEngineTest.cs +++ b/tests/ManiaTemplates.Tests/IntegrationTests/ManialinkEngineTest.cs @@ -101,4 +101,24 @@ public async void Should_Render_Component_Without_Content_For_Slot() var template = _maniaTemplateEngine.RenderAsync("SlotRecursionInner", new{}, assemblies).Result; Assert.Equal(expected, template, ignoreLineEndingDifferences: true); } + + [Fact] + public async void Should_Pass_Properties_To_Components_And_Slots() + { + var propertyTestTemplate = await File.ReadAllTextAsync("IntegrationTests/templates/property-test.mt"); + var testWrapperTemplate = await File.ReadAllTextAsync("IntegrationTests/templates/wrapper.mt"); + 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); + } } \ No newline at end of file diff --git a/tests/ManiaTemplates.Tests/IntegrationTests/expected/property-test.xml b/tests/ManiaTemplates.Tests/IntegrationTests/expected/property-test.xml new file mode 100644 index 0000000..ddbcf60 --- /dev/null +++ b/tests/ManiaTemplates.Tests/IntegrationTests/expected/property-test.xml @@ -0,0 +1,17 @@ + + + diff --git a/tests/ManiaTemplates.Tests/IntegrationTests/templates/component.mt b/tests/ManiaTemplates.Tests/IntegrationTests/templates/component.mt new file mode 100644 index 0000000..3a5664f --- /dev/null +++ b/tests/ManiaTemplates.Tests/IntegrationTests/templates/component.mt @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/tests/ManiaTemplates.Tests/IntegrationTests/templates/property-test.mt b/tests/ManiaTemplates.Tests/IntegrationTests/templates/property-test.mt new file mode 100644 index 0000000..159a4b0 --- /dev/null +++ b/tests/ManiaTemplates.Tests/IntegrationTests/templates/property-test.mt @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/tests/ManiaTemplates.Tests/IntegrationTests/templates/wrapper.mt b/tests/ManiaTemplates.Tests/IntegrationTests/templates/wrapper.mt new file mode 100644 index 0000000..9098306 --- /dev/null +++ b/tests/ManiaTemplates.Tests/IntegrationTests/templates/wrapper.mt @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/tests/ManiaTemplates.Tests/Lib/MtTransformerTest.cs b/tests/ManiaTemplates.Tests/Lib/MtTransformerTest.cs index e2c75cc..445376e 100644 --- a/tests/ManiaTemplates.Tests/Lib/MtTransformerTest.cs +++ b/tests/ManiaTemplates.Tests/Lib/MtTransformerTest.cs @@ -10,9 +10,9 @@ namespace ManiaTemplates.Tests.Lib; public class MtTransformerTest { private readonly ITestOutputHelper _testOutputHelper; + 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" }, @@ -47,8 +47,6 @@ public class MtTransformerTest " }; - private readonly MtTransformer _transformer; - public MtTransformerTest(ITestOutputHelper testOutputHelper) { _testOutputHelper = testOutputHelper; @@ -90,9 +88,9 @@ public void Should_Build_Manialink() var expected = File.ReadAllText("Lib/expected.tt"); var result = _transformer.BuildManialink(_testComponent, "expected"); var generalizedResult = TransformCodeToOrderNumber(result); - + _testOutputHelper.WriteLine(generalizedResult); - + Assert.Equal(expected, generalizedResult, ignoreLineEndingDifferences: true); } @@ -118,15 +116,33 @@ public void Should_Import_Components_Recursively() { var assemblies = new List(); assemblies.Add(Assembly.GetExecutingAssembly()); - + _maniaTemplateEngine.AddTemplateFromString("Embeddable", ""); - _maniaTemplateEngine.AddTemplateFromString("RecursionElement", ""); - _maniaTemplateEngine.AddTemplateFromString("RecursionRoot", ""); - - var output = _maniaTemplateEngine.RenderAsync("RecursionRoot", new {}, assemblies).Result; - Assert.Equal( @$" + _maniaTemplateEngine.AddTemplateFromString("RecursionElement", + ""); + _maniaTemplateEngine.AddTemplateFromString("RecursionRoot", + ""); + + var output = _maniaTemplateEngine.RenderAsync("RecursionRoot", new { }, assemblies).Result; + Assert.Equal(@$" ", output, ignoreLineEndingDifferences: true); } + + [Fact] + public void Should_Replace_Curly_Braces_Correctly() + { + Assert.Equal("abcd", MtTransformer.ReplaceCurlyBraces("{{a}}{{ b }}{{c }}{{ d}}", s => s)); + Assert.Equal("x y z", MtTransformer.ReplaceCurlyBraces("{{x}} {{ y }} {{z }}", s => s)); + Assert.Equal("unittest", MtTransformer.ReplaceCurlyBraces("{{ unit }}test", s => s)); + Assert.Equal("#unit#test", MtTransformer.ReplaceCurlyBraces("{{ unit }}test", s => $"#{s}#")); + Assert.Equal("#{ unit#}test", MtTransformer.ReplaceCurlyBraces("{{{ unit }}}test", s => $"#{s}#")); + } + + [Fact] + public void Should_Wrap_Strings_In_Quotes() + { + Assert.Equal(@"$""unit test""", MtTransformer.WrapStringInQuotes("unit test")); + } } \ No newline at end of file diff --git a/tests/ManiaTemplates.Tests/Lib/expected.tt b/tests/ManiaTemplates.Tests/Lib/expected.tt index f49dc93..0cfafe4 100644 --- a/tests/ManiaTemplates.Tests/Lib/expected.tt +++ b/tests/ManiaTemplates.Tests/Lib/expected.tt @@ -90,7 +90,7 @@ __insertedOneTimeManiaScripts.Add("FWKSFxnFcgdsXVn9dn5IW3isD6T8z+2eK6liK8rPSpU=" <#+ } -void Render_Slot_3_default(CRoot_ForEachLoop1 __data,Action __slotRenderer_default) { +void Render_Slot_3_default(CRoot_ForEachLoop1 __data,Action __slotRenderer_default,int zIndex = 0,double x = 0.0,double y = 0.0,double w = 0.0,double h = 0.0) { var numbers = __data.numbers; var enabled = __data.enabled; var __index = __data.__index; @@ -104,7 +104,7 @@ Render_Component_MtContext5(__data: __data, text: $"{(i)}, {(j)} at index {(__in __outerIndex7++; } } -void Render_Slot_8_default(CRoot __data,Action __slotRenderer_default) { +void Render_Slot_8_default(CRoot __data,Action __slotRenderer_default,int zIndex = 0,double x = 0.0,double y = 0.0,double w = 0.0,double h = 0.0) { var numbers = __data.numbers; var enabled = __data.enabled; #> @@ -115,7 +115,7 @@ Render_Component_MtContext6(__data: __data, arg3: (new test())); <#+ } -void Render_Slot_4_default(CRoot __data,Action __slotRenderer_default) { +void Render_Slot_4_default(CRoot __data,Action __slotRenderer_default,int zIndex = 0,double x = 0.0,double y = 0.0,double w = 0.0,double h = 0.0) { var numbers = __data.numbers; var enabled = __data.enabled; Render_Component_MtContext2(__data: __data, __slotRenderer_default: () => Render_Slot_8_default(__data: __data, __slotRenderer_default: () => DoNothing()));