public async Task EventDispatcher_OnReactInstanceDispose_EventDoesNotDispatch()
        {
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var waitDispatched = new AutoResetEvent(false);
            var executor       = new MockJavaScriptExecutor
            {
                OnCallFunctionReturnFlushedQueue = (p0, p1, p2) =>
                {
                    waitDispatched.Set();
                    return(EmptyResponse);
                },
                OnFlushQueue = () => EmptyResponse,
                OnInvokeCallbackAndReturnFlushedQueue = (_, __) => EmptyResponse
            };

            var context = await CreateContextAsync(executor);

            var dispatcher = new EventDispatcher(context);
            await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnResume);

            var testEvent = new MockEvent(42, "Foo");

            using (BlockJavaScriptThread(context))
            {
                dispatcher.DispatchEvent(testEvent);
                await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnReactInstanceDispose);
            }

            Assert.IsFalse(waitDispatched.WaitOne(500));

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);

            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
Exemple #2
0
        public async Task EventDispatcher_MultipleDispatches()
        {
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var waitDispatched = new AutoResetEvent(false);
            var executor       = new MockJavaScriptExecutor
            {
                OnCallFunctionReturnFlushedQueue = (p0, p1, p2) =>
                {
                    waitDispatched.Set();
                    return(EmptyResponse);
                },
                OnFlushQueue = () => EmptyResponse,
                OnInvokeCallbackAndReturnFlushedQueue = (_, __) => EmptyResponse
            };

            var context = await CreateContextAsync(executor);

            var dispatcher = new EventDispatcher(context);
            await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnResume);

            var count = 100;

            for (var i = 0; i < count; ++i)
            {
                var testEvent = new MockEvent(42, "Foo");
                dispatcher.DispatchEvent(testEvent);
                Assert.IsTrue(waitDispatched.WaitOne());
            }

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);

            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
Exemple #3
0
        public async Task EventDispatcher_NonCoalesced()
        {
            var waitDispatched = new AutoResetEvent(false);
            var executor       = new MockJavaScriptExecutor
            {
                OnCallFunctionReturnFlushedQueue = (p0, p1, p2) =>
                {
                    waitDispatched.Set();
                    return(EmptyResponse);
                },
                OnFlushQueue = () => EmptyResponse,
                OnInvokeCallbackAndReturnFlushedQueue = (_, __) => EmptyResponse
            };

            var context = await CreateContextAsync(executor);

            var dispatcher = new EventDispatcher(context);
            await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnResume);

            var e1 = new NonCoalescedEvent(42, TimeSpan.Zero, "Foo");
            var e2 = new NonCoalescedEvent(42, TimeSpan.Zero, "Foo");

            using (BlockJavaScriptThread(context))
            {
                dispatcher.DispatchEvent(e1);
                dispatcher.DispatchEvent(e2);
            }

            Assert.IsTrue(waitDispatched.WaitOne());
            Assert.IsTrue(waitDispatched.WaitOne());

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);
        }
Exemple #4
0
        public async Task EventDispatcher_EventDispatches()
        {
            // TODO: (#288) Check for non-determinism.
            var waitDispatched = new AutoResetEvent(false);
            var executor       = new MockJavaScriptExecutor
            {
                OnCallFunctionReturnFlushedQueue = (p0, p1, p2) =>
                {
                    waitDispatched.Set();
                    return(EmptyResponse);
                },
                OnFlushQueue = () => EmptyResponse,
                OnInvokeCallbackAndReturnFlushedQueue = (_, __) => EmptyResponse
            };

            var context = await CreateContextAsync(executor);

            var dispatcher = new EventDispatcher(context);
            await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnResume);

            var testEvent = new MockEvent(42, TimeSpan.Zero, "Foo");

            dispatcher.DispatchEvent(testEvent);

            Assert.IsTrue(waitDispatched.WaitOne());

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);
        }
        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.RunOnDispatcherAsync(() => instance.Initialize());

            var caught = false;
            await DispatcherHelpers.RunOnDispatcherAsync(() =>
            {
                try
                {
                    instance.Initialize();
                }
                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);
        }
Exemple #6
0
        public void ReactBridge_ValidJavaScriptResponse()
        {
            var responses = new[]
            {
                JToken.Parse("null"),
                JToken.Parse("undefined"),
                JArray.Parse("[[],[],[]]"),
                JArray.Parse("[[1],[1],[[]]]"),
                JArray.Parse("[[1],[1],[[1,2,3]], 42]"),
            };

            var n = responses.Length;

            using (var nativeThread = CreateNativeModulesThread())
            {
                var count    = 0;
                var executor = new MockJavaScriptExecutor
                {
                    OnCallFunctionReturnFlushedQueue = (module, method, args) =>
                    {
                        return(responses[count++]);
                    }
                };

                var bridge = new ReactBridge(executor, new MockReactCallback(), nativeThread);

                for (var i = 0; i < n; ++i)
                {
                    bridge.CallFunction("module", "method", new JArray());
                }

                Assert.AreEqual(n, count);
            }
        }
Exemple #7
0
        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.RunOnDispatcherAsync(() => instance.Dispose());

            Assert.AreEqual(1, module.OnReactInstanceDisposeCalls);

            // Dispose is idempotent
            await DispatcherHelpers.RunOnDispatcherAsync(() => instance.Dispose());

            Assert.AreEqual(1, module.OnReactInstanceDisposeCalls);

            Assert.IsTrue(instance.IsDisposed);
        }
Exemple #8
0
        public async Task EventDispatcher_EventsNotCoalesced()
        {
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var waitDispatched = new AutoResetEvent(false);
            var executor       = new MockJavaScriptExecutor
            {
                OnCallFunctionReturnFlushedQueue = (p0, p1, p2) =>
                {
                    waitDispatched.Set();
                    return(EmptyResponse);
                },
                OnFlushQueue = () => EmptyResponse,
                OnInvokeCallbackAndReturnFlushedQueue = (_, __) => EmptyResponse
            };

            var context = await CreateContextAsync(executor);

            var dispatcher = new EventDispatcher(context);
            await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnResume);

            var disposed = new AutoResetEvent(false);

            var diffTag1 = new TestEvent(42, "foo", 1);
            var diffTag2 = new TestEvent(43, "foo", 1);

            var diffName1 = new TestEvent(42, "foo", 1);
            var diffName2 = new TestEvent(42, "bar", 1);

            var diffKey1 = new TestEvent(42, "foo", 1);
            var diffKey2 = new TestEvent(42, "foo", 2);

            var pairs = new[]
            {
                new[] { diffTag1, diffTag2 },
                new[] { diffName1, diffName2 },
                new[] { diffKey1, diffKey2 },
            };

            foreach (var pair in pairs)
            {
                using (BlockJavaScriptThread(context))
                {
                    dispatcher.DispatchEvent(pair[0]);
                    dispatcher.DispatchEvent(pair[1]);
                }

                Assert.IsTrue(waitDispatched.WaitOne());
                Assert.IsTrue(waitDispatched.WaitOne());
            }

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);

            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
        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);
        }
Exemple #10
0
        public async Task EventDispatcher_EventsNotCoalesced()
        {
            var waitDispatched = new AutoResetEvent(false);
            var executor       = new MockJavaScriptExecutor((p0, p1, p2) =>
            {
                if (p1 == "callFunctionReturnFlushedQueue")
                {
                    waitDispatched.Set();
                }

                return(JArray.Parse("[[],[],[]]"));
            });

            var context = await CreateContextAsync(executor);

            var dispatcher = new EventDispatcher(context);
            await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnResume);

            var disposed = new AutoResetEvent(false);

            var diffTag1 = new TestEvent(42, TimeSpan.Zero, "foo", 1);
            var diffTag2 = new TestEvent(43, TimeSpan.Zero, "foo", 1);

            var diffName1 = new TestEvent(42, TimeSpan.Zero, "foo", 1);
            var diffName2 = new TestEvent(42, TimeSpan.Zero, "bar", 1);

            var diffKey1 = new TestEvent(42, TimeSpan.Zero, "foo", 1);
            var diffKey2 = new TestEvent(42, TimeSpan.Zero, "foo", 2);

            var pairs = new[]
            {
                new[] { diffTag1, diffTag2 },
                new[] { diffName1, diffName2 },
                new[] { diffKey1, diffKey2 },
            };

            foreach (var pair in pairs)
            {
                using (BlockJavaScriptThread(context))
                {
                    dispatcher.DispatchEvent(pair[0]);
                    dispatcher.DispatchEvent(pair[1]);
                }

                Assert.IsTrue(waitDispatched.WaitOne());
                Assert.IsTrue(waitDispatched.WaitOne());
            }

            await DispatcherHelpers.RunOnDispatcherAsync(context.Dispose);
        }
Exemple #11
0
        public async Task EventDispatcher_EventsCoalesced1()
        {
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var waitDispatched = new AutoResetEvent(false);
            var executor       = new MockJavaScriptExecutor
            {
                OnCallFunctionReturnFlushedQueue = (p0, p1, p2) =>
                {
                    waitDispatched.Set();
                    return(EmptyResponse);
                },
                OnFlushQueue = () => EmptyResponse,
                OnInvokeCallbackAndReturnFlushedQueue = (_, __) => EmptyResponse
            };

            var context = await CreateContextAsync(executor);

            var dispatcher = new EventDispatcher(context);
            await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnResume);

            var winner   = default(int);
            var disposed = new AutoResetEvent(false);

            var firstEvent = new TestEvent(42, "foo", 1, () => winner = 1, () => disposed.Set());
            await Task.Delay(1); // Ensure second event has higher timstamp

            var secondEvent = new TestEvent(42, "foo", 1, () => winner = 2, () => disposed.Set());

            using (BlockJavaScriptThread(context))
            {
                dispatcher.DispatchEvent(firstEvent);
                dispatcher.DispatchEvent(secondEvent);

                // First event is disposed after coalesce
                Assert.IsTrue(disposed.WaitOne());
            }

            Assert.IsTrue(waitDispatched.WaitOne());
            Assert.AreEqual(2, winner);
            Assert.IsFalse(waitDispatched.WaitOne(500));

            // Second event is disposed after dispatch
            Assert.IsTrue(disposed.WaitOne());

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);

            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
        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);
        }
        public void ReactBridge_InvalidJavaScriptResponse()
        {
            var responses = new[]
            {
                JArray.Parse("[null,[],[]]"),
                JArray.Parse("[[],null,[]]"),
                JArray.Parse("[[],[],null]"),
                JArray.Parse("[[42],[],[]]"),
                JArray.Parse("[[],[42],[]]"),
                JArray.Parse("[[],[],[42]]"),
                JArray.Parse("[[42],[42],[]]"),
                JArray.Parse("[[42],[42],[[],[]]]"),
                JArray.Parse("[]"),
                JArray.Parse("[[]]"),
                JArray.Parse("[[],[]]"),
                JObject.Parse("{}"),
                JToken.Parse("0"),
            };

            var n = responses.Length;

            using (var nativeThread = CreateNativeModulesThread())
            {
                var count    = 0;
                var executor = new MockJavaScriptExecutor
                {
                    OnCallFunctionReturnFlushedQueue = (module, method, args) =>
                    {
                        return(responses[count++]);
                    }
                };

                var bridge = new ReactBridge(executor, new MockReactCallback(), nativeThread);

                for (var i = 0; i < n; ++i)
                {
                    Assert.That(
                        () => bridge.CallFunction("module", "method", new JArray()),
                        Throws.InvalidOperationException
                        );
                }

                Assert.AreEqual(n, count);
            }
        }
Exemple #14
0
        public async Task EventDispatcher_EventsCoalesced2()
        {
            var waitDispatched = new AutoResetEvent(false);
            var executor       = new MockJavaScriptExecutor
            {
                OnCallFunctionReturnFlushedQueue = (p0, p1, p2) =>
                {
                    waitDispatched.Set();
                    return(EmptyResponse);
                },
                OnFlushQueue = () => EmptyResponse,
                OnInvokeCallbackAndReturnFlushedQueue = (_, __) => EmptyResponse
            };

            var context = await CreateContextAsync(executor);

            var dispatcher = new EventDispatcher(context);
            await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnResume);

            var winner   = default(int);
            var disposed = new AutoResetEvent(false);

            var firstEvent  = new TestEvent(42, TimeSpan.MaxValue, "foo", 1, () => winner = 1, () => disposed.Set());
            var secondEvent = new TestEvent(42, TimeSpan.Zero, "foo", 1, () => winner = 2, () => disposed.Set());

            using (BlockJavaScriptThread(context))
            {
                dispatcher.DispatchEvent(firstEvent);
                dispatcher.DispatchEvent(secondEvent);

                // First event is disposed after coalesce
                Assert.IsTrue(disposed.WaitOne());
            }

            Assert.IsTrue(waitDispatched.WaitOne());
            Assert.AreEqual(1, winner);
            Assert.IsFalse(waitDispatched.WaitOne(500));

            // Second event is disposed after dispatch
            Assert.IsTrue(disposed.WaitOne());

            await DispatcherHelpers.RunOnDispatcherAsync(context.Dispose);
        }
Exemple #15
0
        public async Task EventDispatcher_EventsCoalesced1()
        {
            var waitDispatched = new AutoResetEvent(false);
            var executor       = new MockJavaScriptExecutor((p0, p1, p2) =>
            {
                if (p1 == "callFunctionReturnFlushedQueue")
                {
                    waitDispatched.Set();
                }

                return(JArray.Parse("[[],[],[]]"));
            });

            var context = await CreateContextAsync(executor);

            var dispatcher = new EventDispatcher(context);
            await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnResume);

            var winner   = default(int);
            var disposed = new AutoResetEvent(false);

            var firstEvent  = new TestEvent(42, TimeSpan.Zero, "foo", 1, () => winner = 1, () => disposed.Set());
            var secondEvent = new TestEvent(42, TimeSpan.MaxValue, "foo", 1, () => winner = 2, () => disposed.Set());

            using (BlockJavaScriptThread(context))
            {
                dispatcher.DispatchEvent(firstEvent);
                dispatcher.DispatchEvent(secondEvent);

                // First event is disposed after coalesce
                Assert.IsTrue(disposed.WaitOne());
            }

            Assert.IsTrue(waitDispatched.WaitOne());
            Assert.AreEqual(2, winner);
            Assert.IsFalse(waitDispatched.WaitOne(500));

            // Second event is disposed after dispatch
            Assert.IsTrue(disposed.WaitOne());

            await DispatcherHelpers.RunOnDispatcherAsync(context.Dispose);
        }
        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);
        }
Exemple #17
0
        public void ReactBridge_ReactCallbacks()
        {
            using (var nativeThread = CreateNativeModulesThread())
            {
                var jsonResponse = JArray.Parse("[[42,17],[16,22],[[],[\"foo\"]]]");

                var executor = new MockJavaScriptExecutor
                {
                    OnCallFunctionReturnFlushedQueue = (module, method, args) =>
                    {
                        Assert.AreEqual(module, "module");
                        Assert.AreEqual(method, "method");
                        return(jsonResponse);
                    }
                };

                var callbacks    = new List <Tuple <int, int, JArray> >();
                var eventHandler = new AutoResetEvent(false);
                var callback     = new MockReactCallback
                {
                    InvokeHandler          = (moduleId, methodId, args) => callbacks.Add(Tuple.Create(moduleId, methodId, args)),
                    OnBatchCompleteHandler = () => eventHandler.Set(),
                };

                var bridge = new ReactBridge(executor, callback, nativeThread);
                bridge.CallFunction("module", "method", new JArray());

                Assert.IsTrue(eventHandler.WaitOne());

                Assert.AreEqual(2, callbacks.Count);

                Assert.AreEqual(42, callbacks[0].Item1);
                Assert.AreEqual(16, callbacks[0].Item2);
                Assert.AreEqual(0, callbacks[0].Item3.Count);

                Assert.AreEqual(17, callbacks[1].Item1);
                Assert.AreEqual(22, callbacks[1].Item2);
                Assert.AreEqual(1, callbacks[1].Item3.Count);
                Assert.AreEqual("foo", callbacks[1].Item3[0].Value <string>());
            }
        }
        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);
        }
Exemple #19
0
        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 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);
        }