Skip to content

Commit

Permalink
Merge pull request #45 from EvoEsports/bugfix/data-context-missing
Browse files Browse the repository at this point in the history
Fix properties are not passed to slot render methods
  • Loading branch information
araszka authored Jan 11, 2024
2 parents 6996932 + 24397d8 commit 0edf64a
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 37 deletions.
64 changes: 41 additions & 23 deletions src/ManiaTemplates/Lib/MtTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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), "") + " {");

Expand Down Expand Up @@ -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
)
});
}

Expand All @@ -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<string>
{
""
};

//Create available arguments
var renderArguments = new List<string> { "" };

//Attach attributes to render method call
foreach (var (attributeName, attributeValue) in attributeList)
{
if (component.Properties.TryGetValue(attributeName, out var value))
Expand Down Expand Up @@ -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
{
Expand All @@ -526,8 +538,8 @@ private string ProcessComponentNode(
$", __slotRenderer_{parentSlotName}: () => DoNothing()");
}
}

renderComponentCall.Append(")");
renderComponentCall.Append(')');

i++;
}
Expand All @@ -539,7 +551,7 @@ private string ProcessComponentNode(

return renderComponentCall.ToString();
}

/// <summary>
/// Creates the method which renders the contents of a component.
/// </summary>
Expand All @@ -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)
Expand All @@ -598,6 +605,17 @@ private string CreateComponentRenderMethod(MtComponent component, string renderM
.ToString();
}

/// <summary>
/// Takes all available properties of a component and adds them to the given list of method arguments.
/// </summary>
private static void AppendComponentPropertiesToMethodArgumentsList(MtComponent component, List<string> 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))}"));
}

/// <summary>
/// Takes all available slots of a component and app ends the slot render arguments to the given list.
/// </summary>
Expand Down Expand Up @@ -1048,7 +1066,7 @@ private static bool IsStringType(MtComponentProperty property)
/// <summary>
/// Wraps a string in quotes.
/// </summary>
private static string WrapStringInQuotes(string str)
public static string WrapStringInQuotes(string str)
{
return $@"$""{str}""";
}
Expand Down Expand Up @@ -1122,7 +1140,7 @@ private static XmlNode XmlStringToNode(string content)
/// <summary>
/// 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.
/// </summary>
private static string ReplaceCurlyBraces(string value, Func<string, string> curlyContentWrapper)
public static string ReplaceCurlyBraces(string value, Func<string, string> curlyContentWrapper)
{
var matches = TemplateInterpolationRegex.Match(value);
var output = value;
Expand Down
20 changes: 20 additions & 0 deletions tests/ManiaTemplates.Tests/IntegrationTests/ManialinkEngineTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<manialink version="3" id="MtPropertyTest" name="EvoSC#-MtPropertyTest">
<frame size="15 11">
<label size="15 3" text="integrationtest" />
</frame>
<frame size="15 11">
<label size="15 3" text="integrationintegration" />
</frame>
<frame size="15 11">
<label size="15 3" text="test" />
</frame>
<label text="integration" />
<frame size="123 11">
<frame size="77 11">
<label text="integration" />
</frame>
</frame>
</manialink>
12 changes: 12 additions & 0 deletions tests/ManiaTemplates.Tests/IntegrationTests/templates/component.mt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<component>
<import component="Wrapper" as="Wrapper" />

<property type="string" name="text" default="" />
<property type="double" name="width" default="15" />

<template>
<Wrapper width="{{ width }}">
<label size="{{ width }} 3" text="{{ text }}" />
</Wrapper>
</template>
</component>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<component>
<import component="TestComponent" as="TestComponent" />
<import component="Wrapper" as="Wrapper" />

<property type="string" name="testVariable" />

<template>
<TestComponent text="{{ testVariable }}test" />
<TestComponent text="{{ testVariable }}{{ testVariable }}" />
<TestComponent text="test" />
<label text="{{ testVariable }}" />
<Wrapper width="{{ 123.0 }}">
<Wrapper width="{{ 77.0 }}">
<label text="{{ testVariable }}" />
</Wrapper>
</Wrapper>
</template>
</component>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<component>
<property type="double" name="width" default="20" />

<template>
<frame size="{{ width }} 11">
<slot />
</frame>
</template>
</component>
38 changes: 27 additions & 11 deletions tests/ManiaTemplates.Tests/Lib/MtTransformerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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" },
Expand Down Expand Up @@ -47,8 +47,6 @@ public class MtTransformerTest
</Frame>"
};

private readonly MtTransformer _transformer;

public MtTransformerTest(ITestOutputHelper testOutputHelper)
{
_testOutputHelper = testOutputHelper;
Expand Down Expand Up @@ -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);
}

Expand All @@ -118,15 +116,33 @@ public void Should_Import_Components_Recursively()
{
var assemblies = new List<Assembly>();
assemblies.Add(Assembly.GetExecutingAssembly());

_maniaTemplateEngine.AddTemplateFromString("Embeddable", "<component><template><el/></template></component>");
_maniaTemplateEngine.AddTemplateFromString("RecursionElement", "<component><import component='Embeddable' as='Comp' /><template><Comp/></template></component>");
_maniaTemplateEngine.AddTemplateFromString("RecursionRoot", "<component><import component='RecursionElement' as='REL' /><template><REL/></template></component>");

var output = _maniaTemplateEngine.RenderAsync("RecursionRoot", new {}, assemblies).Result;
Assert.Equal( @$"<manialink version=""3"" id=""MtRecursionRoot"" name=""EvoSC#-MtRecursionRoot"">
_maniaTemplateEngine.AddTemplateFromString("RecursionElement",
"<component><import component='Embeddable' as='Comp' /><template><Comp/></template></component>");
_maniaTemplateEngine.AddTemplateFromString("RecursionRoot",
"<component><import component='RecursionElement' as='REL' /><template><REL/></template></component>");

var output = _maniaTemplateEngine.RenderAsync("RecursionRoot", new { }, assemblies).Result;
Assert.Equal(@$"<manialink version=""3"" id=""MtRecursionRoot"" name=""EvoSC#-MtRecursionRoot"">
<el />
</manialink>
", 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"));
}
}
6 changes: 3 additions & 3 deletions tests/ManiaTemplates.Tests/Lib/expected.tt
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ __insertedOneTimeManiaScripts.Add("FWKSFxnFcgdsXVn9dn5IW3isD6T8z+2eK6liK8rPSpU="
</script>
<#+
}
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;
Expand All @@ -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;
#>
Expand All @@ -115,7 +115,7 @@ Render_Component_MtContext6(__data: __data, arg3: (new test()));
</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()));
Expand Down

0 comments on commit 0edf64a

Please sign in to comment.