Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix properties are not passed to slot render methods #45

Merged
merged 2 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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