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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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")); }
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); }