Skip to content

Commit 7df5fa2

Browse files
Added null and decimal marshaling options to WindowsScriptEngine.
1 parent aa16a8a commit 7df5fa2

4 files changed

Lines changed: 87 additions & 1 deletion

File tree

ClearScript/Windows/WindowsScriptEngine.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,11 @@ internal override object MarshalToScript(object obj, HostItemFlags flags)
426426
{
427427
if (obj == null)
428428
{
429+
if (engineFlags.HasFlag(WindowsScriptEngineFlags.MarshalNullAsDispatch))
430+
{
431+
return new DispatchWrapper(null);
432+
}
433+
429434
return DBNull.Value;
430435
}
431436

@@ -439,6 +444,11 @@ internal override object MarshalToScript(object obj, HostItemFlags flags)
439444
return null;
440445
}
441446

447+
if (engineFlags.HasFlag(WindowsScriptEngineFlags.MarshalDecimalAsCurrency) && (obj is decimal))
448+
{
449+
return new CurrencyWrapper(obj);
450+
}
451+
442452
var hostItem = obj as HostItem;
443453
if (hostItem != null)
444454
{

ClearScript/Windows/WindowsScriptEngineFlags.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ public enum WindowsScriptEngineFlags
9292
/// <summary>
9393
/// Specifies that script language features that enhance standards compliance are to be enabled. This option only affects <see cref="JScriptEngine"/>.
9494
/// </summary>
95-
EnableStandardsMode = 0x00000008
95+
EnableStandardsMode = 0x00000008,
96+
97+
/// <summary>
98+
/// Specifies that <c>null</c> is to be marshaled as a variant of type <c>VT_DISPATCH</c>.
99+
/// </summary>
100+
MarshalNullAsDispatch = 0x00000010,
101+
102+
/// <summary>
103+
/// Specifies that <see cref="decimal"/> values are to be marshaled as variants of type <c>VT_CY</c>.
104+
/// </summary>
105+
MarshalDecimalAsCurrency = 0x00000020
96106
}
97107
}

ClearScriptTest/JScriptEngineTest.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -967,9 +967,44 @@ public void JScriptEngine_GetStackTrace()
967967
[TestMethod, TestCategory("JScriptEngine")]
968968
public void JScriptEngine_StandardsMode()
969969
{
970+
// ReSharper disable AccessToDisposedClosure
971+
972+
TestUtil.AssertException<ScriptEngineException>(() => engine.Evaluate("JSON"));
973+
970974
engine.Dispose();
971975
engine = new JScriptEngine(WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.EnableStandardsMode);
976+
972977
Assert.AreEqual("{\"foo\":123,\"bar\":456.789}", engine.Evaluate("JSON.stringify({ foo: 123, bar: 456.789 })"));
978+
979+
// ReSharper restore AccessToDisposedClosure
980+
}
981+
982+
[TestMethod, TestCategory("JScriptEngine")]
983+
public void JScriptEngine_MarshalNullAsDispatch()
984+
{
985+
engine.Script.func = new Func<object>(() => null);
986+
Assert.IsTrue((bool)engine.Evaluate("func() === null"));
987+
988+
engine.Dispose();
989+
engine = new JScriptEngine(WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.MarshalNullAsDispatch);
990+
991+
engine.Script.func = new Func<object>(() => null);
992+
Assert.IsTrue((bool)engine.Evaluate("func() === null"));
993+
}
994+
995+
[TestMethod, TestCategory("JScriptEngine")]
996+
public void JScriptEngine_MarshalDecimalAsCurrency()
997+
{
998+
engine.Script.func = new Func<object>(() => 123.456M);
999+
Assert.AreEqual("number", engine.Evaluate("typeof(func())"));
1000+
Assert.AreEqual(123.456 + 5, engine.Evaluate("func() + 5"));
1001+
1002+
engine.Dispose();
1003+
engine = new JScriptEngine(WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.MarshalDecimalAsCurrency);
1004+
1005+
engine.Script.func = new Func<object>(() => 123.456M);
1006+
Assert.AreEqual("number", engine.Evaluate("typeof(func())"));
1007+
Assert.AreEqual(123.456 + 5, engine.Evaluate("func() + 5"));
9731008
}
9741009

9751010
// ReSharper restore InconsistentNaming

ClearScriptTest/VBScriptEngineTest.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,37 @@ public void VBScriptEngine_StandardsMode()
912912
VBScriptEngine_Execute();
913913
}
914914

915+
[TestMethod, TestCategory("VBScriptEngine")]
916+
public void VBScriptEngine_MarshalNullAsDispatch()
917+
{
918+
engine.Script.func = new Func<object>(() => null);
919+
Assert.IsTrue((bool)engine.Evaluate("IsNull(func())"));
920+
921+
engine.Dispose();
922+
engine = new VBScriptEngine(WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.MarshalNullAsDispatch);
923+
924+
engine.Script.func = new Func<object>(() => null);
925+
Assert.IsTrue((bool)engine.Evaluate("func() is nothing"));
926+
}
927+
928+
[TestMethod, TestCategory("VBScriptEngine")]
929+
public void VBScriptEngine_MarshalDecimalAsCurrency()
930+
{
931+
// ReSharper disable AccessToDisposedClosure
932+
933+
engine.Script.func = new Func<object>(() => 123.456M);
934+
TestUtil.AssertException<ScriptEngineException>(() => engine.Evaluate("TypeName(func())"));
935+
936+
engine.Dispose();
937+
engine = new VBScriptEngine(WindowsScriptEngineFlags.EnableDebugging | WindowsScriptEngineFlags.MarshalDecimalAsCurrency);
938+
939+
engine.Script.func = new Func<object>(() => 123.456M);
940+
Assert.AreEqual("Currency", engine.Evaluate("TypeName(func())"));
941+
Assert.AreEqual(123.456M + 5, engine.Evaluate("func() + 5"));
942+
943+
// ReSharper restore AccessToDisposedClosure
944+
}
945+
915946
// ReSharper restore InconsistentNaming
916947

917948
#endregion

0 commit comments

Comments
 (0)