Skip to content

Commit 2a1ead6

Browse files
exyitomasherceg
authored andcommitted
Add some more tests for ParametrizedCodes with default values in symbols
1 parent e4eca58 commit 2a1ead6

File tree

3 files changed

+126
-14
lines changed

3 files changed

+126
-14
lines changed

src/Framework/Framework/Compilation/Javascript/ParametrizedCode.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ public ParametrizedCode AssignParameters(Func<CodeSymbolicParameter, CodeParamet
178178
var isGlobalContext = a.IsGlobalContext && param.IsSafeMemberAccess;
179179

180180
if (isGlobalContext)
181-
builder.Add(stringParts[1 + i].AsSpan(1, stringParts[i].Length - 1).DotvvmInternString()); // skip `.`
181+
builder.Add(stringParts[1 + i].AsSpan(1, stringParts[1 + i].Length - 1).DotvvmInternString()); // skip `.`
182182
else
183183
{
184184
builder.Add(a.Code, param.OperatorPrecedence);

src/Tests/Runtime/JavascriptCompilation/JsFormatterTests.cs

-13
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
using DotVVM.Framework.Compilation.Javascript.Ast;
22
using Microsoft.VisualStudio.TestTools.UnitTesting;
3-
using System;
43
using System.Collections.Generic;
54
using System.Text;
6-
using DotVVM.Framework.Compilation.Javascript;
75
using static DotVVM.Framework.Tests.Runtime.JavascriptCompilation.JsParensInsertionTests;
86

97
namespace DotVVM.Framework.Tests.Runtime.JavascriptCompilation
@@ -47,17 +45,6 @@ public void JsFormatter_Indexer()
4745
AssertFormatting("a[b]", new JsIdentifierExpression("a").Indexer(new JsIdentifierExpression("b")));
4846
}
4947

50-
[TestMethod]
51-
public void JsFormatter_SymbolicParameter_Global()
52-
{
53-
var symbol = new CodeSymbolicParameter();
54-
Assert.AreEqual("a+global",
55-
new JsBinaryExpression(new JsMemberAccessExpression(new JsSymbolicParameter(symbol), "a"), BinaryOperatorType.Plus,
56-
new JsSymbolicParameter(symbol))
57-
.FormatParametrizedScript().ToString(o => o == symbol ? CodeParameterAssignment.FromExpression(new JsIdentifierExpression("global"), isGlobalContext: true) :
58-
throw new Exception()));
59-
}
60-
6148
[TestMethod]
6249
public void JsFormatter_FunctionExpression()
6350
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
using DotVVM.Framework.Compilation.Javascript.Ast;
2+
using Microsoft.VisualStudio.TestTools.UnitTesting;
3+
using System;
4+
using DotVVM.Framework.Compilation.Javascript;
5+
6+
namespace DotVVM.Framework.Tests.Runtime.JavascriptCompilation
7+
{
8+
[TestClass]
9+
public class JsParametrizedCodeTests
10+
{
11+
static CodeSymbolicParameter symbolA = new CodeSymbolicParameter("A");
12+
static CodeSymbolicParameter symbolB = new CodeSymbolicParameter("B");
13+
static CodeSymbolicParameter symbolC = new CodeSymbolicParameter("C", defaultAssignment: new JsIdentifier("defaultValue").FormatParametrizedScript());
14+
static CodeSymbolicParameter symbolD = new CodeSymbolicParameter("D", defaultAssignment: new JsBinaryExpression(new JsSymbolicParameter(symbolA), BinaryOperatorType.Times, new JsSymbolicParameter(symbolC)).FormatParametrizedScript());
15+
static CodeSymbolicParameter symbolE = new CodeSymbolicParameter("E", defaultAssignment: new JsBinaryExpression(new JsSymbolicParameter(symbolA), BinaryOperatorType.Plus, new JsSymbolicParameter(symbolD)).FormatParametrizedScript());
16+
17+
[TestMethod]
18+
public void SymbolicParameters_Global()
19+
{
20+
// full would be "global.a+global
21+
var pcode = new JsBinaryExpression(new JsMemberAccessExpression(new JsSymbolicParameter(symbolA), "a"), BinaryOperatorType.Plus,
22+
new JsSymbolicParameter(symbolA))
23+
.FormatParametrizedScript();
24+
Assert.AreEqual("a+global",
25+
pcode.ToString(o => o == symbolA ? CodeParameterAssignment.FromExpression(new JsIdentifierExpression("global"), isGlobalContext: true) :
26+
throw new Exception()));
27+
Assert.AreEqual("a+global",
28+
pcode.AssignParameters(o => o == symbolA ? CodeParameterAssignment.FromExpression(new JsIdentifierExpression("global"), isGlobalContext: true) :
29+
throw new Exception())
30+
.ToString(o => default));
31+
}
32+
33+
[TestMethod]
34+
public void SymbolicParameters_Global_ThroughDefault()
35+
{
36+
var globalDefaultSymbol = new CodeSymbolicParameter("global", defaultAssignment: symbolA.ToParametrizedCode());
37+
// may be "global.a+global" or "a+global" - doesn't matter if the optimization works in this case, but it shouldn't be broken
38+
var pcode = new JsBinaryExpression(new JsMemberAccessExpression(new JsSymbolicParameter(globalDefaultSymbol), "a"), BinaryOperatorType.Plus,
39+
new JsSymbolicParameter(globalDefaultSymbol))
40+
.FormatParametrizedScript();
41+
Assert.AreEqual("global.a+global",
42+
pcode.ToString(o => o == symbolA ? CodeParameterAssignment.FromExpression(new JsIdentifierExpression("global"), isGlobalContext: true) :
43+
default));
44+
Assert.AreEqual("global.a+global",
45+
pcode.AssignParameters(o => o == symbolA ? CodeParameterAssignment.FromExpression(new JsIdentifierExpression("global"), isGlobalContext: true) :
46+
default)
47+
.ToString(o => default));
48+
}
49+
50+
[TestMethod]
51+
public void SymbolicParameters_Throws_Unassigned()
52+
{
53+
var pcode = new JsBinaryExpression(new JsMemberAccessExpression(new JsSymbolicParameter(symbolA), "a"), BinaryOperatorType.Plus, new JsSymbolicParameter(symbolA)).FormatParametrizedScript();
54+
55+
var pcode2 = pcode.AssignParameters(o => default); // fine, not all have to be assigned
56+
var pcodeResolved = pcode.AssignParameters(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("x") : default);
57+
58+
Assert.AreEqual("y.a+y", pcode.ToString(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("y") : default));
59+
Assert.AreEqual("z.a+z", pcode2.ToString(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("z") : default));
60+
Assert.AreEqual("x.a+x", pcodeResolved.ToString(o => default));
61+
Assert.AreEqual("x.a+x", pcodeResolved.ToString(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("AREADY_ASSIGNED_BEFORE") : default));
62+
63+
var ex = Assert.ThrowsException<InvalidOperationException>(() => pcode.ToString(o => default));
64+
XAssert.Contains("Assignment of parameter '{A|", ex.Message);
65+
66+
ex = Assert.ThrowsException<InvalidOperationException>(() => pcode2.ToString(o => default));
67+
XAssert.Contains("Assignment of parameter '{A|", ex.Message);
68+
}
69+
70+
[TestMethod]
71+
public void SymbolicParameters_Partial_DefaultChain()
72+
{
73+
var expr = new JsBinaryExpression(symbolA.ToExpression(), BinaryOperatorType.Plus, symbolE.ToExpression());
74+
var pcode = expr.FormatParametrizedScript();
75+
76+
Assert.AreEqual("x+(x+x*defaultValue)", pcode.ToString(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("x") : default));
77+
Assert.AreEqual("y+(y+y*defaultValue)", pcode.ToString(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("y") : default));
78+
79+
// substitute symbolD for identifier, order doesn't matter
80+
Assert.AreEqual("x+(x+D)",
81+
pcode.AssignParameters(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("x") : default)
82+
.ToString(o => o == symbolD ? CodeParameterAssignment.FromExpression(new JsIdentifierExpression("D")) : default));
83+
Assert.AreEqual("x+(x+D)",
84+
pcode.AssignParameters(o => o == symbolD ? CodeParameterAssignment.FromExpression(new JsIdentifierExpression("D")) : default)
85+
.ToString(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("x") : default));
86+
87+
// substitute symbolD for symbolA, order now matters
88+
Assert.AreEqual("x+(x+x)",
89+
pcode.AssignParameters(o => o == symbolD ? CodeParameterAssignment.FromExpression(new JsSymbolicParameter(symbolA)) : default)
90+
.ToString(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("x") : default));
91+
Assert.AreEqual("x+(x+y)",
92+
pcode.AssignParameters(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("x") : default)
93+
.AssignParameters(o => o == symbolD ? CodeParameterAssignment.FromExpression(new JsSymbolicParameter(symbolA)) : default)
94+
.ToString(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("y") : default));
95+
}
96+
97+
[TestMethod]
98+
public void SymbolicParameters_AddDefault()
99+
{
100+
var expr = new JsBinaryExpression(symbolA.ToExpression(), BinaryOperatorType.Plus, symbolE.ToExpression());
101+
var pcode = expr.FormatParametrizedScript();
102+
103+
// add default for symbolA
104+
var assigned = pcode.AssignParameters(o => o == symbolA ? symbolA.ToExpression(CodeParameterAssignment.FromIdentifier("a")).FormatParametrizedScript() : default);
105+
106+
Assert.AreEqual("a+(a+a*defaultValue)", assigned.ToString(o => default));
107+
Assert.AreEqual("a+(a+a*defaultValue)", assigned.ToDefaultString());
108+
109+
Assert.AreEqual("x+(x+x*defaultValue)", assigned.ToString(o => o == symbolA ? CodeParameterAssignment.FromIdentifier("x") : default));
110+
Assert.AreEqual("a+x", assigned.ToString(o => o == symbolE ? CodeParameterAssignment.FromIdentifier("x") : default));
111+
}
112+
113+
[TestMethod]
114+
public void SymbolicParameters_NoAssignmentNoAllocation()
115+
{
116+
var expr = new JsBinaryExpression(symbolA.ToExpression(), BinaryOperatorType.Plus, symbolE.ToExpression());
117+
var pcode = expr.FormatParametrizedScript();
118+
Func<CodeSymbolicParameter, CodeParameterAssignment> noAssignment = o => default;
119+
120+
var b = GC.GetAllocatedBytesForCurrentThread();
121+
pcode.AssignParameters(noAssignment);
122+
Assert.AreEqual(0, GC.GetAllocatedBytesForCurrentThread() - b);
123+
}
124+
}
125+
}

0 commit comments

Comments
 (0)