Skip to content

Commit 033b617

Browse files
committed
Merge pull request scriptcs#755 from ztone/mono-eval-tests
Add engine tests for Mono
2 parents 44f014f + 1019b1b commit 033b617

6 files changed

Lines changed: 384 additions & 14 deletions

File tree

src/ScriptCs.Engine.Mono/MonoScriptEngine.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ public ScriptResult Execute(string code, string[] scriptArgs, AssemblyReferences
3535
Guard.AgainstNullArgument("scriptPackSession", scriptPackSession);
3636

3737
references.PathReferences.UnionWith(scriptPackSession.References);
38-
var parser = new SyntaxParser();
3938

4039
SessionState<Evaluator> sessionState;
4140
if (!scriptPackSession.State.ContainsKey(SessionKey))
@@ -85,29 +84,36 @@ public ScriptResult Execute(string code, string[] scriptArgs, AssemblyReferences
8584
}
8685

8786
Logger.Debug("Starting execution");
87+
var result = Execute(code, sessionState.Session);
88+
Logger.Debug("Finished execution");
89+
return result;
90+
}
8891

92+
protected virtual ScriptResult Execute(string code, Evaluator session)
93+
{
8994
try
9095
{
96+
var parser = new SyntaxParser();
9197
var parseResult = parser.Parse(code);
9298

9399
if (parseResult.TypeDeclarations != null && parseResult.TypeDeclarations.Any())
94100
{
95101
foreach (var @class in parseResult.TypeDeclarations)
96102
{
97-
sessionState.Session.Compile(@class);
103+
session.Compile(@class);
98104
}
99105
}
100106

101107
if (parseResult.MethodExpressions != null && parseResult.MethodExpressions.Any())
102108
{
103109
foreach (var prototype in parseResult.MethodPrototypes)
104110
{
105-
sessionState.Session.Run(prototype);
111+
session.Run(prototype);
106112
}
107113

108114
foreach (var method in parseResult.MethodExpressions)
109115
{
110-
sessionState.Session.Run(method);
116+
session.Run(method);
111117
}
112118
}
113119

@@ -116,9 +122,7 @@ public ScriptResult Execute(string code, string[] scriptArgs, AssemblyReferences
116122
object scriptResult;
117123
bool resultSet;
118124

119-
sessionState.Session.Evaluate(parseResult.Evaluations, out scriptResult, out resultSet);
120-
121-
Logger.Debug("Finished execution");
125+
session.Evaluate(parseResult.Evaluations, out scriptResult, out resultSet);
122126

123127
return new ScriptResult(returnValue: scriptResult);
124128
}

test/ScriptCs.Core.Tests/packages.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<package id="AutoFixture.Xunit" version="3.18.8" targetFramework="net45" />
66
<package id="Common.Logging" version="2.1.2" targetFramework="net45" />
77
<package id="Microsoft.Web.Xdt" version="2.1.0" targetFramework="net45" />
8+
<package id="Mono.CSharp" version="3.4.0" targetFramework="net45" />
89
<package id="Moq" version="4.2.1402.2112" targetFramework="net45" />
910
<package id="NuGet.Core" version="2.8.2" targetFramework="net45" />
1011
<package id="Should" version="1.1.20" targetFramework="net45" />
Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
extern alias MonoCSharp;
2+
3+
using System.Linq;
4+
5+
using Common.Logging;
6+
using Moq;
7+
using MonoCSharp::Mono.CSharp;
8+
using Ploeh.AutoFixture.Xunit;
9+
10+
using ScriptCs.Tests;
11+
using ScriptCs.Contracts;
12+
13+
using Should;
14+
15+
using Xunit.Extensions;
16+
17+
namespace ScriptCs.Engine.Mono.Tests
18+
{
19+
public class MonoScriptEngineTests
20+
{
21+
public class TheExecuteMethod
22+
{
23+
[Theory, ScriptCsAutoData]
24+
public void ShouldCreateScriptHostWithContexts(
25+
[Frozen] Mock<IScriptHostFactory> scriptHostFactory,
26+
[Frozen] Mock<IScriptPack> scriptPack,
27+
ScriptPackSession scriptPackSession,
28+
[NoAutoProperties] MonoScriptEngine engine)
29+
{
30+
// Arrange
31+
const string Code = "var a = 0;";
32+
33+
scriptHostFactory.Setup(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()))
34+
.Returns<IScriptPackManager, string[]>((p, q) => new ScriptHost(p, new ScriptEnvironment(q)));
35+
36+
scriptPack.Setup(p => p.Initialize(It.IsAny<IScriptPackSession>()));
37+
scriptPack.Setup(p => p.GetContext()).Returns((IScriptPackContext)null);
38+
39+
// Act
40+
engine.Execute(Code, new string[0], new AssemblyReferences(), Enumerable.Empty<string>(), scriptPackSession);
41+
42+
// Assert
43+
scriptHostFactory.Verify(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()));
44+
}
45+
46+
[Theory, ScriptCsAutoData]
47+
public void ShouldReuseExistingSessionIfProvided(
48+
[Frozen] Mock<IScriptHostFactory> scriptHostFactory,
49+
[NoAutoProperties] MonoTestScriptEngine engine,
50+
ScriptPackSession scriptPackSession)
51+
{
52+
// Arrange
53+
const string Code = "var a = 0;";
54+
55+
scriptHostFactory.Setup(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()))
56+
.Returns<IScriptPackManager, string[]>((p, q) => new ScriptHost(p, new ScriptEnvironment(q)));
57+
58+
var session = new SessionState<Evaluator> { Session = new Evaluator(new CompilerContext( new CompilerSettings(), new ConsoleReportPrinter())) };
59+
scriptPackSession.State[MonoScriptEngine.SessionKey] = session;
60+
61+
// Act
62+
engine.Execute(Code, new string[0], new AssemblyReferences(), Enumerable.Empty<string>(), scriptPackSession);
63+
64+
// Assert
65+
engine.Session.ShouldEqual(session.Session);
66+
}
67+
68+
[Theory, ScriptCsAutoData]
69+
public void ShouldCreateNewSessionIfNotProvided(
70+
[Frozen] Mock<IScriptHostFactory> scriptHostFactory,
71+
[NoAutoProperties] MonoTestScriptEngine engine,
72+
ScriptPackSession scriptPackSession)
73+
{
74+
// Arrange
75+
const string Code = "var a = 0;";
76+
77+
scriptHostFactory.Setup(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()))
78+
.Returns<IScriptPackManager, string[]>((p, q) => new ScriptHost(p, new ScriptEnvironment(q)));
79+
80+
// Act
81+
engine.Execute(Code, new string[0], new AssemblyReferences(), Enumerable.Empty<string>(), scriptPackSession);
82+
83+
// Assert
84+
engine.Session.ShouldNotBeNull();
85+
}
86+
87+
[Theory, ScriptCsAutoData]
88+
public void ShouldAddNewReferencesIfTheyAreProvided(
89+
[Frozen] Mock<IScriptHostFactory> scriptHostFactory,
90+
[NoAutoProperties] MonoTestScriptEngine engine,
91+
ScriptPackSession scriptPackSession)
92+
{
93+
// Arrange
94+
const string Code = "var a = 0;";
95+
96+
scriptHostFactory.Setup(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()))
97+
.Returns<IScriptPackManager, string[]>((p, q) => new ScriptHost(p, new ScriptEnvironment(q)));
98+
99+
var session = new SessionState<Evaluator> { Session = new Evaluator(new CompilerContext( new CompilerSettings(), new ConsoleReportPrinter())) };
100+
scriptPackSession.State[MonoScriptEngine.SessionKey] = session;
101+
var refs = new AssemblyReferences();
102+
refs.PathReferences.Add("System");
103+
104+
// Act
105+
engine.Execute(Code, new string[0], refs, Enumerable.Empty<string>(), scriptPackSession);
106+
107+
// Assert
108+
((SessionState<Evaluator>)scriptPackSession.State[MonoScriptEngine.SessionKey]).References.PathReferences.Count().ShouldEqual(1);
109+
}
110+
111+
[Theory, ScriptCsAutoData]
112+
public void ShouldReturnAScriptResult(
113+
[Frozen] Mock<IScriptHostFactory> scriptHostFactory,
114+
[NoAutoProperties] MonoScriptEngine engine,
115+
ScriptPackSession scriptPackSession)
116+
{
117+
// Arrange
118+
var code = string.Empty;
119+
120+
scriptHostFactory.Setup(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()))
121+
.Returns<IScriptPackManager, string[]>((p, q) => new ScriptHost(p, new ScriptEnvironment(q)));
122+
123+
var session = new SessionState<Evaluator> { Session = new Evaluator(new CompilerContext( new CompilerSettings(), new ConsoleReportPrinter())) };
124+
scriptPackSession.State[MonoScriptEngine.SessionKey] = session;
125+
var refs = new AssemblyReferences();
126+
refs.PathReferences.Add("System");
127+
128+
// Act
129+
var result = engine.Execute(code, new string[0], refs, Enumerable.Empty<string>(), scriptPackSession);
130+
131+
// Assert
132+
result.ShouldBeType<ScriptResult>();
133+
}
134+
135+
// Need to get the compiler ex from mono.
136+
// Currently the ConsoleReportWriter is swallowing the ex
137+
/*
138+
[Theory, ScriptCsAutoData]
139+
public void ShouldReturnCompileExceptionIfCodeDoesNotCompile(
140+
[Frozen] Mock<IScriptHostFactory> scriptHostFactory,
141+
[NoAutoProperties] MonoScriptEngine engine,
142+
ScriptPackSession scriptPackSession)
143+
{
144+
// Arrange
145+
const string Code = "this shold not compile";
146+
147+
scriptHostFactory.Setup(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()))
148+
.Returns<IScriptPackManager, string[]>((p, q) => new ScriptHost(p, new ScriptEnvironment(q)));
149+
150+
var session = new SessionState<Evaluator> { Session = new Evaluator(new CompilerContext( new CompilerSettings(), new ConsoleReportPrinter())) };
151+
scriptPackSession.State[MonoScriptEngine.SessionKey] = session;
152+
var refs = new AssemblyReferences();
153+
refs.PathReferences.Add("System");
154+
155+
// Act
156+
var result = engine.Execute(Code, new string[0], refs, Enumerable.Empty<string>(), scriptPackSession);
157+
158+
System.Threading.Thread.Sleep(1000);
159+
160+
// Assert
161+
result.CompileExceptionInfo.ShouldNotBeNull();
162+
}
163+
*/
164+
165+
[Theory, ScriptCsAutoData]
166+
public void ShouldNotReturnCompileExceptionIfCodeDoesCompile(
167+
[Frozen] Mock<IScriptHostFactory> scriptHostFactory,
168+
[NoAutoProperties] MonoScriptEngine engine,
169+
ScriptPackSession scriptPackSession)
170+
{
171+
// Arrange
172+
const string Code = "var theNumber = 42; //this should compile";
173+
174+
scriptHostFactory.Setup(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()))
175+
.Returns<IScriptPackManager, string[]>((p, q) => new ScriptHost(p, new ScriptEnvironment(q)));
176+
177+
var session = new SessionState<Evaluator> { Session = new Evaluator(new CompilerContext( new CompilerSettings(), new ConsoleReportPrinter())) };
178+
scriptPackSession.State[MonoScriptEngine.SessionKey] = session;
179+
var refs = new AssemblyReferences();
180+
refs.PathReferences.Add("System");
181+
182+
// Act
183+
var result = engine.Execute(Code, new string[0], refs, Enumerable.Empty<string>(), scriptPackSession);
184+
185+
// Assert
186+
result.ShouldBeType<ScriptResult>();
187+
result.CompileExceptionInfo.ShouldBeNull();
188+
result.ExecuteExceptionInfo.ShouldBeNull();
189+
}
190+
191+
[Theory, ScriptCsAutoData]
192+
public void ShouldReturnExecuteExceptionIfCodeExecutionThrowsException(
193+
[Frozen] Mock<IScriptHostFactory> scriptHostFactory,
194+
[NoAutoProperties] MonoScriptEngine engine,
195+
ScriptPackSession scriptPackSession)
196+
{
197+
// Arrange
198+
const string Code = "throw new System.Exception(); //this should throw an Exception";
199+
200+
scriptHostFactory.Setup(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()))
201+
.Returns<IScriptPackManager, string[]>((p, q) => new ScriptHost(p, new ScriptEnvironment(q)));
202+
203+
var session = new SessionState<Evaluator> { Session = new Evaluator(new CompilerContext( new CompilerSettings(), new ConsoleReportPrinter())) };
204+
scriptPackSession.State[MonoScriptEngine.SessionKey] = session;
205+
var refs = new AssemblyReferences();
206+
refs.PathReferences.Add("System");
207+
208+
// Act
209+
var result = engine.Execute(Code, new string[0], refs, Enumerable.Empty<string>(), scriptPackSession);
210+
211+
// Assert
212+
result.ExecuteExceptionInfo.ShouldNotBeNull();
213+
}
214+
215+
[Theory, ScriptCsAutoData]
216+
public void ShouldNotReturnExecuteExceptionIfCodeExecutionDoesNotThrowAnException(
217+
[Frozen] Mock<IScriptHostFactory> scriptHostFactory,
218+
[NoAutoProperties] MonoScriptEngine engine,
219+
ScriptPackSession scriptPackSession)
220+
{
221+
// Arrange
222+
const string Code = "var theNumber = 42; //this should not throw an Exception";
223+
224+
scriptHostFactory.Setup(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()))
225+
.Returns<IScriptPackManager, string[]>((p, q) => new ScriptHost(p, new ScriptEnvironment(q)));
226+
227+
var session = new SessionState<Evaluator> { Session = new Evaluator(new CompilerContext( new CompilerSettings(), new ConsoleReportPrinter())) };
228+
scriptPackSession.State[MonoScriptEngine.SessionKey] = session;
229+
var refs = new AssemblyReferences();
230+
refs.PathReferences.Add("System");
231+
232+
// Act
233+
var result = engine.Execute(Code, new string[0], refs, Enumerable.Empty<string>(), scriptPackSession);
234+
235+
// Assert
236+
result.ExecuteExceptionInfo.ShouldBeNull();
237+
}
238+
239+
[Theory, ScriptCsAutoData]
240+
public void ShouldReturnReturnValueIfCodeExecutionReturnsValue(
241+
[Frozen] Mock<IScriptHostFactory> scriptHostFactory,
242+
[NoAutoProperties] MonoScriptEngine engine,
243+
ScriptPackSession scriptPackSession)
244+
{
245+
// Mono doesn't support comments after evals as well as Roslyn
246+
const string Code = "\"Hello\""; //this should return \"Hello\"";
247+
248+
// Arrange
249+
scriptHostFactory.Setup(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()))
250+
.Returns<IScriptPackManager, string[]>((p, q) => new ScriptHost(p, new ScriptEnvironment(q)));
251+
252+
var session = new SessionState<Evaluator> { Session = new Evaluator(new CompilerContext( new CompilerSettings(), new ConsoleReportPrinter())) };
253+
scriptPackSession.State[MonoScriptEngine.SessionKey] = session;
254+
var refs = new AssemblyReferences();
255+
refs.PathReferences.Add("System");
256+
257+
// Act
258+
var result = engine.Execute(Code, new string[0], refs, Enumerable.Empty<string>(), scriptPackSession);
259+
260+
// Assert
261+
result.ReturnValue.ShouldEqual("Hello");
262+
}
263+
264+
[Theory, ScriptCsAutoData]
265+
public void ShouldNotReturnReturnValueIfCodeExecutionDoesNotReturnValue(
266+
[Frozen] Mock<IScriptHostFactory> scriptHostFactory,
267+
[NoAutoProperties] MonoScriptEngine engine,
268+
ScriptPackSession scriptPackSession)
269+
{
270+
// Arrange
271+
const string Code = "var theNumber = 42; //this should not return a value";
272+
273+
scriptHostFactory.Setup(f => f.CreateScriptHost(It.IsAny<IScriptPackManager>(), It.IsAny<string[]>()))
274+
.Returns<IScriptPackManager, string[]>((p, q) => new ScriptHost(p, new ScriptEnvironment(q)));
275+
276+
var session = new SessionState<Evaluator> { Session = new Evaluator(new CompilerContext( new CompilerSettings(), new ConsoleReportPrinter())) };
277+
scriptPackSession.State[MonoScriptEngine.SessionKey] = session;
278+
var refs = new AssemblyReferences();
279+
refs.PathReferences.Add("System");
280+
281+
// Act
282+
var result = engine.Execute(Code, new string[0], refs, Enumerable.Empty<string>(), scriptPackSession);
283+
284+
// Assert
285+
result.ReturnValue.ShouldBeNull();
286+
}
287+
}
288+
289+
public class MonoTestScriptEngine : MonoScriptEngine
290+
{
291+
public MonoTestScriptEngine(IScriptHostFactory scriptHostFactory, ILog logger)
292+
: base(scriptHostFactory, logger)
293+
{
294+
}
295+
296+
public Evaluator Session { get; private set; }
297+
298+
protected override ScriptResult Execute(string code, Evaluator session)
299+
{
300+
Session = session;
301+
return ScriptResult.Empty;
302+
}
303+
}
304+
}
305+
}

0 commit comments

Comments
 (0)