Example #1
0
        public void JavaScriptModuleRegistry_InvalidModule_Throws()
        {
            var registry      = new JavaScriptModuleRegistry.Builder().Build();
            var reactInstance = new MockReactInstance();

            AssertEx.Throws <InvalidOperationException>(() => registry.GetJavaScriptModule <TestJavaScriptModule>(reactInstance));
        }
        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 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 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);
        }
Example #6
0
        public void JavaScriptModuleRegistry_Validate()
        {
            var builder = new JavaScriptModuleRegistry.Builder();

            AssertEx.Throws <ArgumentException>(
                () => builder.Add(typeof(JavaScriptModuleBase)),
                ex => Assert.AreEqual("type", ex.ParamName));

            AssertEx.Throws <ArgumentException>(
                () => builder.Add(typeof(IDerivedJavaScriptModule)),
                ex => Assert.AreEqual("type", ex.ParamName));

            AssertEx.Throws <ArgumentException>(
                () => builder.Add(typeof(object)),
                ex => Assert.AreEqual("type", ex.ParamName));

            AssertEx.Throws <ArgumentException>(
                () => builder.Add(typeof(NoConstructorJavaScriptModule)),
                ex => Assert.AreEqual("type", ex.ParamName));
        }
        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);
        }
Example #8
0
        private static ReactInstance CreateReactInstance(IJavaScriptExecutor executor)
        {
            var registry  = new NativeModuleRegistry.Builder().Build();
            var jsModules = new JavaScriptModuleRegistry.Builder()
                            .Add <RCTEventEmitter>()
                            .Build();

            var instance = new ReactInstance.Builder
            {
                QueueConfigurationSpec   = ReactQueueConfigurationSpec.Default,
                BundleLoader             = JavaScriptBundleLoader.CreateFileLoader("ms-appx:///Resources/test.js"),
                JavaScriptModuleRegistry = jsModules,
                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);
        }
Example #10
0
        public void JavaScriptModuleRegistry_Invoke()
        {
            var registry = new JavaScriptModuleRegistry.Builder()
                           .Add <RCTEventEmitter>()
                           .Add <AppRegistry>()
                           .Add <TestJavaScriptModule>()
                           .Build();

            var are           = new AutoResetEvent(false);
            var modules       = new List <string>();
            var methods       = new List <string>();
            var argsList      = new List <JArray>();
            var reactInstance = new MockReactInstance((mod, met, args, tracingName) =>
            {
                modules.Add(mod);
                methods.Add(met);
                argsList.Add(args);
                are.Set();
            });

            var module = registry.GetJavaScriptModule <TestJavaScriptModule>(reactInstance);

            module.Foo(42);

            are.WaitOne();

            Assert.AreEqual(1, modules.Count);
            Assert.AreEqual(1, methods.Count);
            Assert.AreEqual(1, modules.Count);

            Assert.AreEqual("TestJavaScriptModule", modules[0]);
            Assert.AreEqual("Foo", methods[0]);
            Assert.AreEqual(
                JArray.FromObject(new[] { 42 }).ToString(Formatting.None),
                argsList[0].ToString(Formatting.None));
        }
        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);
        }
Example #12
0
 public void SetUp()
 {
     _registryBuilder   = new JavaScriptModuleRegistry.Builder();
     _mockFactory       = new MockFactory();
     _mockReactInstance = _mockFactory.CreateMock <IReactInstance>();
 }
        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);
        }
Example #14
0
 public static JavaScriptModuleRegistry.Builder Add <T>(this JavaScriptModuleRegistry.Builder builder)
     where T : IJavaScriptModule
 {
     return(builder.Add(typeof(T)));
 }
Example #15
0
 public virtual void SetUp()
 {
     _registryBuilder = new JavaScriptModuleRegistry.Builder();
 }
        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;
        }