From 2a8200f16923dd9e5a47e6ebc7c08a4bb0c8c78e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Herceg?= Date: Mon, 16 Oct 2023 21:04:29 +0200 Subject: [PATCH 1/2] Fixed string conversion bug with global function --- .../JavascriptTranslatableMethodCollection.cs | 4 ++-- .../Javascript/PrimitiveToStringTranslator.cs | 2 +- .../Common/DotVVM.Samples.Common.csproj | 1 + .../ToStringGlobalFunctionBugViewModel.cs | 18 ++++++++++++++++++ .../ToStringGlobalFunctionBug.dothtml | 19 +++++++++++++++++++ .../Abstractions/SamplesRouteUrls.designer.cs | 1 + .../Tests/Tests/Feature/FormattingTests.cs | 16 +++++++++++++++- 7 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 src/Samples/Common/ViewModels/FeatureSamples/Formatting/ToStringGlobalFunctionBugViewModel.cs create mode 100644 src/Samples/Common/Views/FeatureSamples/Formatting/ToStringGlobalFunctionBug.dothtml diff --git a/src/Framework/Framework/Compilation/Javascript/JavascriptTranslatableMethodCollection.cs b/src/Framework/Framework/Compilation/Javascript/JavascriptTranslatableMethodCollection.cs index ad843b4789..3a5fbd2f65 100644 --- a/src/Framework/Framework/Compilation/Javascript/JavascriptTranslatableMethodCollection.cs +++ b/src/Framework/Framework/Compilation/Javascript/JavascriptTranslatableMethodCollection.cs @@ -760,7 +760,7 @@ JsExpression wrapInRound(JsExpression a) => } else if (p[0].ParameterType == typeof(string) || p[0].ParameterType == typeof(bool)) { - AddMethodTranslator(m, translator: new GenericMethodCompiler(args => wrapInRound(new JsIdentifierExpression("Number").Invoke(args[1])))); + AddMethodTranslator(m, translator: new GenericMethodCompiler(args => wrapInRound(new JsIdentifierExpression("window").Member("Number").Invoke(args[1])))); } } @@ -773,7 +773,7 @@ JsExpression wrapInRound(JsExpression a) => continue; if (p[0].ParameterType.IsNumericType() && p[0].ParameterType != typeof(char)) { - AddMethodTranslator(m, translator: new GenericMethodCompiler(args => new JsIdentifierExpression("Boolean").Invoke(args[1]))); + AddMethodTranslator(m, translator: new GenericMethodCompiler(args => new JsIdentifierExpression("window").Member("Boolean").Invoke(args[1]))); } } } diff --git a/src/Framework/Framework/Compilation/Javascript/PrimitiveToStringTranslator.cs b/src/Framework/Framework/Compilation/Javascript/PrimitiveToStringTranslator.cs index ad8253b2b9..c47019a547 100644 --- a/src/Framework/Framework/Compilation/Javascript/PrimitiveToStringTranslator.cs +++ b/src/Framework/Framework/Compilation/Javascript/PrimitiveToStringTranslator.cs @@ -59,7 +59,7 @@ internal static bool CanBeNull(Expression expr) if (isNullable) js = new JsBinaryExpression(js, BinaryOperatorType.NullishCoalescing, new JsLiteral("")); if (!isStringAlready) - js = new JsIdentifierExpression("String").Invoke(js); + js = new JsIdentifierExpression("window").Member("String").Invoke(js); return js; } } diff --git a/src/Samples/Common/DotVVM.Samples.Common.csproj b/src/Samples/Common/DotVVM.Samples.Common.csproj index bd6baaecd1..d59a3ae001 100644 --- a/src/Samples/Common/DotVVM.Samples.Common.csproj +++ b/src/Samples/Common/DotVVM.Samples.Common.csproj @@ -98,6 +98,7 @@ + diff --git a/src/Samples/Common/ViewModels/FeatureSamples/Formatting/ToStringGlobalFunctionBugViewModel.cs b/src/Samples/Common/ViewModels/FeatureSamples/Formatting/ToStringGlobalFunctionBugViewModel.cs new file mode 100644 index 0000000000..c733f749e4 --- /dev/null +++ b/src/Samples/Common/ViewModels/FeatureSamples/Formatting/ToStringGlobalFunctionBugViewModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DotVVM.Framework.ViewModel; +using DotVVM.Framework.Hosting; + +namespace DotVVM.Samples.Common.ViewModels.FeatureSamples.Formatting +{ + public class ToStringGlobalFunctionBugViewModel : DotvvmViewModelBase + { + public bool Boolean { get; set; } + + public string String { get; set; } + } +} + diff --git a/src/Samples/Common/Views/FeatureSamples/Formatting/ToStringGlobalFunctionBug.dothtml b/src/Samples/Common/Views/FeatureSamples/Formatting/ToStringGlobalFunctionBug.dothtml new file mode 100644 index 0000000000..c78790870e --- /dev/null +++ b/src/Samples/Common/Views/FeatureSamples/Formatting/ToStringGlobalFunctionBug.dothtml @@ -0,0 +1,19 @@ +@viewModel DotVVM.Samples.Common.ViewModels.FeatureSamples.Formatting.ToStringGlobalFunctionBugViewModel, DotVVM.Samples.Common + + + + + + + + + + + +

Boolean: {{value: Boolean}}

+

String: {{value: String}}

+ + + + + diff --git a/src/Samples/Tests/Abstractions/SamplesRouteUrls.designer.cs b/src/Samples/Tests/Abstractions/SamplesRouteUrls.designer.cs index 89dde243e6..0d0f7f63cc 100644 --- a/src/Samples/Tests/Abstractions/SamplesRouteUrls.designer.cs +++ b/src/Samples/Tests/Abstractions/SamplesRouteUrls.designer.cs @@ -249,6 +249,7 @@ public partial class SamplesRouteUrls public const string FeatureSamples_Directives_ViewModelMissingAssembly = "FeatureSamples/Directives/ViewModelMissingAssembly"; public const string FeatureSamples_EmbeddedResourceControls_EmbeddedResourceControls = "FeatureSamples/EmbeddedResourceControls/EmbeddedResourceControls"; public const string FeatureSamples_Formatting_Formatting = "FeatureSamples/Formatting/Formatting"; + public const string FeatureSamples_Formatting_ToStringGlobalFunctionBug = "FeatureSamples/Formatting/ToStringGlobalFunctionBug"; public const string FeatureSamples_FormControlsEnabled_FormControlsEnabled = "FeatureSamples/FormControlsEnabled/FormControlsEnabled"; public const string FeatureSamples_GenericTypes_InCommandBinding = "FeatureSamples/GenericTypes/InCommandBinding"; public const string FeatureSamples_GenericTypes_InResourceBinding = "FeatureSamples/GenericTypes/InResourceBinding"; diff --git a/src/Samples/Tests/Tests/Feature/FormattingTests.cs b/src/Samples/Tests/Tests/Feature/FormattingTests.cs index 5bc3b4c50e..bc5153b643 100644 --- a/src/Samples/Tests/Tests/Feature/FormattingTests.cs +++ b/src/Samples/Tests/Tests/Feature/FormattingTests.cs @@ -55,8 +55,22 @@ public void Feature_Formatting_Formatting() }); } + [Fact] + public void Feature_Formatting_ToStringGlobalFunctionBug() + { + RunInAllBrowsers(browser => { + browser.NavigateToUrl(SamplesRouteUrls.FeatureSamples_Formatting_ToStringGlobalFunctionBug); + + AssertUI.TextEquals(browser.Single(".result-boolean"), "Boolean: false"); + AssertUI.TextEquals(browser.Single(".result-string"), "String:"); + browser.Single("input[type=button]").Click(); + AssertUI.TextEquals(browser.Single(".result-boolean"), "Boolean: true"); + AssertUI.TextEquals(browser.Single(".result-string"), "String:"); + }); + } + public FormattingTests(ITestOutputHelper output) : base(output) { + } } } -} From 4a8c0201921b8dfc1537332991260d9a2c518eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Herceg?= Date: Sun, 22 Oct 2023 10:49:14 +0200 Subject: [PATCH 2/2] Fixed unit tests --- src/Tests/Binding/JavascriptCompilationTests.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Tests/Binding/JavascriptCompilationTests.cs b/src/Tests/Binding/JavascriptCompilationTests.cs index f86d57076a..e7daabc72b 100644 --- a/src/Tests/Binding/JavascriptCompilationTests.cs +++ b/src/Tests/Binding/JavascriptCompilationTests.cs @@ -999,8 +999,8 @@ public void JsTranslator_MathMethods(string binding, string expected) } [TestMethod] - [DataRow("Convert.ToBoolean(IntProp)", "Boolean(IntProp())")] - [DataRow("Convert.ToBoolean(DoubleProp)", "Boolean(DoubleProp())")] + [DataRow("Convert.ToBoolean(IntProp)", "window.Boolean(IntProp())")] + [DataRow("Convert.ToBoolean(DoubleProp)", "window.Boolean(DoubleProp())")] [DataRow("Convert.ToDecimal(DoubleProp)", "DoubleProp")] [DataRow("Convert.ToInt32(DoubleProp)", "Math.round(DoubleProp())")] [DataRow("Convert.ToByte(DoubleProp)", "Math.round(DoubleProp())")] @@ -1261,6 +1261,7 @@ public void JavascriptCompilation_ApiRefreshOn() [TestMethod] public void JavascriptCompilation_MarkupControlProperty() { + _ = TestMarkupControl.SomePropertyProperty; var dataContext = bindingHelper.CreateDataContext(new [] { typeof(object) }, markupControl: typeof(TestMarkupControl)); var result = bindingHelper.ValueBindingToJs("_control.SomeProperty + 'aa'", dataContext, niceMode: false); Assert.AreEqual("($control.SomeProperty()??\"\")+\"aa\"", result);