public void NativeModuleRegistry_WriteModuleDefinitions() { var registry = new NativeModuleRegistry.Builder(new ReactContext()) .Add(new TestNativeModule()) .Build(); using (var stringWriter = new StringWriter()) { using (var writer = new JsonTextWriter(stringWriter)) { registry.WriteModuleDescriptions(writer); } var json = JArray.Parse(stringWriter.ToString()); Assert.AreEqual(1, json.Count); var module = json[0] as JArray; Assert.IsNotNull(module); Assert.IsTrue(module.Count >= 3); var moduleName = module[0]; Assert.AreEqual("Test", moduleName.ToString()); var methods = json[0][2] as JArray; Assert.IsNotNull(methods); var methodNames = methods.ToObject <string[]>(); Assert.IsTrue(methodNames.Contains("Foo")); Assert.IsTrue(methodNames.Contains("Bar")); } }
public void NativeModuleRegistry_ArgumentChecks() { var builder = new NativeModuleRegistry.Builder(); AssertEx.Throws<ArgumentNullException>( () => builder.Add(null), ex => Assert.AreEqual("module", ex.ParamName)); }
public void NativeModuleRegistry_Override_Disallowed() { var builder = new NativeModuleRegistry.Builder(new ReactContext()); builder.Add(new OverrideDisallowedModule()); AssertEx.Throws <InvalidOperationException>(() => builder.Add(new OverrideDisallowedModule())); }
public async Task ReactInstance_Initialize_Dispose() { var mre = new ManualResetEvent(false); var module = new TestNativeModule { OnInitialized = () => mre.Set(), }; var reactContext = new ReactContext(); var registry = new NativeModuleRegistry.Builder(reactContext) .Add(module) .Build(); var executor = new MockJavaScriptExecutor { OnCallFunctionReturnFlushedQueue = (_, __, ___) => JValue.CreateNull(), OnFlushQueue = () => JValue.CreateNull(), OnInvokeCallbackAndReturnFlushedQueue = (_, __) => JValue.CreateNull() }; var builder = new ReactInstance.Builder() { QueueConfiguration = TestReactQueueConfiguration.Create(_ => { }), Registry = registry, JavaScriptExecutorFactory = () => executor, BundleLoader = JavaScriptBundleLoader.CreateFileLoader("ms-appx:///Resources/test.js"), }; var instance = await DispatcherHelpers.CallOnDispatcherAsync(() => builder.Build()); reactContext.InitializeWithInstance(instance); await DispatcherHelpers.CallOnDispatcherAsync(async() => await instance.InitializeAsync()); var caught = false; await DispatcherHelpers.CallOnDispatcherAsync(async() => { try { await instance.InitializeAsync(); } catch (InvalidOperationException) { caught = true; } }); Assert.IsTrue(caught); mre.WaitOne(); Assert.AreEqual(1, module.InitializeCalls); await DispatcherHelpers.CallOnDispatcherAsync(instance.DisposeAsync); Assert.AreEqual(1, module.OnReactInstanceDisposeCalls); // Dispose is idempotent await DispatcherHelpers.CallOnDispatcherAsync(instance.DisposeAsync); Assert.AreEqual(1, module.OnReactInstanceDisposeCalls); Assert.IsTrue(instance.IsDisposed); }
public void NativeModuleRegistry_WriteModuleDefinitions() { var registry = new NativeModuleRegistry.Builder() .Add(new TestNativeModule()) .Build(); using (var stringWriter = new StringWriter()) { using (var writer = new JsonTextWriter(stringWriter)) { registry.WriteModuleDescriptions(writer); } var json = JArray.Parse(stringWriter.ToString()); Assert.AreEqual(1, json.Count); var module = json[0] as JArray; Assert.IsNotNull(module); Assert.IsTrue(module.Count >= 3); var moduleName = module[0]; Assert.AreEqual("Test", moduleName.ToString()); var methods = json[0][2] as JArray; Assert.IsNotNull(methods); var methodNames = methods.ToObject<string[]>(); Assert.IsTrue(methodNames.Contains("Foo")); Assert.IsTrue(methodNames.Contains("Bar")); } }
public void NativeModuleRegistry_ModuleWithNullName_Throws() { var builder = new NativeModuleRegistry.Builder(); AssertEx.Throws<ArgumentException>( () => builder.Add(new NullNameModule()), ex => Assert.AreEqual("module", ex.ParamName)); }
public void NativeModuleRegistry_ModuleWithNullName_Throws() { var builder = new NativeModuleRegistry.Builder(new ReactContext()); AssertEx.Throws <ArgumentException>( () => builder.Add(new NullNameModule()), ex => Assert.AreEqual("module", ex.ParamName)); }
public void NativeModuleRegistry_ArgumentChecks() { var builder = new NativeModuleRegistry.Builder(); AssertEx.Throws <ArgumentNullException>( () => builder.Add(null), ex => Assert.AreEqual("module", ex.ParamName)); }
public async Task ReactInstance_Initialize_Dispose() { var module = new TestNativeModule(); var registry = new NativeModuleRegistry.Builder() .Add(module) .Build(); var jsRegistry = new JavaScriptModuleRegistry.Builder().Build(); var executor = new MockJavaScriptExecutor { OnCallFunctionReturnFlushedQueue = (_, __, ___) => JValue.CreateNull(), OnFlushQueue = () => JValue.CreateNull(), OnInvokeCallbackAndReturnFlushedQueue = (_, __) => JValue.CreateNull() }; var builder = new ReactInstance.Builder() { QueueConfigurationSpec = ReactQueueConfigurationSpec.Default, Registry = registry, JavaScriptModuleRegistry = jsRegistry, JavaScriptExecutorFactory = () => executor, BundleLoader = JavaScriptBundleLoader.CreateFileLoader("ms-appx:///Resources/test.js"), NativeModuleCallExceptionHandler = _ => { }, }; var instance = await DispatcherHelpers.CallOnDispatcherAsync(() => builder.Build()); await DispatcherHelpers.RunOnDispatcherAsync(() => instance.Initialize()); var caught = false; await DispatcherHelpers.RunOnDispatcherAsync(() => { try { instance.Initialize(); } catch (InvalidOperationException) { caught = true; } }); Assert.IsTrue(caught); Assert.AreEqual(1, module.InitializeCalls); await DispatcherHelpers.CallOnDispatcherAsync(instance.DisposeAsync); Assert.AreEqual(1, module.OnReactInstanceDisposeCalls); // Dispose is idempotent await DispatcherHelpers.CallOnDispatcherAsync(instance.DisposeAsync); Assert.AreEqual(1, module.OnReactInstanceDisposeCalls); Assert.IsTrue(instance.IsDisposed); }
public void NativeModuleRegistry_Override_Allowed() { var registry = new NativeModuleRegistry.Builder(new ReactContext()) .Add(new OverrideAllowedModule()) .Add(new OverrideAllowedModule()) .Build(); Assert.AreEqual(1, registry.Modules.Count()); }
public void NativeModuleRegistry_Override_Allowed() { var registry = new NativeModuleRegistry.Builder() .Add(new OverrideAllowedModule()) .Add(new OverrideAllowedModule()) .Build(); Assert.AreEqual(1, registry.Modules.Count()); }
private void ProcessPackage( IReactPackage reactPackage, ReactContext reactContext, NativeModuleRegistry.Builder nativeRegistryBuilder) { foreach (var nativeModule in reactPackage.CreateNativeModules(reactContext)) { nativeRegistryBuilder.Add(nativeModule); } }
public async Task ReactInstance_Initialize_Dispose() { var module = new TestNativeModule(); var registry = new NativeModuleRegistry.Builder() .Add(module) .Build(); var jsRegistry = new JavaScriptModuleRegistry.Builder().Build(); var executor = new MockJavaScriptExecutor { OnCallFunctionReturnFlushedQueue = (_, __, ___) => JValue.CreateNull(), OnFlushQueue = () => JValue.CreateNull(), OnInvokeCallbackAndReturnFlushedQueue = (_, __) => JValue.CreateNull() }; var builder = new ReactInstance.Builder() { QueueConfigurationSpec = ReactQueueConfigurationSpec.Default, Registry = registry, JavaScriptModuleRegistry = jsRegistry, JavaScriptExecutorFactory = () => executor, BundleLoader = JavaScriptBundleLoader.CreateFileLoader("ms-appx:///Resources/test.js"), NativeModuleCallExceptionHandler = _ => { }, }; var instance = await DispatcherHelpers.CallOnDispatcherAsync(() => builder.Build()); await DispatcherHelpers.RunOnDispatcherAsync(() => instance.Initialize()); var caught = false; await DispatcherHelpers.RunOnDispatcherAsync(() => { try { instance.Initialize(); } catch (InvalidOperationException) { caught = true; } }); Assert.IsTrue(caught); Assert.AreEqual(1, module.InitializeCalls); await DispatcherHelpers.CallOnDispatcherAsync(instance.DisposeAsync); Assert.AreEqual(1, module.OnReactInstanceDisposeCalls); // Dispose is idempotent await DispatcherHelpers.CallOnDispatcherAsync(instance.DisposeAsync); Assert.AreEqual(1, module.OnReactInstanceDisposeCalls); Assert.IsTrue(instance.IsDisposed); }
private static ReactInstance CreateReactInstance(ReactContext reactContext, IJavaScriptExecutor executor) { var registry = new NativeModuleRegistry.Builder(reactContext).Build(); var instance = new ReactInstance.Builder { QueueConfiguration = TestReactQueueConfiguration.Create(ex => Assert.Fail(ex.ToString())), BundleLoader = JavaScriptBundleLoader.CreateFileLoader("ms-appx:///Resources/test.js"), Registry = registry, JavaScriptExecutorFactory = () => executor, }.Build(); return(instance); }
private void ProcessPackage( IReactPackage reactPackage, ReactContext reactContext, NativeModuleRegistry.Builder nativeRegistryBuilder, JavaScriptModuleRegistry.Builder jsModulesBuilder) { foreach (var nativeModule in reactPackage.CreateNativeModules(reactContext)) { nativeRegistryBuilder.Add(nativeModule); } foreach (var type in reactPackage.CreateJavaScriptModulesConfig()) { jsModulesBuilder.Add(type); } }
public async Task ReactInstance_ExceptionHandled_Disposes() { var eventHandler = new AutoResetEvent(false); var module = new OnDisposeNativeModule(() => eventHandler.Set()); var registry = new NativeModuleRegistry.Builder() .Add(module) .Build(); var jsRegistry = new JavaScriptModuleRegistry.Builder().Build(); var executor = new MockJavaScriptExecutor { OnCallFunctionReturnFlushedQueue = (_, __, ___) => JValue.CreateNull(), OnFlushQueue = () => JValue.CreateNull(), OnInvokeCallbackAndReturnFlushedQueue = (_, __) => JValue.CreateNull() }; var exception = new Exception(); var tcs = new TaskCompletionSource <Exception>(); var handler = new Action <Exception>(ex => { Task.Run(() => tcs.SetResult(ex)); }); var builder = new ReactInstance.Builder() { QueueConfigurationSpec = ReactQueueConfigurationSpec.Default, Registry = registry, JavaScriptModuleRegistry = jsRegistry, JavaScriptExecutorFactory = () => executor, BundleLoader = JavaScriptBundleLoader.CreateFileLoader("ms-appx:///Resources/test.js"), NativeModuleCallExceptionHandler = handler, }; var instance = await DispatcherHelpers.CallOnDispatcherAsync(() => builder.Build()); instance.QueueConfiguration.JavaScriptQueueThread.RunOnQueue(() => { throw exception; }); var actualException = await tcs.Task; Assert.AreSame(exception, actualException); Assert.IsTrue(eventHandler.WaitOne()); Assert.IsTrue(instance.IsDisposed); }
private static ReactInstance CreateReactInstance(IJavaScriptExecutor executor) { var registry = new NativeModuleRegistry.Builder().Build(); var instance = new ReactInstance.Builder { QueueConfigurationSpec = ReactQueueConfigurationSpec.Default, BundleLoader = JavaScriptBundleLoader.CreateFileLoader("ms-appx:///Resources/test.js"), Registry = registry, JavaScriptExecutorFactory = () => executor, NativeModuleCallExceptionHandler = ex => Assert.Fail(ex.ToString()), }.Build(); instance.Initialize(); return(instance); }
public async Task ReactInstance_GetModules() { var module = new TestNativeModule(); var registry = new NativeModuleRegistry.Builder() .Add(module) .Build(); var jsRegistry = new JavaScriptModuleRegistry.Builder() .Add <TestJavaScriptModule>() .Build(); var executor = new MockJavaScriptExecutor { OnCallFunctionReturnFlushedQueue = (_, __, ___) => JValue.CreateNull(), OnFlushQueue = () => JValue.CreateNull(), OnInvokeCallbackAndReturnFlushedQueue = (_, __) => JValue.CreateNull() }; var builder = new ReactInstance.Builder() { QueueConfigurationSpec = ReactQueueConfigurationSpec.Default, Registry = registry, JavaScriptModuleRegistry = jsRegistry, JavaScriptExecutorFactory = () => executor, BundleLoader = JavaScriptBundleLoader.CreateFileLoader("ms-appx:///Resources/test.js"), NativeModuleCallExceptionHandler = _ => { } }; var instance = await DispatcherHelpers.CallOnDispatcherAsync(() => builder.Build()); var actualModule = instance.GetNativeModule <TestNativeModule>(); Assert.AreSame(module, actualModule); var firstJSModule = instance.GetJavaScriptModule <TestJavaScriptModule>(); var secondJSModule = instance.GetJavaScriptModule <TestJavaScriptModule>(); Assert.AreSame(firstJSModule, secondJSModule); await DispatcherHelpers.CallOnDispatcherAsync(instance.DisposeAsync); }
public async Task ReactInstance_GetModules() { var module = new TestNativeModule(); var registry = new NativeModuleRegistry.Builder() .Add(module) .Build(); var jsRegistry = new JavaScriptModuleRegistry.Builder() .Add<TestJavaScriptModule>() .Build(); var executor = new MockJavaScriptExecutor { OnCallFunctionReturnFlushedQueue = (_, __, ___) => JValue.CreateNull(), OnFlushQueue = () => JValue.CreateNull(), OnInvokeCallbackAndReturnFlushedQueue = (_, __) => JValue.CreateNull() }; var builder = new ReactInstance.Builder() { QueueConfigurationSpec = ReactQueueConfigurationSpec.Default, Registry = registry, JavaScriptModuleRegistry = jsRegistry, JavaScriptExecutorFactory = () => executor, BundleLoader = JavaScriptBundleLoader.CreateFileLoader("ms-appx:///Resources/test.js"), NativeModuleCallExceptionHandler = _ => { } }; var instance = await DispatcherHelpers.CallOnDispatcherAsync(() => builder.Build()); var actualModule = instance.GetNativeModule<TestNativeModule>(); Assert.AreSame(module, actualModule); var firstJSModule = instance.GetJavaScriptModule<TestJavaScriptModule>(); var secondJSModule = instance.GetJavaScriptModule<TestJavaScriptModule>(); Assert.AreSame(firstJSModule, secondJSModule); await DispatcherHelpers.CallOnDispatcherAsync(instance.DisposeAsync); }
public void NativeModuleRegistry_WriteModuleDefinitions() { var registry = new NativeModuleRegistry.Builder() .Add(new TestNativeModule()) .Build(); using (var stringWriter = new StringWriter()) { using (var writer = new JsonTextWriter(stringWriter)) { registry.WriteModuleDescriptions(writer); } var actual = JObject.Parse(stringWriter.ToString()); Assert.AreEqual(1, actual.Properties().Count()); var moduleDef = actual.GetValue("Test") as JObject; Assert.IsNotNull(moduleDef); var moduleId = moduleDef.GetValue("moduleID"); Assert.IsNotNull(moduleId); Assert.AreEqual("0", moduleId.ToString()); var methods = moduleDef.GetValue("methods") as JObject; Assert.IsNotNull(methods); var fooMethod = methods.GetValue("Foo") as JObject; Assert.IsNotNull(fooMethod); var barMethod = methods.GetValue("Bar") as JObject; Assert.IsNotNull(barMethod); var fooMethodId = fooMethod.GetValue("methodID"); var barMethodId = barMethod.GetValue("methodID"); Assert.AreNotEqual(fooMethodId.ToString(), barMethodId.ToString()); Assert.IsTrue(fooMethodId.ToString() == "0" || fooMethodId.ToString() == "1"); Assert.IsTrue(barMethodId.ToString() == "0" || barMethodId.ToString() == "1"); } }
public async Task ReactInstance_ExceptionHandled_DoesNotDispose() { var eventHandler = new AutoResetEvent(false); var module = new OnDisposeNativeModule(() => eventHandler.Set()); var registry = new NativeModuleRegistry.Builder(new ReactContext()) .Add(module) .Build(); var executor = new MockJavaScriptExecutor { OnCallFunctionReturnFlushedQueue = (_, __, ___) => JValue.CreateNull(), OnFlushQueue = () => JValue.CreateNull(), OnInvokeCallbackAndReturnFlushedQueue = (_, __) => JValue.CreateNull() }; var exception = new Exception(); var tcs = new TaskCompletionSource <Exception>(TaskCreationOptions.RunContinuationsAsynchronously); var builder = new ReactInstance.Builder() { QueueConfiguration = TestReactQueueConfiguration.Create(tcs.SetResult), Registry = registry, JavaScriptExecutorFactory = () => executor, BundleLoader = JavaScriptBundleLoader.CreateFileLoader("ms-appx:///Resources/test.js"), }; var instance = await DispatcherHelpers.CallOnDispatcherAsync(() => builder.Build()); instance.QueueConfiguration.JavaScriptQueue.Dispatch(() => { throw exception; }); var actualException = await tcs.Task; Assert.AreSame(exception, actualException); Assert.IsFalse(eventHandler.WaitOne(500)); Assert.IsFalse(instance.IsDisposed); }
public void NativeModuleRegistry_Override_Disallowed() { var builder = new NativeModuleRegistry.Builder(); builder.Add(new OverrideDisallowedModule()); AssertEx.Throws<InvalidOperationException>(() => builder.Add(new OverrideDisallowedModule())); }
public async Task ReactInstance_ExceptionHandled_Disposes() { var eventHandler = new AutoResetEvent(false); var module = new OnDisposeNativeModule(() => eventHandler.Set()); var registry = new NativeModuleRegistry.Builder() .Add(module) .Build(); var jsRegistry = new JavaScriptModuleRegistry.Builder().Build(); var executor = new MockJavaScriptExecutor { OnCallFunctionReturnFlushedQueue = (_, __, ___) => JValue.CreateNull(), OnFlushQueue = () => JValue.CreateNull(), OnInvokeCallbackAndReturnFlushedQueue = (_, __) => JValue.CreateNull() }; var exception = new Exception(); var tcs = new TaskCompletionSource<Exception>(); var handler = new Action<Exception>(ex => { Task.Run(() => tcs.SetResult(ex)); }); var builder = new ReactInstance.Builder() { QueueConfigurationSpec = ReactQueueConfigurationSpec.Default, Registry = registry, JavaScriptModuleRegistry = jsRegistry, JavaScriptExecutorFactory = () => executor, BundleLoader = JavaScriptBundleLoader.CreateFileLoader("ms-appx:///Resources/test.js"), NativeModuleCallExceptionHandler = handler, }; var instance = await DispatcherHelpers.CallOnDispatcherAsync(() => builder.Build()); instance.QueueConfiguration.JavaScriptQueueThread.RunOnQueue(() => { throw exception; }); var actualException = await tcs.Task; Assert.AreSame(exception, actualException); Assert.IsTrue(eventHandler.WaitOne()); Assert.IsTrue(instance.IsDisposed); }
private async Task<ReactContext> CreateReactContextAsync( Func<IJavaScriptExecutor> jsExecutorFactory, JavaScriptBundleLoader jsBundleLoader) { Tracer.Write(ReactConstants.Tag, "Creating React context."); _sourceUrl = jsBundleLoader.SourceUrl; var nativeRegistryBuilder = new NativeModuleRegistry.Builder(); var jsModulesBuilder = new JavaScriptModuleRegistry.Builder(); var reactContext = new ReactContext(); if (_useDeveloperSupport) { reactContext.NativeModuleCallExceptionHandler = _devSupportManager.HandleException; } using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "createAndProcessCoreModulesPackage").Start()) { var coreModulesPackage = new CoreModulesPackage(this, InvokeDefaultOnBackPressed, _uiImplementationProvider); ProcessPackage(coreModulesPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder); } foreach (var reactPackage in _packages) { using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "createAndProcessCustomReactPackage").Start()) { ProcessPackage(reactPackage, reactContext, nativeRegistryBuilder, jsModulesBuilder); } } var nativeModuleRegistry = default(NativeModuleRegistry); using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "buildNativeModuleRegistry").Start()) { nativeModuleRegistry = nativeRegistryBuilder.Build(); } var exceptionHandler = _nativeModuleCallExceptionHandler ?? _devSupportManager.HandleException; var reactInstanceBuilder = new ReactInstance.Builder { QueueConfigurationSpec = ReactQueueConfigurationSpec.Default, JavaScriptExecutorFactory = jsExecutorFactory, Registry = nativeModuleRegistry, JavaScriptModuleRegistry = jsModulesBuilder.Build(), BundleLoader = jsBundleLoader, NativeModuleCallExceptionHandler = exceptionHandler, }; var reactInstance = default(ReactInstance); using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "createReactInstance").Start()) { reactInstance = reactInstanceBuilder.Build(); } // TODO: add bridge idle debug listener reactContext.InitializeWithInstance(reactInstance); reactInstance.Initialize(); using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "RunJavaScriptBundle").Start()) { await reactInstance.InitializeBridgeAsync().ConfigureAwait(false); } return reactContext; }
private async Task <ReactContext> CreateReactContextCoreAsync( Func <IJavaScriptExecutor> jsExecutorFactory, JavaScriptBundleLoader jsBundleLoader, CancellationToken token) { Tracer.Write(ReactConstants.Tag, "Creating React context."); _sourceUrl = jsBundleLoader.SourceUrl; var reactContext = new ReactContext(); if (_useDeveloperSupport) { reactContext.NativeModuleCallExceptionHandler = _nativeModuleCallExceptionHandler ?? _devSupportManager.HandleException; } var nativeRegistryBuilder = new NativeModuleRegistry.Builder(reactContext); using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "createAndProcessCoreModulesPackage").Start()) { var coreModulesPackage = new CoreModulesPackage( this, InvokeDefaultOnBackPressed, _uiImplementationProvider); ProcessPackage(coreModulesPackage, reactContext, nativeRegistryBuilder); } foreach (var reactPackage in _packages) { using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "createAndProcessCustomReactPackage").Start()) { ProcessPackage(reactPackage, reactContext, nativeRegistryBuilder); } } var nativeModuleRegistry = default(NativeModuleRegistry); using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "buildNativeModuleRegistry").Start()) { nativeModuleRegistry = nativeRegistryBuilder.Build(); } var queueConfiguration = ReactQueueConfigurationFactory.Default.Create(reactContext.HandleException); var reactInstanceBuilder = new ReactInstance.Builder { QueueConfiguration = queueConfiguration, JavaScriptExecutorFactory = jsExecutorFactory, Registry = nativeModuleRegistry, BundleLoader = jsBundleLoader, }; var reactInstance = default(ReactInstance); using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "createReactInstance").Start()) { reactInstance = reactInstanceBuilder.Build(); } // TODO: add bridge idle debug listener reactContext.InitializeWithInstance(reactInstance); reactInstance.Initialize(); using (Tracer.Trace(Tracer.TRACE_TAG_REACT_BRIDGE, "RunJavaScriptBundle").Start()) { await reactInstance.InitializeBridgeAsync(token).ConfigureAwait(false); } return(reactContext); }