chore: tests

This commit is contained in:
shirakaba
2022-11-23 01:40:29 +09:00
parent 7a276df09c
commit 832595281f
6 changed files with 372 additions and 22 deletions

View File

@@ -185,6 +185,79 @@ export var test_Observable_addEventListener_MultipleEvents_ShouldTrim = function
TKUnit.assert(receivedCount === 2, 'Callbacks not raised properly.');
};
export var test_Observable_addEventListener_ListenerEquality_Same = function () {
var obj = new TestObservable();
var count = 0;
var callback = function (data: EventData) {
count++;
};
obj.addEventListener(Observable.propertyChangeEvent, callback);
obj.addEventListener(Observable.propertyChangeEvent, callback);
obj.set('testName', 1);
TKUnit.assert(count === 1, 'The propertyChanged notification should be raised once.');
};
export var test_Observable_addEventListener_ListenerEquality_SameForFalsyThisArg = function () {
var obj = new TestObservable();
var count = 0;
var callback = function (data: EventData) {
count++;
};
obj.addEventListener(Observable.propertyChangeEvent, callback);
obj.addEventListener(Observable.propertyChangeEvent, callback, null);
obj.addEventListener(Observable.propertyChangeEvent, callback, undefined);
obj.addEventListener(Observable.propertyChangeEvent, callback, false);
obj.addEventListener(Observable.propertyChangeEvent, callback, 0);
obj.addEventListener(Observable.propertyChangeEvent, callback, NaN);
obj.addEventListener(Observable.propertyChangeEvent, callback, '');
obj.set('testName', 1);
TKUnit.assert(count === 1, `Expected to register exactly 1 event listener due to falsy thisArgs being treated the same as omitted thisArgs, but found ${count} events fired.`);
};
export var test_Observable_addEventListener_ListenerEquality_DistinctByStrictEquality = function () {
var obj = new TestObservable();
var count = 0;
var callback = function (data: EventData) {
count++;
};
obj.addEventListener(Observable.propertyChangeEvent, callback);
obj.addEventListener(Observable.propertyChangeEvent, callback, {});
obj.addEventListener(Observable.propertyChangeEvent, callback, {});
obj.set('testName', 1);
TKUnit.assert(count === 3, `Expected to register exactly 3 event listeners due to thisArgs differing by strict equality, but found ${count} events fired.`);
};
export var test_Observable_addEventListener_ListenerEquality_DistinctByCapture = function () {
var obj = new TestObservable();
var count = 0;
var callback = function (data: EventData) {
count++;
};
obj.addEventListener(Observable.propertyChangeEvent, callback, null);
obj.addEventListener(Observable.propertyChangeEvent, callback, null, true);
obj.addEventListener(Observable.propertyChangeEvent, callback, null, false);
obj.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: true });
obj.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
obj.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: true, once: true });
obj.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: true, passive: true });
obj.set('testName', 1);
TKUnit.assert(count === 2, `Expected to register exactly 2 event listeners due to their equality depending only on the capture value, but found ${count} events fired.`);
};
// TODO: corresponding removeEventListener tests, making sure we only remove more than one event listener when passing in just the event name as an arg.
export var test_Observable_addEventListener_MultipleCallbacks = function () {
var obj = new TestObservable();

View File

@@ -4,7 +4,7 @@ import { GestureEventData, Label, GestureTypes, PanGestureEventData, PinchGestur
export var test_DummyTestForSnippetOnly0 = function () {
// >> gestures-double-tap
var label = new Label();
var observer = label.on(GestureTypes.doubleTap, function (args: GestureEventData) {
label.on(GestureTypes.doubleTap, function (args: GestureEventData) {
console.log('Double Tap');
});
// << gestures-double-tap
@@ -13,7 +13,7 @@ export var test_DummyTestForSnippetOnly0 = function () {
export var test_DummyTestForSnippetOnly01 = function () {
// >> gestures-double-tap-alt
var label = new Label();
var observer = label.on('doubleTap', function (args: GestureEventData) {
label.on('doubleTap', function (args: GestureEventData) {
console.log('Double Tap');
});
// << gestures-double-tap-alt
@@ -22,7 +22,7 @@ export var test_DummyTestForSnippetOnly01 = function () {
export var test_DummyTestForSnippetOnly1 = function () {
// >> gestures-long-press
var label = new Label();
var observer = label.on(GestureTypes.longPress, function (args: GestureEventData) {
label.on(GestureTypes.longPress, function (args: GestureEventData) {
console.log('Long Press');
});
// << gestures-long-press
@@ -31,7 +31,7 @@ export var test_DummyTestForSnippetOnly1 = function () {
export var test_DummyTestForSnippetOnly11 = function () {
// >> gestures-long-press-alt
var label = new Label();
var observer = label.on('longPress', function (args: GestureEventData) {
label.on('longPress', function (args: GestureEventData) {
console.log('Long Press');
});
// << gestures-long-press-alt
@@ -40,7 +40,7 @@ export var test_DummyTestForSnippetOnly11 = function () {
export var test_DummyTestForSnippetOnly2 = function () {
// >> gestures-pan
var label = new Label();
var observer = label.on(GestureTypes.pan, function (args: PanGestureEventData) {
label.on(GestureTypes.pan, function (args: PanGestureEventData) {
console.log('Pan deltaX:' + args.deltaX + '; deltaY:' + args.deltaY + ';');
});
// << gestures-pan
@@ -49,7 +49,7 @@ export var test_DummyTestForSnippetOnly2 = function () {
export var test_DummyTestForSnippetOnly22 = function () {
// >> gestures-pan-alt
var label = new Label();
var observer = label.on('pan', function (args: PanGestureEventData) {
label.on('pan', function (args: PanGestureEventData) {
console.log('Pan deltaX:' + args.deltaX + '; deltaY:' + args.deltaY + ';');
});
// << gestures-pan-alt
@@ -58,7 +58,7 @@ export var test_DummyTestForSnippetOnly22 = function () {
export var test_DummyTestForSnippetOnly3 = function () {
// >> gestures-pan-pinch
var label = new Label();
var observer = label.on(GestureTypes.pinch, function (args: PinchGestureEventData) {
label.on(GestureTypes.pinch, function (args: PinchGestureEventData) {
console.log('Pinch scale: ' + args.scale);
});
// << gestures-pan-pinch
@@ -67,7 +67,7 @@ export var test_DummyTestForSnippetOnly3 = function () {
export var test_DummyTestForSnippetOnly33 = function () {
// >> gestures-pan-pinch-alt
var label = new Label();
var observer = label.on('pinch', function (args: PinchGestureEventData) {
label.on('pinch', function (args: PinchGestureEventData) {
console.log('Pinch scale: ' + args.scale);
});
// << gestures-pan-pinch-alt
@@ -76,7 +76,7 @@ export var test_DummyTestForSnippetOnly33 = function () {
export var test_DummyTestForSnippetOnly4 = function () {
// >> gestures-rotation
var label = new Label();
var observer = label.on(GestureTypes.rotation, function (args: RotationGestureEventData) {
label.on(GestureTypes.rotation, function (args: RotationGestureEventData) {
console.log('Rotation: ' + args.rotation);
});
// << gestures-rotation
@@ -85,7 +85,7 @@ export var test_DummyTestForSnippetOnly4 = function () {
export var test_DummyTestForSnippetOnly44 = function () {
// >> gestures-rotation-alt
var label = new Label();
var observer = label.on('rotation', function (args: RotationGestureEventData) {
label.on('rotation', function (args: RotationGestureEventData) {
console.log('Rotation: ' + args.rotation);
});
// << gestures-rotation-alt
@@ -94,7 +94,7 @@ export var test_DummyTestForSnippetOnly44 = function () {
export var test_DummyTestForSnippetOnly5 = function () {
// >> gestures-swipe
var label = new Label();
var observer = label.on(GestureTypes.swipe, function (args: SwipeGestureEventData) {
label.on(GestureTypes.swipe, function (args: SwipeGestureEventData) {
console.log('Swipe direction: ' + args.direction);
});
// << gestures-swipe
@@ -103,7 +103,7 @@ export var test_DummyTestForSnippetOnly5 = function () {
export var test_DummyTestForSnippetOnly55 = function () {
// >> gestures-swipe-alt
var label = new Label();
var observer = label.on('swipe', function (args: SwipeGestureEventData) {
label.on('swipe', function (args: SwipeGestureEventData) {
console.log('Swipe direction: ' + args.direction);
});
// << gestures-swipe-alt
@@ -112,7 +112,7 @@ export var test_DummyTestForSnippetOnly55 = function () {
export var test_DummyTestForSnippetOnly6 = function () {
// >> gestures-tap
var label = new Label();
var observer = label.on(GestureTypes.tap, function (args: GestureEventData) {
label.on(GestureTypes.tap, function (args: GestureEventData) {
console.log('Tap');
});
// << gestures-tap
@@ -121,7 +121,7 @@ export var test_DummyTestForSnippetOnly6 = function () {
export var test_DummyTestForSnippetOnly66 = function () {
// >> gestures-tap-alt
var label = new Label();
var observer = label.on('tap', function (args: GestureEventData) {
label.on('tap', function (args: GestureEventData) {
console.log('Tap');
});
// << gestures-tap-alt
@@ -129,18 +129,19 @@ export var test_DummyTestForSnippetOnly66 = function () {
export var test_DummyTestForSnippetOnly7 = function () {
// >> gestures-stop-observe
var label = new Label();
var observer = label.on(GestureTypes.tap, function (args: GestureEventData) {
function onTap(args: GestureEventData) {
console.log('Tap');
});
observer.disconnect();
}
const label = new Label();
label.on(GestureTypes.tap, onTap);
label.off(GestureTypes.tap, onTap);
// << gestures-stop-observe
};
export var test_DummyTestForSnippetOnly8 = function () {
// >> gestures-multiple
var label = new Label();
var observer = label.on(GestureTypes.tap | GestureTypes.doubleTap | GestureTypes.longPress, function (args: GestureEventData) {
label.on(GestureTypes.tap | GestureTypes.doubleTap | GestureTypes.longPress, function (args: GestureEventData) {
console.log('Event: ' + args.eventName);
});
// << gestures-multiple
@@ -149,7 +150,7 @@ export var test_DummyTestForSnippetOnly8 = function () {
export var test_DummyTestForSnippetOnly88 = function () {
// >> gestures-string
var label = new Label();
var observer = label.on('tap, doubleTap, longPress', function (args: GestureEventData) {
label.on('tap, doubleTap, longPress', function (args: GestureEventData) {
console.log('Event: ' + args.eventName);
});
// << gestures-string
@@ -158,7 +159,7 @@ export var test_DummyTestForSnippetOnly88 = function () {
export var test_DummyTestForSnippetOnly9 = function () {
// >> gestures-events-string
var label = new Label();
var observer = label.on('loaded, tap, longPress', function (args: GestureEventData) {
label.on('loaded, tap, longPress', function (args: GestureEventData) {
console.log('Event: ' + args.eventName);
});
// << gestures-events-string

View File

@@ -1,5 +1,5 @@
import * as TKUnit from '../../tk-unit';
import { View, eachDescendant, getViewById, InheritedProperty, CssProperty, CssAnimationProperty, ShorthandProperty, Property, Style, Frame, Page, Button, Label, Color, StackLayout, AbsoluteLayout, Observable, Utils, BindingOptions, isAndroid, LayoutBase } from '@nativescript/core';
import { View, eachDescendant, getViewById, InheritedProperty, CssProperty, CssAnimationProperty, ShorthandProperty, Property, Style, Frame, Page, ActionBar, Button, Label, Color, StackLayout, AbsoluteLayout, Observable, Utils, BindingOptions, isAndroid, LayoutBase, EventData, ViewBase, DOMEvent } from '@nativescript/core';
import * as helper from '../../ui-helper';
import * as definition from './view-tests';
@@ -35,6 +35,266 @@ export function test_getViewById_Static() {
helper.do_PageTest_WithButton(test);
}
export function test_event_bubbling() {
const test = function ([page, button, actionBar]: [Page, Button, ActionBar]) {
const frameIdBefore = page.frame!.id;
page.frame!.id = 'frame';
page.id = 'page';
button.id = 'button';
actionBar.id = 'actionBar';
const ids: string[] = [];
const callback = (data: EventData) => {
const domEvent = DOMEvent.unstable_currentEvent!;
ids.push((domEvent.currentTarget as ViewBase).id);
};
page.frame!.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
page.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
button.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
// ActionBar is not in the bubbling path, but we listen to it just to
// test that the event is following the expected path.
actionBar.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
button.setProperty('hidden', true, { bubbles: true });
const observed = JSON.stringify(ids);
const expected = JSON.stringify(['button', 'page', 'frame']);
TKUnit.assert(expected === observed, `Expected ${expected}, but got ${observed}`);
// Clean up (the test runner reuses the page rather than creating a
// fresh one)
page.frame.id = frameIdBefore;
page.frame!.removeEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
page.removeEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
button.removeEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
actionBar.removeEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
};
helper.do_PageTest_WithButton(test);
}
export function test_event_capturing() {
const test = function ([page, button, actionBar]: [Page, Button, ActionBar]) {
const frameIdBefore = page.frame!.id;
page.frame!.id = 'frame';
page.id = 'page';
button.id = 'button';
actionBar.id = 'actionBar';
const ids: string[] = [];
const callback = (data: EventData) => {
const domEvent = DOMEvent.unstable_currentEvent!;
ids.push((domEvent.currentTarget as ViewBase).id);
};
page.frame!.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: true });
page.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: true });
button.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: true });
// ActionBar is not in the bubbling path, but we listen to it just to
// test that the event is following the expected path.
actionBar.addEventListener(Observable.propertyChangeEvent, callback, null, { capture: true });
button.setProperty('hidden', true, { bubbles: true });
const observed = JSON.stringify(ids);
const expected = JSON.stringify(['frame', 'page', 'button']);
TKUnit.assert(expected === observed, `Expected ${expected}, but got ${observed}`);
// Clean up (the test runner reuses the page rather than creating a
// fresh one)
page.frame.id = frameIdBefore;
page.frame!.removeEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
page.removeEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
button.removeEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
actionBar.removeEventListener(Observable.propertyChangeEvent, callback, null, { capture: false });
};
helper.do_PageTest_WithButton(test);
}
export function test_event_stopImmediatePropagation() {
const test = function ([page, button]: [Page, Button, ActionBar]) {
page.id = 'page';
button.id = 'button';
const ids: string[] = [];
const callback1 = (data: EventData) => {
const domEvent = DOMEvent.unstable_currentEvent!;
ids.push(`${(domEvent.currentTarget as ViewBase).id}1`);
domEvent.stopImmediatePropagation();
};
const callback2 = (data: EventData) => {
const domEvent = DOMEvent.unstable_currentEvent!;
ids.push(`${(domEvent.currentTarget as ViewBase).id}2`);
domEvent.stopImmediatePropagation();
};
page.addEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.addEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.addEventListener(Observable.propertyChangeEvent, callback2, null, { capture: false });
button.setProperty('hidden', true, { bubbles: true });
const observed = JSON.stringify(ids);
const expected = JSON.stringify(['button2']);
TKUnit.assert(expected === observed, `Expected ${expected}, but got ${observed}`);
// Clean up (the test runner reuses the page rather than creating a
// fresh one)
page.removeEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.removeEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.removeEventListener(Observable.propertyChangeEvent, callback2, null, { capture: false });
};
helper.do_PageTest_WithButton(test);
}
export function test_event_stopPropagation() {
const test = function ([page, button]: [Page, Button, ActionBar]) {
page.id = 'page';
button.id = 'button';
const ids: string[] = [];
const callback1 = (data: EventData) => {
const domEvent = DOMEvent.unstable_currentEvent!;
ids.push(`${(domEvent.currentTarget as ViewBase).id}1`);
domEvent.stopPropagation();
};
const callback2 = (data: EventData) => {
const domEvent = DOMEvent.unstable_currentEvent!;
ids.push(`${(domEvent.currentTarget as ViewBase).id}2`);
domEvent.stopPropagation();
};
page.addEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.addEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.addEventListener(Observable.propertyChangeEvent, callback2, null, { capture: false });
button.setProperty('hidden', true, { bubbles: true });
const observed = JSON.stringify(ids);
const expected = JSON.stringify(['button2', 'button1']);
TKUnit.assert(expected === observed, `Expected ${expected}, but got ${observed}`);
// Clean up (the test runner reuses the page rather than creating a
// fresh one)
page.removeEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.removeEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.removeEventListener(Observable.propertyChangeEvent, callback2, null, { capture: false });
};
helper.do_PageTest_WithButton(test);
}
export function test_event_addEventListenerOnPath() {
const test = function ([page, button]: [Page, Button, ActionBar]) {
page.id = 'page';
button.id = 'button';
const ids: string[] = [];
const callback1 = (data: EventData) => {
const domEvent = DOMEvent.unstable_currentEvent!;
ids.push(`${(domEvent.currentTarget as ViewBase).id}1`);
// Regarding adding an event listener to the currentTarget:
//
// Although we add a listener for callback2 to button now, it's too
// late for it to receive an event because our DOM Events
// implementation evaluates the list of listener entries for the
// currentTarget only once (and thus doesn't reassess it after each
// listener's callback called).
//
// This is partially for performance, partially for simplicity of
// implementation, and partially because it may actually be
// consistent with the DOM spec in the first place (I haven't
// checked, as it's quite exotic).
button.addEventListener(Observable.propertyChangeEvent, callback2, null, { capture: false });
// Regarding adding an event listener to another target in the
// propagation path:
//
// A listener added to the next event target in the propagation path
// (whether it's bubbling or capturing phase) *should* get called,
// as our implementation assesses the listener entries afresh as it
// visits each event target in the path (rather than planning out
// which entries to run on which targets in advance). I believe this
// is consistent with the DOM spec.
page.addEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
};
const callback2 = (data: EventData) => {
const domEvent = DOMEvent.unstable_currentEvent!;
ids.push(`${(domEvent.currentTarget as ViewBase).id}2`);
};
page.addEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.addEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.setProperty('hidden', true, { bubbles: true });
const observed = JSON.stringify(ids);
const expected = JSON.stringify(['button1', 'page1']);
TKUnit.assert(expected === observed, `Expected ${expected}, but got ${observed}`);
// Clean up (the test runner reuses the page rather than creating a
// fresh one)
page.removeEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.removeEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.removeEventListener(Observable.propertyChangeEvent, callback2, null, { capture: false });
};
helper.do_PageTest_WithButton(test);
}
export function test_event_removeEventListenerOnPath() {
const test = function ([page, button]: [Page, Button, ActionBar]) {
page.id = 'page';
button.id = 'button';
const ids: string[] = [];
const callback1 = (data: EventData) => {
const domEvent = DOMEvent.unstable_currentEvent!;
ids.push(`${(domEvent.currentTarget as ViewBase).id}1`);
};
// This callback should run first (given that it is added last).
const callback2 = (data: EventData) => {
const domEvent = DOMEvent.unstable_currentEvent!;
ids.push(`${(domEvent.currentTarget as ViewBase).id}2`);
// We'll remove the callbacks that would otherwise run straight
// after it.
button.removeEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
page.removeEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
};
page.addEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.addEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.addEventListener(Observable.propertyChangeEvent, callback2, null, { capture: false });
button.setProperty('hidden', true, { bubbles: true });
const observed = JSON.stringify(ids);
const expected = JSON.stringify(['button2']);
TKUnit.assert(expected === observed, `Expected ${expected}, but got ${observed}`);
// Clean up (the test runner reuses the page rather than creating a
// fresh one)
page.removeEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.removeEventListener(Observable.propertyChangeEvent, callback1, null, { capture: false });
button.removeEventListener(Observable.propertyChangeEvent, callback2, null, { capture: false });
};
helper.do_PageTest_WithButton(test);
}
export function test_getViewById_Instance() {
const test = function (views: Array<View>) {
views[1].id = 'myLayout';

View File

@@ -11,6 +11,16 @@ const timeOrigin = Date.now();
const emptyArray = [] as const;
export class DOMEvent {
/**
* @private
* Internal API to facilitate testing - to be removed once we've completed
* the breaking changes to migrate fully to DOMEvents.
*
* Gets the last event to be dispatched, allowing you to access the DOM
* Event that corresponds to the currently-running callback.
*/
static unstable_currentEvent: DOMEvent | null = null;
readonly NONE = 0;
readonly CAPTURING_PHASE = 1;
readonly AT_TARGET = 2;
@@ -216,6 +226,10 @@ export class DOMEvent {
this.target = target;
this._canceled = false;
// Internal API to facilitate testing - to be removed once we've
// completed the breaking changes to migrate fully to DOMEvents.
DOMEvent.unstable_currentEvent = this;
/**
* Resets any internal state to allow the event to be redispatched. Call
* this before returning.

View File

@@ -77,6 +77,7 @@ export declare const Connectivity: {
};
export * from './core-types';
export { CSSUtils } from './css/system-classes';
export { DOMEvent } from './data/dom-events/dom-event';
export { ObservableArray, ChangeType } from './data/observable-array';
export type { ChangedData } from './data/observable-array';
export { Observable, WrappedValue, fromObject, fromObjectRecursive } from './data/observable';

View File

@@ -97,6 +97,7 @@ export * from './core-types';
export { CSSUtils } from './css/system-classes';
export { DOMEvent } from './data/dom-events/dom-event';
export { ObservableArray, ChangeType } from './data/observable-array';
export type { ChangedData } from './data/observable-array';
export { Observable, WrappedValue, fromObject, fromObjectRecursive } from './data/observable';