diff --git a/src/React.Core/Exceptions/ReactEngineNotFoundException.cs b/src/React.Core/Exceptions/ReactEngineNotFoundException.cs
index e2ca4cf8f..2e218884f 100644
--- a/src/React.Core/Exceptions/ReactEngineNotFoundException.cs
+++ b/src/React.Core/Exceptions/ReactEngineNotFoundException.cs
@@ -25,6 +25,12 @@ public class ReactEngineNotFoundException : ReactException
///
public ReactEngineNotFoundException() : base(GetMessage()) { }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The message that describes the error.
+ public ReactEngineNotFoundException(string message) : base(message) { }
+
#if NET40
///
/// Used by deserialization
@@ -40,8 +46,8 @@ private static string GetMessage()
{
return
"No usable JavaScript engine was found. Please install a JavaScript engine such " +
- "as React.JavaScriptEngine.ClearScriptV8 (on Windows) or " +
- "React.JavaScriptEngine.VroomJs (on Linux and Mac OS X). Refer to the ReactJS.NET " +
+ "as JavaScriptEngineSwitcher.V8.V8JsEngine (on Windows) or " +
+ "React.VroomJsEngine (on Linux and Mac OS X). Refer to the ReactJS.NET " +
"documentation for more details.";
}
}
diff --git a/src/React.Core/JavaScriptEngineFactory.cs b/src/React.Core/JavaScriptEngineFactory.cs
index 073f7b791..45d038674 100644
--- a/src/React.Core/JavaScriptEngineFactory.cs
+++ b/src/React.Core/JavaScriptEngineFactory.cs
@@ -251,6 +251,23 @@ public virtual void ReturnEngineToPool(IJsEngine engine)
private static Func GetFactory(JsEngineSwitcher jsEngineSwitcher, bool allowMsie)
{
EnsureJsEnginesRegistered(jsEngineSwitcher, allowMsie);
+
+ string defaultEngineName = jsEngineSwitcher.DefaultEngineName;
+ if (!string.IsNullOrWhiteSpace(defaultEngineName))
+ {
+ var engineFactory = jsEngineSwitcher.EngineFactories.Get(defaultEngineName);
+ if (engineFactory != null)
+ {
+ return engineFactory.CreateEngine;
+ }
+ else
+ {
+ throw new ReactEngineNotFoundException(
+ "Could not find a factory, that creates an instance of the JavaScript " +
+ "engine with name `" + defaultEngineName + "`.");
+ }
+ }
+
foreach (var engineFactory in jsEngineSwitcher.EngineFactories)
{
IJsEngine engine = null;
diff --git a/tests/React.Tests/Core/JavaScriptEngineFactoryTest.cs b/tests/React.Tests/Core/JavaScriptEngineFactoryTest.cs
index 0363ae8fa..925243071 100644
--- a/tests/React.Tests/Core/JavaScriptEngineFactoryTest.cs
+++ b/tests/React.Tests/Core/JavaScriptEngineFactoryTest.cs
@@ -19,6 +19,9 @@ namespace React.Tests.Core
{
public class JavaScriptEngineFactoryTest
{
+ private static object _engineSwitcherSynchronizer = new object();
+
+
private JavaScriptEngineFactory CreateBasicFactory()
{
var config = new Mock();
@@ -44,11 +47,17 @@ Func innerEngineFactory
engineFactory.Setup(x => x.CreateEngine()).Returns(innerEngineFactory);
// JsEngineSwitcher is a singleton :(
- var engineFactories = JsEngineSwitcher.Instance.EngineFactories;
- engineFactories.Clear();
- engineFactories.Add(engineFactory.Object);
-
- return new JavaScriptEngineFactory(JsEngineSwitcher.Instance, config.Object, fileSystem.Object);
+ lock (_engineSwitcherSynchronizer)
+ {
+ var engineSwitcher = JsEngineSwitcher.Instance;
+ engineSwitcher.DefaultEngineName = string.Empty;
+
+ var engineFactories = engineSwitcher.EngineFactories;
+ engineFactories.Clear();
+ engineFactories.Add(engineFactory.Object);
+
+ return new JavaScriptEngineFactory(engineSwitcher, config.Object, fileSystem.Object);
+ }
}
[Fact]
@@ -176,5 +185,116 @@ public void ShouldCatchErrorsWhileLoadingScripts()
var ex = Assert.Throws(() => factory.GetEngineForCurrentThread());
Assert.Equal("Error while loading \"foo.js\": Fail\r\nLine: 42\r\nColumn: 911", ex.Message);
}
+
+ [Fact]
+ public void ShouldReturnDefaultEngine()
+ {
+ const string someEngineName = "SomeEngine";
+ const string defaultEngineName = "DefaultEngine";
+ const string someOtherEngineName = "SomeOtherEngine";
+
+ var someEngineFactory = new Mock();
+ someEngineFactory.Setup(x => x.EngineName).Returns(someEngineName);
+ someEngineFactory.Setup(x => x.CreateEngine()).Returns(() =>
+ {
+ var someEngine = new Mock();
+ someEngine.Setup(x => x.Name).Returns(someEngineName);
+ return someEngine.Object;
+ });
+
+ var defaultEngineFactory = new Mock();
+ defaultEngineFactory.Setup(x => x.EngineName).Returns(defaultEngineName);
+ defaultEngineFactory.Setup(x => x.CreateEngine()).Returns(() =>
+ {
+ var defaultEngine = new Mock();
+ defaultEngine.Setup(x => x.Name).Returns(defaultEngineName);
+ return defaultEngine.Object;
+ });
+
+ var someOtherEngineFactory = new Mock();
+ someOtherEngineFactory.Setup(x => x.EngineName).Returns(someOtherEngineName);
+ someOtherEngineFactory.Setup(x => x.CreateEngine()).Returns(() =>
+ {
+ var someOtherEngine = new Mock();
+ someOtherEngine.Setup(x => x.Name).Returns(someOtherEngineName);
+ return someOtherEngine.Object;
+ });
+
+ var config = new Mock();
+ config.Setup(x => x.ScriptsWithoutTransform).Returns(new List());
+ config.Setup(x => x.LoadReact).Returns(true);
+
+ var fileSystem = new Mock();
+
+ JavaScriptEngineFactory factory;
+
+ // JsEngineSwitcher is a singleton :(
+ lock (_engineSwitcherSynchronizer)
+ {
+ var engineSwitcher = JsEngineSwitcher.Instance;
+ engineSwitcher.DefaultEngineName = defaultEngineName;
+
+ var engineFactories = engineSwitcher.EngineFactories;
+ engineFactories.Clear();
+ engineFactories.Add(someEngineFactory.Object);
+ engineFactories.Add(defaultEngineFactory.Object);
+ engineFactories.Add(someOtherEngineFactory.Object);
+
+ factory = new JavaScriptEngineFactory(engineSwitcher, config.Object, fileSystem.Object);
+ }
+
+ var engine = factory.GetEngineForCurrentThread();
+
+ Assert.Equal(defaultEngineName, engine.Name);
+ }
+
+ [Fact]
+ public void ShouldThrowIfDefaultEngineFactoryNotFound()
+ {
+ const string someEngineName = "SomeEngine";
+ const string defaultEngineName = "DefaultEngine";
+ const string someOtherEngineName = "SomeOtherEngine";
+
+ var someEngineFactory = new Mock();
+ someEngineFactory.Setup(x => x.EngineName).Returns(someEngineName);
+ someEngineFactory.Setup(x => x.CreateEngine()).Returns(() =>
+ {
+ var someEngine = new Mock();
+ someEngine.Setup(x => x.Name).Returns(someEngineName);
+ return someEngine.Object;
+ });
+
+ var someOtherEngineFactory = new Mock();
+ someOtherEngineFactory.Setup(x => x.EngineName).Returns(someOtherEngineName);
+ someOtherEngineFactory.Setup(x => x.CreateEngine()).Returns(() =>
+ {
+ var someOtherEngine = new Mock();
+ someOtherEngine.Setup(x => x.Name).Returns(someOtherEngineName);
+ return someOtherEngine.Object;
+ });
+
+ var config = new Mock();
+ config.Setup(x => x.ScriptsWithoutTransform).Returns(new List());
+ config.Setup(x => x.LoadReact).Returns(true);
+
+ var fileSystem = new Mock();
+
+ // JsEngineSwitcher is a singleton :(
+ lock (_engineSwitcherSynchronizer)
+ {
+ var engineSwitcher = JsEngineSwitcher.Instance;
+ engineSwitcher.DefaultEngineName = defaultEngineName;
+
+ var engineFactories = engineSwitcher.EngineFactories;
+ engineFactories.Clear();
+ engineFactories.Add(someEngineFactory.Object);
+ engineFactories.Add(someOtherEngineFactory.Object);
+
+ Assert.Throws(() =>
+ {
+ var factory = new JavaScriptEngineFactory(engineSwitcher, config.Object, fileSystem.Object);
+ });
+ }
+ }
}
}