예제 #1
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);
        }
예제 #2
0
        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 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, "Foo");

            dispatcher.DispatchEvent(testEvent);

            Assert.IsTrue(waitDispatched.WaitOne());

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);
        }
예제 #4
0
        public async Task UIManagerModule_Constants_ViewManager_CustomEvents()
        {
            var context      = new ReactContext();
            var viewManagers = new List <IViewManager> {
                new TestViewManager()
            };

            ReactNative.Bridge.DispatcherHelpers.MainDispatcher = Dispatcher.CurrentDispatcher;
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var uiImplementationProvider = new UIImplementationProvider();

            using (var actionQueue = new ActionQueue(ex => { }))
            {
                var module = await DispatcherHelpers.CallOnDispatcherAsync(
                    () => new UIManagerModule(context, viewManagers, uiImplementationProvider, actionQueue, UIManagerModuleOptions.None));

                var constants = ((INativeModule)module).Constants.GetMap("Test");
                Assert.AreEqual(42, constants.GetMap("directEventTypes").GetValue("otherSelectionChange").Value <int>());
                Assert.AreEqual(42, constants.GetMap("directEventTypes").GetMap("topSelectionChange").GetValue("registrationName").Value <int>());
                Assert.AreEqual(42, constants.GetMap("directEventTypes").GetMap("topLoadingStart").GetValue("foo").Value <int>());
                Assert.AreEqual(42, constants.GetMap("directEventTypes").GetValue("topLoadingError").Value <int>());
            }

            // Ideally we should dispose, but the original dispatcher is somehow lost/etc.
            // await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
        public async Task EventDispatcher_OnReactInstanceDispose_EventDoesNotDispatch()
        {
            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);
        }
예제 #6
0
        public async Task EventDispatcher_DispatchedAfterSuspend_ThenResume()
        {
            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");

            await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnSuspend);

            dispatcher.DispatchEvent(testEvent);

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

            await DispatcherHelpers.RunOnDispatcherAsync(dispatcher.OnResume);

            Assert.IsTrue(waitDispatched.WaitOne());

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);
        }
예제 #7
0
        public async Task Timing_Correct_Order()
        {
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var ids       = new List <int>();
            var countdown = new CountdownEvent(1);
            var context   = CreateReactContext(new MockInvocationHandler((name, args) =>
            {
                Assert.AreEqual(name, nameof(JSTimers.callTimers));
                ids.AddRange((IList <int>)args[0]);
                countdown.Signal();
            }));

            var timing = new Timing(context);

            timing.Initialize();
            await DispatcherHelpers.RunOnDispatcherAsync(context.OnResume);

            var now = DateTimeOffset.Now.ToUnixTimeMilliseconds();

            timing.createTimer(1, 300000, now, false);
            timing.createTimer(2, 1, now, false);

            Assert.IsTrue(countdown.Wait(1000));
            Assert.IsTrue(ids.SequenceEqual(new[] { 2 }));
            timing.deleteTimer(1);

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);

            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
예제 #8
0
        public async Task Timing_Create_Delete()
        {
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var ids        = new List <int>();
            var waitHandle = new AutoResetEvent(false);
            var context    = CreateReactContext(new MockInvocationHandler((name, args) =>
            {
                Assert.AreEqual(name, nameof(JSTimers.callTimers));
                ids.AddRange((IList <int>)args[0]);
                waitHandle.Set();
            }));

            var timing = new Timing(context);

            timing.Initialize();
            await DispatcherHelpers.RunOnDispatcherAsync(context.OnResume);

            var id  = 42;
            var now = DateTimeOffset.Now.ToUnixTimeMilliseconds();

            timing.createTimer(id, 500, now, false);
            timing.deleteTimer(id);
            Assert.IsFalse(waitHandle.WaitOne(1000));

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);

            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
예제 #9
0
        public async Task Timing_Zero_NoRepeat()
        {
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var ids        = new List <int>();
            var waitHandle = new AutoResetEvent(false);
            var context    = CreateReactContext(new MockInvocationHandler((name, args) =>
            {
                Assert.AreEqual(name, nameof(JSTimers.callTimers));
                ids.AddRange((IList <int>)args[0]);
                waitHandle.Set();
            }));

            var timing = new Timing(context);

            timing.Initialize();
            await DispatcherHelpers.RunOnDispatcherAsync(context.OnResume);

            // Callback is called directly
            timing.createTimer(42, 0, DateTimeOffset.Now.ToUnixTimeMilliseconds(), false);

            Assert.IsTrue(new[] { 42 }.SequenceEqual(ids));

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);

            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
예제 #10
0
        public async Task Timing_Zero_Repeat()
        {
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var ids       = new List <int>();
            var countdown = new CountdownEvent(60);
            var context   = CreateReactContext(new MockInvocationHandler((name, args) =>
            {
                Assert.AreEqual(name, nameof(JSTimers.callTimers));
                ids.AddRange((IList <int>)args[0]);
                countdown.Signal();
            }));

            var timing = new Timing(context);

            timing.Initialize();
            await DispatcherHelpers.RunOnDispatcherAsync(context.OnResume);

            // Callback is called directly
            timing.createTimer(42, 0, DateTimeOffset.Now.ToUnixTimeMilliseconds(), true);
            countdown.Wait();
            timing.deleteTimer(42);

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);

            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
예제 #11
0
        public async Task UIManagerModule_CustomEvents_Constants()
        {
            var context          = new ReactContext();
            var viewManagers     = new List <IViewManager>();
            var uiImplementation = new UIImplementation(context, viewManagers);

            var module = await DispatcherHelpers.CallOnDispatcherAsync(
                () => new UIManagerModule(context, viewManagers, uiImplementation));

            var constants = module.Constants;

            Assert.AreEqual("onSelect", constants.GetMap("customBubblingEventTypes").GetMap("topSelect").GetMap("phasedRegistrationNames").GetValue("bubbled"));
            Assert.AreEqual("onSelectCapture", constants.GetMap("customBubblingEventTypes").GetMap("topSelect").GetMap("phasedRegistrationNames").GetValue("captured"));
            Assert.AreEqual("onChange", constants.GetMap("customBubblingEventTypes").GetMap("topChange").GetMap("phasedRegistrationNames").GetValue("bubbled"));
            Assert.AreEqual("onChangeCapture", constants.GetMap("customBubblingEventTypes").GetMap("topChange").GetMap("phasedRegistrationNames").GetValue("captured"));
            Assert.AreEqual("onTouchStart", constants.GetMap("customBubblingEventTypes").GetMap("topTouchStart").GetMap("phasedRegistrationNames").GetValue("bubbled"));
            Assert.AreEqual("onTouchStartCapture", constants.GetMap("customBubblingEventTypes").GetMap("topTouchStart").GetMap("phasedRegistrationNames").GetValue("captured"));
            Assert.AreEqual("onTouchMove", constants.GetMap("customBubblingEventTypes").GetMap("topTouchMove").GetMap("phasedRegistrationNames").GetValue("bubbled"));
            Assert.AreEqual("onTouchMoveCapture", constants.GetMap("customBubblingEventTypes").GetMap("topTouchMove").GetMap("phasedRegistrationNames").GetValue("captured"));
            Assert.AreEqual("onTouchEnd", constants.GetMap("customBubblingEventTypes").GetMap("topTouchEnd").GetMap("phasedRegistrationNames").GetValue("bubbled"));
            Assert.AreEqual("onTouchEndCapture", constants.GetMap("customBubblingEventTypes").GetMap("topTouchEnd").GetMap("phasedRegistrationNames").GetValue("captured"));

            Assert.AreEqual("onSelectionChange", constants.GetMap("customDirectEventTypes").GetMap("topSelectionChange").GetValue("registrationName"));
            Assert.AreEqual("onLoadingStart", constants.GetMap("customDirectEventTypes").GetMap("topLoadingStart").GetValue("registrationName"));
            Assert.AreEqual("onLoadingFinish", constants.GetMap("customDirectEventTypes").GetMap("topLoadingFinish").GetValue("registrationName"));
            Assert.AreEqual("onLoadingError", constants.GetMap("customDirectEventTypes").GetMap("topLoadingError").GetValue("registrationName"));
            Assert.AreEqual("onLayout", constants.GetMap("customDirectEventTypes").GetMap("topLayout").GetValue("registrationName"));
        }
        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, "Foo");
            var e2 = new NonCoalescedEvent(42, "Foo");

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

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

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);
        }
예제 #13
0
        public async Task Timing_ManyTimers()
        {
            var count     = 1000;
            var ids       = new List <int>(count);
            var countdown = new CountdownEvent(count);
            var context   = CreateReactContext(new MockInvocationHandler((name, args) =>
            {
                Assert.AreEqual(name, nameof(JSTimers.callTimers));
                var currentIds = (IList <int>)args[0];
                ids.AddRange(currentIds);
                for (var i = 0; i < currentIds.Count; ++i)
                {
                    countdown.Signal();
                }
            }));

            var timing = new Timing(context);

            timing.Initialize();
            await DispatcherHelpers.RunOnDispatcherAsync(context.OnResume);

            var now = DateTimeOffset.Now.ToUnixTimeMilliseconds();

            for (var i = 0; i < count; ++i)
            {
                timing.createTimer(i, i, now, false);
            }

            Assert.IsTrue(countdown.Wait(count * 2));

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);
        }
예제 #14
0
        public async Task Timing_Repeat()
        {
            var ids       = new List <int>();
            var repeat    = 10;
            var interval  = 200;
            var countdown = new CountdownEvent(repeat);
            var context   = CreateReactContext(new MockInvocationHandler((name, args) =>
            {
                Assert.AreEqual(name, nameof(JSTimers.callTimers));
                ids.AddRange((IList <int>)args[0]);
                if (countdown.CurrentCount > 0)
                {
                    var t = ThreadPool.RunAsync(_ => countdown.Signal());
                }
            }));

            var timing = new Timing(context);

            timing.Initialize();
            await DispatcherHelpers.RunOnDispatcherAsync(context.OnResume);

            var id  = 42;
            var now = DateTimeOffset.Now.ToUnixTimeMilliseconds();

            timing.createTimer(id, interval, now, true);

            Assert.IsTrue(countdown.Wait(interval * repeat * 2));

            timing.deleteTimer(id);

            Assert.AreEqual(42, ids.Distinct().SingleOrDefault());
            Assert.IsTrue(ids.Count >= repeat);

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);
        }
예제 #15
0
        public async Task UIManagerModule_Constants_ViewManager_LazyConstants()
        {
            var context      = new ReactContext();
            var viewManagers = new List <IViewManager> {
                new TestViewManager()
            };

            ReactNative.Bridge.DispatcherHelpers.MainDispatcher = Dispatcher.CurrentDispatcher;
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var uiImplementationProvider = new UIImplementationProvider();

            using (var actionQueue = new ActionQueue(ex => { }))
            {
                var module = await DispatcherHelpers.CallOnDispatcherAsync(
                    () => new UIManagerModule(context, viewManagers, uiImplementationProvider, actionQueue, UIManagerModuleOptions.LazyViewManagers));

                var obj = ((INativeModule)module).Constants.GetValue("ViewManagerNames");
                var viewManagerNames = obj as JArray;
                Assert.IsNotNull(viewManagerNames);
                Assert.AreEqual(1, viewManagerNames.Count());
                Assert.AreEqual("Test", viewManagerNames.Single().Value <string>());
            }

            // Ideally we should dispose, but the original dispatcher is somehow lost/etc.
            // 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);
        }
        public async Task EventDispatcher_IncorrectThreadCalls()
        {
            var context    = new ReactContext();
            var dispatcher = new EventDispatcher(context);

            AssertEx.Throws <InvalidOperationException>(() => dispatcher.OnReactInstanceDispose());

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);
        }
        public async Task EventDispatcher_ArgumentChecks()
        {
            AssertEx.Throws <ArgumentNullException>(() => new EventDispatcher(null), ex => Assert.AreEqual("reactContext", ex.ParamName));

            var context    = new ReactContext();
            var dispatcher = new EventDispatcher(context);

            AssertEx.Throws <ArgumentNullException>(() => dispatcher.DispatchEvent(null), ex => Assert.AreEqual("event", ex.ParamName));
            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);
        }
예제 #19
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);
        }
        private static async Task <ReactContext> CreateContextAsync(IJavaScriptExecutor executor)
        {
            var reactInstance = await DispatcherHelpers.CallOnDispatcherAsync(() => CreateReactInstance(executor));

            await InitializeReactInstanceAsync(reactInstance);

            var context = new ReactContext();

            context.InitializeWithInstance(reactInstance);
            return(context);
        }
예제 #21
0
        public async Task Timing_AnimationBehavior()
        {
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var id = 0;

            var seconds  = 3;
            var fps      = 60;
            var interval = 1000 / fps;

            var canceled = false;
            var fired    = new List <int>();

            var timing = default(Timing);
            var now    = default(long);

            var waitHandle = new AutoResetEvent(false);

            var context = CreateReactContext(new MockInvocationHandler((name, args) =>
            {
                if (!canceled)
                {
                    fired.Add(((IList <int>)args[0]).First());
                    now += interval;
                    timing.createTimer(++id, interval, now, false);
                }
                else
                {
                    waitHandle.Set();
                }
            }));

            timing = new Timing(context);
            timing.Initialize();
            await DispatcherHelpers.RunOnDispatcherAsync(context.OnResume);

            now = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            timing.createTimer(id, interval, now, false);

            await Task.Delay(TimeSpan.FromSeconds(seconds));

            canceled = true;

            var margin = 0.05;

            Assert.IsTrue(fired.Count > (seconds * fps * (1.0 - margin)));

            Assert.IsTrue(waitHandle.WaitOne());

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);

            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
        public async Task EventDispatcher_IncorrectThreadCalls()
        {
            var context    = new ReactContext();
            var dispatcher = new EventDispatcher(context);

            // THIS IS INCORRECT
            // The call asserts due to ReactChoreographer not being initialized. There's no
            // obvious thread check anywhere
            AssertEx.Throws <InvalidOperationException>(() => dispatcher.OnReactInstanceDispose());

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);
        }
예제 #23
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);
        }
예제 #24
0
        private static async Task <ReactContext> CreateContextAsync(IJavaScriptExecutor executor)
        {
            var context = new ReactContext();

            var reactInstance = await DispatcherHelpers.CallOnDispatcherAsync(async() =>
            {
                var instance = CreateReactInstance(context, executor);
                context.InitializeWithInstance(instance);
                instance.Initialize();
                await instance.InitializeBridgeAsync(CancellationToken.None);
                return(instance);
            });

            return(context);
        }
        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);
        }
예제 #26
0
        public async Task UIManagerModule_CustomEvents_Constants()
        {
            var context      = new ReactContext();
            var viewManagers = new List <IViewManager> {
                new NoEventsViewManager()
            };

            ReactNative.Bridge.DispatcherHelpers.MainDispatcher = Dispatcher.CurrentDispatcher;
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var uiImplementationProvider = new UIImplementationProvider();

            using (var actionQueue = new ActionQueue(ex => { }))
            {
                var module = await DispatcherHelpers.CallOnDispatcherAsync(
                    () => new UIManagerModule(context, viewManagers, uiImplementationProvider, actionQueue, UIManagerModuleOptions.None));

                var constants = ((INativeModule)module).Constants;

                Assert.AreEqual("onSelect", constants.GetMap("genericBubblingEventTypes").GetMap("topSelect").GetMap("phasedRegistrationNames").GetValue("bubbled").Value <string>());
                Assert.AreEqual("onSelectCapture", constants.GetMap("genericBubblingEventTypes").GetMap("topSelect").GetMap("phasedRegistrationNames").GetValue("captured").Value <string>());
                Assert.AreEqual("onChange", constants.GetMap("genericBubblingEventTypes").GetMap("topChange").GetMap("phasedRegistrationNames").GetValue("bubbled").Value <string>());
                Assert.AreEqual("onChangeCapture", constants.GetMap("genericBubblingEventTypes").GetMap("topChange").GetMap("phasedRegistrationNames").GetValue("captured").Value <string>());
                Assert.AreEqual("onTouchStart", constants.GetMap("genericBubblingEventTypes").GetMap("topTouchStart").GetMap("phasedRegistrationNames").GetValue("bubbled").Value <string>());
                Assert.AreEqual("onTouchStartCapture", constants.GetMap("genericBubblingEventTypes").GetMap("topTouchStart").GetMap("phasedRegistrationNames").GetValue("captured").Value <string>());
                Assert.AreEqual("onTouchMove", constants.GetMap("genericBubblingEventTypes").GetMap("topTouchMove").GetMap("phasedRegistrationNames").GetValue("bubbled").Value <string>());
                Assert.AreEqual("onTouchMoveCapture", constants.GetMap("genericBubblingEventTypes").GetMap("topTouchMove").GetMap("phasedRegistrationNames").GetValue("captured").Value <string>());
                Assert.AreEqual("onTouchEnd", constants.GetMap("genericBubblingEventTypes").GetMap("topTouchEnd").GetMap("phasedRegistrationNames").GetValue("bubbled").Value <string>());
                Assert.AreEqual("onTouchEndCapture", constants.GetMap("genericBubblingEventTypes").GetMap("topTouchEnd").GetMap("phasedRegistrationNames").GetValue("captured").Value <string>());
                Assert.AreEqual("onMouseOver", constants.GetMap("genericBubblingEventTypes").GetMap("topMouseOver").GetMap("phasedRegistrationNames").GetValue("bubbled").Value <string>());
                Assert.AreEqual("onMouseOverCapture", constants.GetMap("genericBubblingEventTypes").GetMap("topMouseOver").GetMap("phasedRegistrationNames").GetValue("captured").Value <string>());
                Assert.AreEqual("onMouseOut", constants.GetMap("genericBubblingEventTypes").GetMap("topMouseOut").GetMap("phasedRegistrationNames").GetValue("bubbled").Value <string>());
                Assert.AreEqual("onMouseOutCapture", constants.GetMap("genericBubblingEventTypes").GetMap("topMouseOut").GetMap("phasedRegistrationNames").GetValue("captured").Value <string>());

                Assert.AreEqual("onSelectionChange", constants.GetMap("genericDirectEventTypes").GetMap("topSelectionChange").GetValue("registrationName").Value <string>());
                Assert.AreEqual("onLoadingStart", constants.GetMap("genericDirectEventTypes").GetMap("topLoadingStart").GetValue("registrationName").Value <string>());
                Assert.AreEqual("onLoadingFinish", constants.GetMap("genericDirectEventTypes").GetMap("topLoadingFinish").GetValue("registrationName").Value <string>());
                Assert.AreEqual("onLoadingError", constants.GetMap("genericDirectEventTypes").GetMap("topLoadingError").GetValue("registrationName").Value <string>());
                Assert.AreEqual("onLayout", constants.GetMap("genericDirectEventTypes").GetMap("topLayout").GetValue("registrationName").Value <string>());
                Assert.AreEqual("onMouseEnter", constants.GetMap("genericDirectEventTypes").GetMap("topMouseEnter").GetValue("registrationName").Value <string>());
                Assert.AreEqual("onMouseLeave", constants.GetMap("genericDirectEventTypes").GetMap("topMouseLeave").GetValue("registrationName").Value <string>());
                Assert.AreEqual("onMessage", constants.GetMap("genericDirectEventTypes").GetMap("topMessage").GetValue("registrationName").Value <string>());
            }

            // Ideally we should dispose, but the original dispatcher is somehow lost/etc.
            // await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
예제 #27
0
        public async Task Timing_ManOrBoy()
        {
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var r           = new Random();
            var batchCount  = 15;
            var maxDuration = 500;
            var maxBatch    = 10000;
            var id          = 0;

            var ids       = new List <int>();
            var countdown = new CountdownEvent(1);
            var context   = CreateReactContext(new MockInvocationHandler((name, args) =>
            {
                Assert.AreEqual(name, nameof(JSTimers.callTimers));
                var firedTimers = (IList <int>)args[0];
                ids.AddRange((IList <int>)args[0]);
                countdown.Signal(firedTimers.Count);
            }));

            var timing = new Timing(context);

            timing.Initialize();
            await DispatcherHelpers.RunOnDispatcherAsync(context.OnResume);

            for (var i = 0; i < batchCount; ++i)
            {
                var batchSize = r.Next(maxBatch);
                countdown.AddCount(batchSize);
                for (var j = 0; j < batchSize; ++j)
                {
                    var now      = DateTimeOffset.Now.ToUnixTimeMilliseconds();
                    var duration = r.Next(maxDuration);
                    timing.createTimer(id++, duration, now, false);
                }

                await Task.Delay(maxDuration / 4);
            }

            countdown.Signal();
            Assert.IsTrue(countdown.Wait(batchCount * maxDuration / 4 * 2));

            await DispatcherHelpers.CallOnDispatcherAsync(context.DisposeAsync);

            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Dispose);
        }
예제 #28
0
        public async Task UIManagerModule_Constants_ViewManagerOverrides()
        {
            var context      = new ReactContext();
            var viewManagers = new List <IViewManager> {
                new TestViewManager()
            };
            var uiImplementation = new UIImplementation(context, viewManagers);

            var module = await DispatcherHelpers.CallOnDispatcherAsync(
                () => new UIManagerModule(context, viewManagers, uiImplementation));

            var constants = module.Constants;

            Assert.AreEqual(42, constants.GetMap("customDirectEventTypes").GetValue("otherSelectionChange"));
            Assert.AreEqual(42, constants.GetMap("customDirectEventTypes").GetMap("topSelectionChange").GetValue("registrationName"));
            Assert.AreEqual(42, constants.GetMap("customDirectEventTypes").GetMap("topLoadingStart").GetValue("foo"));
            Assert.AreEqual(42, constants.GetMap("customDirectEventTypes").GetValue("topLoadingError"));
        }
예제 #29
0
        public async Task UIManagerModule_CustomEvents_Constants()
        {
            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.Initialize);

            var context      = new ReactContext();
            var viewManagers = new List <IViewManager> {
                new NoEventsViewManager()
            };
            var uiImplementationProvider = new UIImplementationProvider();

            using (var actionQueue = new ActionQueue(ex => { }))
            {
                var module = await DispatcherHelpers.CallOnDispatcherAsync(() => new UIManagerModule(context, viewManagers, uiImplementationProvider, actionQueue));

                var constants = module.Constants.GetMap("Test");

                Assert.AreEqual("onSelect", constants.GetMap("bubblingEventTypes").GetMap("topSelect").GetMap("phasedRegistrationNames").GetValue("bubbled"));
                Assert.AreEqual("onSelectCapture", constants.GetMap("bubblingEventTypes").GetMap("topSelect").GetMap("phasedRegistrationNames").GetValue("captured"));
                Assert.AreEqual("onChange", constants.GetMap("bubblingEventTypes").GetMap("topChange").GetMap("phasedRegistrationNames").GetValue("bubbled"));
                Assert.AreEqual("onChangeCapture", constants.GetMap("bubblingEventTypes").GetMap("topChange").GetMap("phasedRegistrationNames").GetValue("captured"));
                Assert.AreEqual("onTouchStart", constants.GetMap("bubblingEventTypes").GetMap("topTouchStart").GetMap("phasedRegistrationNames").GetValue("bubbled"));
                Assert.AreEqual("onTouchStartCapture", constants.GetMap("bubblingEventTypes").GetMap("topTouchStart").GetMap("phasedRegistrationNames").GetValue("captured"));
                Assert.AreEqual("onTouchMove", constants.GetMap("bubblingEventTypes").GetMap("topTouchMove").GetMap("phasedRegistrationNames").GetValue("bubbled"));
                Assert.AreEqual("onTouchMoveCapture", constants.GetMap("bubblingEventTypes").GetMap("topTouchMove").GetMap("phasedRegistrationNames").GetValue("captured"));
                Assert.AreEqual("onTouchEnd", constants.GetMap("bubblingEventTypes").GetMap("topTouchEnd").GetMap("phasedRegistrationNames").GetValue("bubbled"));
                Assert.AreEqual("onTouchEndCapture", constants.GetMap("bubblingEventTypes").GetMap("topTouchEnd").GetMap("phasedRegistrationNames").GetValue("captured"));
                Assert.AreEqual("onMouseOver", constants.GetMap("bubblingEventTypes").GetMap("topMouseOver").GetMap("phasedRegistrationNames").GetValue("bubbled"));
                Assert.AreEqual("onMouseOverCapture", constants.GetMap("bubblingEventTypes").GetMap("topMouseOver").GetMap("phasedRegistrationNames").GetValue("captured"));
                Assert.AreEqual("onMouseOut", constants.GetMap("bubblingEventTypes").GetMap("topMouseOut").GetMap("phasedRegistrationNames").GetValue("bubbled"));
                Assert.AreEqual("onMouseOutCapture", constants.GetMap("bubblingEventTypes").GetMap("topMouseOut").GetMap("phasedRegistrationNames").GetValue("captured"));

                Assert.AreEqual("onSelectionChange", constants.GetMap("directEventTypes").GetMap("topSelectionChange").GetValue("registrationName"));
                Assert.AreEqual("onLoadingStart", constants.GetMap("directEventTypes").GetMap("topLoadingStart").GetValue("registrationName"));
                Assert.AreEqual("onLoadingFinish", constants.GetMap("directEventTypes").GetMap("topLoadingFinish").GetValue("registrationName"));
                Assert.AreEqual("onLoadingError", constants.GetMap("directEventTypes").GetMap("topLoadingError").GetValue("registrationName"));
                Assert.AreEqual("onLayout", constants.GetMap("directEventTypes").GetMap("topLayout").GetValue("registrationName"));
                Assert.AreEqual("onMouseEnter", constants.GetMap("directEventTypes").GetMap("topMouseEnter").GetValue("registrationName"));
                Assert.AreEqual("onMouseLeave", constants.GetMap("directEventTypes").GetMap("topMouseLeave").GetValue("registrationName"));
                Assert.AreEqual("onMessage", constants.GetMap("directEventTypes").GetMap("topMessage").GetValue("registrationName"));
            }

            await DispatcherHelpers.RunOnDispatcherAsync(ReactChoreographer.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);
        }