diff --git a/.eslintrc b/.eslintrc index 8d41320c0..72845e2f3 100644 --- a/.eslintrc +++ b/.eslintrc @@ -34,7 +34,8 @@ { "files": ["*.tsx"], "rules": { - "@typescript-eslint/no-unused-vars": "off" + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-any": "off" } } ] diff --git a/apps/automated/app/test-runner.ts b/apps/automated/app/test-runner.ts index da0db5d56..015b82477 100644 --- a/apps/automated/app/test-runner.ts +++ b/apps/automated/app/test-runner.ts @@ -21,22 +21,25 @@ export function isRunningOnEmulator(): boolean { } } -export const allTests = {}; + // Enable running a singleTest group, type the group name here + const singleTest = null; -import * as globalsTests from './globals/globals-tests'; -allTests['GLOBALS'] = globalsTests; + let allTests = {}; -import * as domNodeTest from './debugger/dom-node-tests'; -allTests['DOM-NODE'] = domNodeTest; + import * as globalsTests from './globals/globals-tests'; + allTests['GLOBALS'] = globalsTests; -import * as profilingTests from './profiling/profiling-tests'; -allTests['PROFILING'] = profilingTests; + import * as domNodeTest from './debugger/dom-node-tests'; + allTests['DOM-NODE'] = domNodeTest; -import * as platformTests from './platform/platform-tests'; -allTests['PLATFORM'] = platformTests; + import * as profilingTests from './profiling/profiling-tests'; + allTests['PROFILING'] = profilingTests; -import * as fsTests from './file-system/file-system-tests'; -allTests['FILE-SYSTEM'] = fsTests; + import * as platformTests from './platform/platform-tests'; + allTests['PLATFORM'] = platformTests; + + import * as fsTests from './file-system/file-system-tests'; + allTests['FILE-SYSTEM'] = fsTests; // Disabled tests as they have external dependencies // TODO: find a way to run these tests locally, but don't run them on the CI as they are flaky @@ -49,265 +52,276 @@ allTests['FILE-SYSTEM'] = fsTests; // import * as fetchTests from "./fetch/fetch-tests"; // allTests["FETCH"] = fetchTests; -import * as appSettingsTests from './application-settings/application-settings-tests'; -allTests['APPLICATION-SETTINGS'] = appSettingsTests; + import * as appSettingsTests from './application-settings/application-settings-tests'; + allTests['APPLICATION-SETTINGS'] = appSettingsTests; -import * as applicationTests from './application/application-tests'; -allTests['APPLICATION'] = applicationTests; + import * as applicationTests from './application/application-tests'; + allTests['APPLICATION'] = applicationTests; -import * as imageSourceTests from './image-source/image-source-tests'; -allTests['IMAGE-SOURCE'] = imageSourceTests; + import * as imageSourceTests from './image-source/image-source-tests'; + allTests['IMAGE-SOURCE'] = imageSourceTests; -import * as observableArrayTests from './data/observable-array-tests'; -allTests['OBSERVABLE-ARRAY'] = observableArrayTests; + import * as observableArrayTests from './data/observable-array-tests'; + allTests['OBSERVABLE-ARRAY'] = observableArrayTests; -import * as virtualArrayTests from './data/virtual-array-tests'; -allTests['VIRTUAL-ARRAY'] = virtualArrayTests; + import * as virtualArrayTests from './data/virtual-array-tests'; + allTests['VIRTUAL-ARRAY'] = virtualArrayTests; -import * as observableTests from './data/observable-tests'; -allTests['OBSERVABLE'] = observableTests; + import * as observableTests from './data/observable-tests'; + allTests['OBSERVABLE'] = observableTests; -import * as timerTests from './timer/timer-tests'; -allTests['TIMER'] = timerTests; + import * as timerTests from './timer/timer-tests'; + allTests['TIMER'] = timerTests; -import * as animationFrameTests from './animation-frame/animation-frame'; -allTests['ANIMATION-FRAME'] = animationFrameTests; + import * as animationFrameTests from './animation-frame/animation-frame'; + allTests['ANIMATION-FRAME'] = animationFrameTests; -import * as colorTests from './color/color-tests'; -allTests['COLOR'] = colorTests; + import * as colorTests from './color/color-tests'; + allTests['COLOR'] = colorTests; -import * as bindableTests from './ui/core/bindable/bindable-tests'; -allTests['BINDABLE'] = bindableTests; + import * as bindableTests from './ui/core/bindable/bindable-tests'; + allTests['BINDABLE'] = bindableTests; -import * as bindingExpressionTests from './ui/core/bindable/binding-expressions-tests'; -allTests['BINDING-EXPRESSIONS'] = bindingExpressionTests; + import * as bindingExpressionTests from './ui/core/bindable/binding-expressions-tests'; + allTests['BINDING-EXPRESSIONS'] = bindingExpressionTests; -import * as xmlParserTests from './xml-parser-tests/xml-parser-tests'; -allTests['XML-PARSER'] = xmlParserTests; + import * as xmlParserTests from './xml-parser-tests/xml-parser-tests'; + allTests['XML-PARSER'] = xmlParserTests; -import * as formattedStringTests from './text/formatted-string-tests'; -allTests['FORMATTEDSTRING'] = formattedStringTests; + import * as formattedStringTests from './text/formatted-string-tests'; + allTests['FORMATTEDSTRING'] = formattedStringTests; -import * as fileSystemAccessTests from './file-system-access-tests/file-system-access-tests'; -allTests['FILE-SYSTEM-ACCESS'] = fileSystemAccessTests; + import * as fileSystemAccessTests from './file-system-access-tests/file-system-access-tests'; + allTests['FILE-SYSTEM-ACCESS'] = fileSystemAccessTests; -import * as qualifierMatcherTests from './name-resolvers-tests/qualifier-matcher-tests'; -allTests['QUALIFIER-MATCHER'] = qualifierMatcherTests; + import * as qualifierMatcherTests from './name-resolvers-tests/qualifier-matcher-tests'; + allTests['QUALIFIER-MATCHER'] = qualifierMatcherTests; -import * as moduleNameResolverTests from './name-resolvers-tests/module-name-resolver-tests'; -allTests['MODULE-NAME-RESOLVER'] = moduleNameResolverTests; + import * as moduleNameResolverTests from './name-resolvers-tests/module-name-resolver-tests'; + allTests['MODULE-NAME-RESOLVER'] = moduleNameResolverTests; -import * as weakEventsTests from './ui/core/weak-event-listener/weak-event-listener-tests'; -allTests['WEAK-EVENTS'] = weakEventsTests; + import * as weakEventsTests from './ui/core/weak-event-listener/weak-event-listener-tests'; + allTests['WEAK-EVENTS'] = weakEventsTests; -import * as traceErrorTests from './trace/trace-error-tests'; -allTests['TRACE-ERROR'] = traceErrorTests; + import * as traceErrorTests from './trace/trace-error-tests'; + allTests['TRACE-ERROR'] = traceErrorTests; -import * as connectivityTests from './connectivity/connectivity-tests'; -allTests['CONNECTIVITY'] = connectivityTests; + import * as connectivityTests from './connectivity/connectivity-tests'; + allTests['CONNECTIVITY'] = connectivityTests; -import * as proxyViewContainerTests from './ui/proxy-view-container/proxy-view-container-tests'; -allTests['PROXY-VIEW-CONTAINER'] = proxyViewContainerTests; + import * as proxyViewContainerTests from './ui/proxy-view-container/proxy-view-container-tests'; + allTests['PROXY-VIEW-CONTAINER'] = proxyViewContainerTests; -import * as scrollViewTests from './ui/scroll-view/scroll-view-tests'; -allTests['SCROLL-VIEW'] = scrollViewTests; + import * as scrollViewTests from './ui/scroll-view/scroll-view-tests'; + allTests['SCROLL-VIEW'] = scrollViewTests; -import * as actionBarTests from './ui/action-bar/action-bar-tests'; -allTests['ACTION-BAR'] = actionBarTests; + import * as actionBarTests from './ui/action-bar/action-bar-tests'; + allTests['ACTION-BAR'] = actionBarTests; //TODO: 1 test commented out: test_EventInCodelessFragment -import * as xmlDeclarationTests from './xml-declaration/xml-declaration-tests'; -allTests['XML-DECLARATION'] = xmlDeclarationTests; + import * as xmlDeclarationTests from './xml-declaration/xml-declaration-tests'; + allTests['XML-DECLARATION'] = xmlDeclarationTests; -import * as dockLayoutTests from './ui/layouts/dock-layout-tests'; -allTests['DOCKLAYOUT'] = dockLayoutTests; + import * as dockLayoutTests from './ui/layouts/dock-layout-tests'; + allTests['DOCKLAYOUT'] = dockLayoutTests; -import * as wrapLayoutTests from './ui/layouts/wrap-layout-tests'; -allTests['WRAPLAYOUT'] = wrapLayoutTests; + import * as wrapLayoutTests from './ui/layouts/wrap-layout-tests'; + allTests['WRAPLAYOUT'] = wrapLayoutTests; -import * as absoluteLayoutTests from './ui/layouts/absolute-layout-tests'; -allTests['ABSOLUTELAYOUT'] = absoluteLayoutTests; + import * as absoluteLayoutTests from './ui/layouts/absolute-layout-tests'; + allTests['ABSOLUTELAYOUT'] = absoluteLayoutTests; -import * as gridLayoutTests from './ui/layouts/grid-layout-tests'; -allTests['GRIDLAYOUT'] = gridLayoutTests; + import * as gridLayoutTests from './ui/layouts/grid-layout-tests'; + allTests['GRIDLAYOUT'] = gridLayoutTests; -import * as stackLayoutTests from './ui/layouts/stack-layout-tests'; -allTests['STACKLAYOUT'] = stackLayoutTests; + import * as stackLayoutTests from './ui/layouts/stack-layout-tests'; + allTests['STACKLAYOUT'] = stackLayoutTests; -import * as flexBoxLayoutTests from './ui/layouts/flexbox-layout-tests'; -allTests['FLEXBOXLAYOUT'] = flexBoxLayoutTests; + import * as flexBoxLayoutTests from './ui/layouts/flexbox-layout-tests'; + allTests['FLEXBOXLAYOUT'] = flexBoxLayoutTests; -import * as safeAreaLayoutTests from './ui/layouts/safe-area-tests'; -import * as safeAreaListViewtTests from './ui/list-view/list-view-safe-area-tests'; -import * as scrollViewSafeAreaTests from './ui/scroll-view/scroll-view-safe-area-tests'; -import * as repeaterSafeAreaTests from './ui/repeater/repeater-safe-area-tests'; -import * as webViewSafeAreaTests from './ui/web-view/web-view-safe-area-tests'; + import * as safeAreaLayoutTests from './ui/layouts/safe-area-tests'; + import * as safeAreaListViewtTests from './ui/list-view/list-view-safe-area-tests'; + import * as scrollViewSafeAreaTests from './ui/scroll-view/scroll-view-safe-area-tests'; + import * as repeaterSafeAreaTests from './ui/repeater/repeater-safe-area-tests'; + import * as webViewSafeAreaTests from './ui/web-view/web-view-safe-area-tests'; -if (isIOS && Utils.ios.MajorVersion > 10) { - allTests['SAFEAREALAYOUT'] = safeAreaLayoutTests; - allTests['SAFEAREA-LISTVIEW'] = safeAreaListViewtTests; - allTests['SAFEAREA-SCROLL-VIEW'] = scrollViewSafeAreaTests; - allTests['SAFEAREA-REPEATER'] = repeaterSafeAreaTests; - allTests['SAFEAREA-WEBVIEW'] = webViewSafeAreaTests; -} + if (isIOS && Utils.ios.MajorVersion > 10) { + allTests['SAFEAREALAYOUT'] = safeAreaLayoutTests; + allTests['SAFEAREA-LISTVIEW'] = safeAreaListViewtTests; + allTests['SAFEAREA-SCROLL-VIEW'] = scrollViewSafeAreaTests; + allTests['SAFEAREA-REPEATER'] = repeaterSafeAreaTests; + allTests['SAFEAREA-WEBVIEW'] = webViewSafeAreaTests; + } -import * as rootViewsCssClassesTests from './ui/styling/root-views-css-classes-tests'; -allTests['ROOT-VIEWS-CSS-CLASSES'] = rootViewsCssClassesTests; + import * as rootViewsCssClassesTests from './ui/styling/root-views-css-classes-tests'; + allTests['ROOT-VIEWS-CSS-CLASSES'] = rootViewsCssClassesTests; -import * as stylePropertiesTests from './ui/styling/style-properties-tests'; -allTests['STYLE-PROPERTIES'] = stylePropertiesTests; + import * as stylePropertiesTests from './ui/styling/style-properties-tests'; + allTests['STYLE-PROPERTIES'] = stylePropertiesTests; -import * as frameTests from './ui/frame/frame-tests'; -allTests['FRAME'] = frameTests; + import * as frameTests from './ui/frame/frame-tests'; + allTests['FRAME'] = frameTests; -import * as viewTests from './ui/view/view-tests'; -allTests['VIEW'] = viewTests; + import * as viewTests from './ui/view/view-tests'; + allTests['VIEW'] = viewTests; -import * as viewLayoutChangedEventTests from './ui/view/view-tests-layout-event'; -allTests['VIEW-LAYOUT-EVENT'] = viewLayoutChangedEventTests; + import * as viewLayoutChangedEventTests from './ui/view/view-tests-layout-event'; + allTests['VIEW-LAYOUT-EVENT'] = viewLayoutChangedEventTests; -import * as styleTests from './ui/styling/style-tests'; -allTests['STYLE'] = styleTests; + import * as styleTests from './ui/styling/style-tests'; + allTests['STYLE'] = styleTests; -import * as visualStateTests from './ui/styling/visual-state-tests'; -allTests['VISUAL-STATE'] = visualStateTests; + import * as visualStateTests from './ui/styling/visual-state-tests'; + allTests['VISUAL-STATE'] = visualStateTests; -import * as valueSourceTests from './ui/styling/value-source-tests'; -allTests['VALUE-SOURCE'] = valueSourceTests; + import * as valueSourceTests from './ui/styling/value-source-tests'; + allTests['VALUE-SOURCE'] = valueSourceTests; -import * as builderTests from './ui/builder/builder-tests'; -allTests['BUILDER'] = builderTests; + import * as builderTests from './ui/builder/builder-tests'; + allTests['BUILDER'] = builderTests; -import * as builderFileQualifierTests from './ui/builder/builder-file-qualifiers-tests'; -allTests['BUILDER-QUALIFIERS'] = builderFileQualifierTests; + import * as builderFileQualifierTests from './ui/builder/builder-file-qualifiers-tests'; + allTests['BUILDER-QUALIFIERS'] = builderFileQualifierTests; -import * as buttonTests from './ui/button/button-tests'; -allTests['BUTTON'] = buttonTests; + import * as buttonTests from './ui/button/button-tests'; + allTests['BUTTON'] = buttonTests; -import * as labelTests from './ui/label/label-tests'; -allTests['LABEL'] = labelTests; + import * as labelTests from './ui/label/label-tests'; + allTests['LABEL'] = labelTests; -import * as bottomNavigationTests from './ui/bottom-navigation/bottom-navigation-tests'; -allTests['BOTTOM-NAVIGATION'] = bottomNavigationTests; + import * as bottomNavigationTests from './ui/bottom-navigation/bottom-navigation-tests'; + allTests['BOTTOM-NAVIGATION'] = bottomNavigationTests; -import * as bottomNavigationTestsNew from './ui/bottom-navigation/bottom-navigation-tests-new'; -allTests['BOTTOM-NAVIGATION-NEW'] = bottomNavigationTestsNew; + import * as bottomNavigationTestsNew from './ui/bottom-navigation/bottom-navigation-tests-new'; + allTests['BOTTOM-NAVIGATION-NEW'] = bottomNavigationTestsNew; -import * as bottomNavigationNavigationTests from './ui/bottom-navigation/bottom-navigation-navigation-tests'; + import * as bottomNavigationNavigationTests from './ui/bottom-navigation/bottom-navigation-navigation-tests'; // TODO: uncomment this // allTests["BOTTOM-NAVIGATION-NAVIGATION"] = bottomNavigationNavigationTests; -import * as tabsTests from './ui/tabs/tabs-tests'; -allTests['TABS'] = tabsTests; + import * as tabsTests from './ui/tabs/tabs-tests'; + allTests['TABS'] = tabsTests; -import * as tabsTestsNew from './ui/tabs/tabs-tests-new'; -allTests['TABS-NEW'] = tabsTestsNew; + import * as tabsTestsNew from './ui/tabs/tabs-tests-new'; + allTests['TABS-NEW'] = tabsTestsNew; -import * as tabsNavigationTests from './ui/tabs/tabs-navigation-tests'; -allTests['TABS-NAVIGATION'] = tabsNavigationTests; + import * as tabsNavigationTests from './ui/tabs/tabs-navigation-tests'; + allTests['TABS-NAVIGATION'] = tabsNavigationTests; -import * as tabViewTests from './ui/tab-view/tab-view-tests'; -allTests['TAB-VIEW'] = tabViewTests; + import * as tabViewTests from './ui/tab-view/tab-view-tests'; + allTests['TAB-VIEW'] = tabViewTests; -import * as tabViewTestsNew from './ui/tab-view/tab-view-tests-new'; -allTests['TAB-VIEW-NEW'] = tabViewTestsNew; + import * as tabViewTestsNew from './ui/tab-view/tab-view-tests-new'; + allTests['TAB-VIEW-NEW'] = tabViewTestsNew; -import * as tabViewNavigationTests from './ui/tab-view/tab-view-navigation-tests'; -allTests['TAB-VIEW-NAVIGATION'] = tabViewNavigationTests; + import * as tabViewNavigationTests from './ui/tab-view/tab-view-navigation-tests'; + allTests['TAB-VIEW-NAVIGATION'] = tabViewNavigationTests; -import * as imageTests from './ui/image/image-tests'; -allTests['IMAGE'] = imageTests; + import * as imageTests from './ui/image/image-tests'; + allTests['IMAGE'] = imageTests; -import * as imageCacheTests from './ui/image-cache/image-cache-tests'; -allTests['IMAGE-CACHE'] = imageCacheTests; + import * as imageCacheTests from './ui/image-cache/image-cache-tests'; + allTests['IMAGE-CACHE'] = imageCacheTests; -import * as sliderTests from './ui/slider/slider-tests'; -allTests['SLIDER'] = sliderTests; + import * as sliderTests from './ui/slider/slider-tests'; + allTests['SLIDER'] = sliderTests; -import * as switchTests from './ui/switch/switch-tests'; -allTests['SWITCH'] = switchTests; + import * as switchTests from './ui/switch/switch-tests'; + allTests['SWITCH'] = switchTests; -import * as progressTests from './ui/progress/progress-tests'; -allTests['PROGRESS'] = progressTests; + import * as progressTests from './ui/progress/progress-tests'; + allTests['PROGRESS'] = progressTests; -import * as placeholderTests from './ui/placeholder/placeholder-tests'; -allTests['PLACEHOLDER'] = placeholderTests; + import * as placeholderTests from './ui/placeholder/placeholder-tests'; + allTests['PLACEHOLDER'] = placeholderTests; -import * as pageTests from './ui/page/page-tests'; -allTests['PAGE'] = pageTests; + import * as pageTests from './ui/page/page-tests'; + allTests['PAGE'] = pageTests; -import * as listViewTests from './ui/list-view/list-view-tests'; -allTests['LISTVIEW'] = listViewTests; + import * as listViewTests from './ui/list-view/list-view-tests'; + allTests['LISTVIEW'] = listViewTests; -import * as activityIndicatorTests from './ui/activity-indicator/activity-indicator-tests'; -allTests['ACTIVITY-INDICATOR'] = activityIndicatorTests; + import * as activityIndicatorTests from './ui/activity-indicator/activity-indicator-tests'; + allTests['ACTIVITY-INDICATOR'] = activityIndicatorTests; -import * as textFieldTests from './ui/text-field/text-field-tests'; -allTests['TEXT-FIELD'] = textFieldTests; + import * as textFieldTests from './ui/text-field/text-field-tests'; + allTests['TEXT-FIELD'] = textFieldTests; -import * as textViewTests from './ui/text-view/text-view-tests'; -allTests['TEXT-VIEW'] = textViewTests; + import * as textViewTests from './ui/text-view/text-view-tests'; + allTests['TEXT-VIEW'] = textViewTests; -import * as listPickerTests from './ui/list-picker/list-picker-tests'; -allTests['LIST-PICKER'] = listPickerTests; + import * as listPickerTests from './ui/list-picker/list-picker-tests'; + allTests['LIST-PICKER'] = listPickerTests; -import * as datePickerTests from './ui/date-picker/date-picker-tests'; -allTests['DATE-PICKER'] = datePickerTests; + import * as datePickerTests from './ui/date-picker/date-picker-tests'; + allTests['DATE-PICKER'] = datePickerTests; -import * as timePickerTests from './ui/time-picker/time-picker-tests'; -allTests['TIME-PICKER'] = timePickerTests; + import * as timePickerTests from './ui/time-picker/time-picker-tests'; + allTests['TIME-PICKER'] = timePickerTests; -import * as webViewTests from './ui/web-view/web-view-tests'; -allTests['WEB-VIEW'] = webViewTests; + import * as webViewTests from './ui/web-view/web-view-tests'; + allTests['WEB-VIEW'] = webViewTests; -import * as htmlViewTests from './ui/html-view/html-view-tests'; -allTests['HTML-VIEW'] = htmlViewTests; + import * as htmlViewTests from './ui/html-view/html-view-tests'; + allTests['HTML-VIEW'] = htmlViewTests; -import * as repeaterTests from './ui/repeater/repeater-tests'; -allTests['REPEATER'] = repeaterTests; + import * as repeaterTests from './ui/repeater/repeater-tests'; + allTests['REPEATER'] = repeaterTests; -import * as segmentedBarTests from './ui/segmented-bar/segmented-bar-tests'; -allTests['SEGMENTED-BAR'] = segmentedBarTests; + import * as segmentedBarTests from './ui/segmented-bar/segmented-bar-tests'; + allTests['SEGMENTED-BAR'] = segmentedBarTests; -import * as animationTests from './ui/animation/animation-tests'; -allTests['ANIMATION'] = animationTests; + import * as animationTests from './ui/animation/animation-tests'; + allTests['ANIMATION'] = animationTests; -import * as lifecycle from './ui/lifecycle/lifecycle-tests'; -allTests['LIFECYCLE'] = lifecycle; + import * as lifecycle from './ui/lifecycle/lifecycle-tests'; + allTests['LIFECYCLE'] = lifecycle; -import * as cssAnimationTests from './ui/animation/css-animation-tests'; -allTests['CSS-ANIMATION'] = cssAnimationTests; + import * as cssAnimationTests from './ui/animation/css-animation-tests'; + allTests['CSS-ANIMATION'] = cssAnimationTests; -import * as transitionTests from './navigation/transition-tests'; -allTests['TRANSITIONS'] = transitionTests; + import * as transitionTests from './navigation/transition-tests'; + allTests['TRANSITIONS'] = transitionTests; -import * as searchBarTests from './ui/search-bar/search-bar-tests'; -allTests['SEARCH-BAR'] = searchBarTests; + import * as searchBarTests from './ui/search-bar/search-bar-tests'; + allTests['SEARCH-BAR'] = searchBarTests; -import * as navigationTests from './navigation/navigation-tests'; -allTests['NAVIGATION'] = navigationTests; + import * as navigationTests from './navigation/navigation-tests'; + allTests['NAVIGATION'] = navigationTests; -import * as livesyncTests from './livesync/livesync-tests'; -allTests['LIVESYNC'] = livesyncTests; + import * as livesyncTests from './livesync/livesync-tests'; + allTests['LIVESYNC'] = livesyncTests; -import * as tabViewRootTests from './ui/tab-view/tab-view-root-tests'; -allTests['TAB-VIEW-ROOT'] = tabViewRootTests; + import * as tabViewRootTests from './ui/tab-view/tab-view-root-tests'; + allTests['TAB-VIEW-ROOT'] = tabViewRootTests; -import * as bottomNavigationRootTests from './ui/bottom-navigation/bottom-navigation-root-tests'; -allTests['BOTTOM-NAVIGATION-ROOT'] = bottomNavigationRootTests; + import * as bottomNavigationRootTests from './ui/bottom-navigation/bottom-navigation-root-tests'; + allTests['BOTTOM-NAVIGATION-ROOT'] = bottomNavigationRootTests; // Reset root view didn't work with android tabs // import * as tabsRootTests from "./ui/tabs/tabs-root-tests"; // allTests["TABS-ROOT"] = tabsRootTests; -import * as resetRootViewTests from './ui/root-view/reset-root-view-tests'; -allTests['RESET-ROOT-VIEW'] = resetRootViewTests; + import * as resetRootViewTests from './ui/root-view/reset-root-view-tests'; + allTests['RESET-ROOT-VIEW'] = resetRootViewTests; -import * as rootViewTests from './ui/root-view/root-view-tests'; -allTests['ROOT-VIEW'] = rootViewTests; + import * as rootViewTests from './ui/root-view/root-view-tests'; + allTests['ROOT-VIEW'] = rootViewTests; + + import * as utilsTests from './utils/utils-tests'; + allTests['UTILS'] = utilsTests; + + if (singleTest != null) { + const tempTest = allTests[singleTest]; + allTests = {}; + if (tempTest) { + allTests[singleTest] = tempTest; + } else { + console.log("Test does not exist", singleTest); + } + } -import * as utilsTests from './utils/utils-tests'; -allTests['UTILS'] = utilsTests; const testsSuitesWithLongDelay = { HTTP: 15 * 1000, diff --git a/packages/core/data/observable/index.ts b/packages/core/data/observable/index.ts index 8fcd4735a..fcd38e9f3 100644 --- a/packages/core/data/observable/index.ts +++ b/packages/core/data/observable/index.ts @@ -22,11 +22,11 @@ let _wrappedIndex = 0; export class WrappedValue implements WrappedValueDefinition { constructor(public wrapped: any) {} - public static unwrap(value: any) { + public static unwrap(value: any): any { return value instanceof WrappedValue ? value.wrapped : value; } - public static wrap(value: any) { + public static wrap(value: any): any { const w = _wrappedValues[_wrappedIndex++ % 5]; w.wrapped = value; @@ -34,7 +34,11 @@ export class WrappedValue implements WrappedValueDefinition { } } -let _wrappedValues = [new WrappedValue(null), new WrappedValue(null), new WrappedValue(null), new WrappedValue(null), new WrappedValue(null)]; +const _wrappedValues = [new WrappedValue(null), new WrappedValue(null), new WrappedValue(null), new WrappedValue(null), new WrappedValue(null)]; + + +const _globalEventHandlers = {}; + export class Observable implements ObservableDefinition { public static propertyChangeEvent = 'propertyChange'; @@ -46,7 +50,7 @@ export class Observable implements ObservableDefinition { return this[name]; } - public set(name: string, value: any) { + public set(name: string, value: any): void { // TODO: Parameter validation const oldValue = this[name]; if (this[name] === value) { @@ -58,7 +62,7 @@ export class Observable implements ObservableDefinition { this.notifyPropertyChange(name, newValue, oldValue); } - public setProperty(name: string, value: any) { + public setProperty(name: string, value: any): void { const oldValue = this[name]; if (this[name] === value) { return; @@ -74,20 +78,28 @@ export class Observable implements ObservableDefinition { } } - public on(eventNames: string, callback: (data: EventData) => void, thisArg?: any) { + public on(eventNames: string, callback: (data: EventData) => void, thisArg?: any): void { this.addEventListener(eventNames, callback, thisArg); } - public once(event: string, callback: (data: EventData) => void, thisArg?: any) { + public once(event: string, callback: (data: EventData) => void, thisArg?: any): void { + if (typeof event !== 'string') { + throw new TypeError('Event must be string.'); + } + + if (typeof callback !== 'function') { + throw new TypeError('callback must be function.'); + } + const list = this._getEventList(event, true); list.push({ callback, thisArg, once: true }); } - public off(eventNames: string, callback?: any, thisArg?: any) { + public off(eventNames: string, callback?: any, thisArg?: any): void { this.removeEventListener(eventNames, callback, thisArg); } - public addEventListener(eventNames: string, callback: (data: EventData) => void, thisArg?: Object) { + public addEventListener(eventNames: string, callback: (data: EventData) => void, thisArg?: any): void { if (typeof eventNames !== 'string') { throw new TypeError('Events name(s) must be string.'); } @@ -108,7 +120,7 @@ export class Observable implements ObservableDefinition { } } - public removeEventListener(eventNames: string, callback?: any, thisArg?: Object) { + public removeEventListener(eventNames: string, callback?: any, thisArg?: any): void { if (typeof eventNames !== 'string') { throw new TypeError('Events name(s) must be string.'); } @@ -123,7 +135,7 @@ export class Observable implements ObservableDefinition { if (callback) { const list = this._getEventList(event, false); if (list) { - const index = this._indexOfListener(list, callback, thisArg); + const index = Observable._indexOfListener(list, callback, thisArg); if (index >= 0) { list.splice(index, 1); } @@ -138,14 +150,126 @@ export class Observable implements ObservableDefinition { } } - public notify(data: T) { - const observers = >this._observers[data.eventName]; - if (!observers) { - return; + public static on(eventName: string, callback: any, thisArg?: any): void { + this.addEventListener(eventName, callback, thisArg); + } + + public static once(eventName: string, callback: any, thisArg?: any): void { + if (typeof eventName !== 'string') { + throw new TypeError('Event must be string.'); } + if (typeof callback !== 'function') { + throw new TypeError('callback must be function.'); + } + + const eventClass = this.name; + if (!_globalEventHandlers[eventClass]) { + _globalEventHandlers[eventClass] = {}; + } + if (!Array.isArray(_globalEventHandlers[eventClass][eventName])) { + _globalEventHandlers[eventClass][eventName] = []; + } + _globalEventHandlers[eventClass][eventName].push({callback, thisArg, once: true}); + } + + public static off(eventName: string, callback?: any, thisArg?: any): void { + this.removeEventListener(eventName, callback, thisArg); + } + + public static removeEventListener(eventName: string, callback?: any, thisArg?: any): void { + if (typeof eventName !== 'string') { + throw new TypeError('Event must be string.'); + } + + if (callback && typeof callback !== 'function') { + throw new TypeError('callback must be function.'); + } + + const eventClass = this.name; + + // Short Circuit if no handlers exist.. + if (!_globalEventHandlers[eventClass] || !Array.isArray(_globalEventHandlers[eventClass][eventName])) { return; } + + const events = _globalEventHandlers[eventClass][eventName]; + if (thisArg) { + for (let i = 0; i < events.length; i++) { + if (events[i].callback === callback && events[i].thisArg === thisArg) { + events.splice(i, 1); + i--; + } + } + } else if (callback) { + for (let i = 0; i < events.length; i++) { + if (events[i].callback === callback) { + events.splice(i, 1); + i--; + } + } + } else { + // Clear all events of this type + delete _globalEventHandlers[eventClass][eventName]; + } + + if (events.length === 0) { + // Clear all events of this type + delete _globalEventHandlers[eventClass][eventName]; + } + + // Clear the primary class grouping if no events are left + const keys = Object.keys(_globalEventHandlers[eventClass]); + if (keys.length === 0) { + delete _globalEventHandlers[eventClass]; + } + + } + + public static addEventListener(eventName: string, callback: any, thisArg?: any): void { + if (typeof eventName !== 'string') { + throw new TypeError('Event must be string.'); + } + + if (typeof callback !== 'function') { + throw new TypeError('callback must be function.'); + } + + const eventClass = this.name; + if (!_globalEventHandlers[eventClass]) { + _globalEventHandlers[eventClass] = {}; + } + if (!Array.isArray(_globalEventHandlers[eventClass][eventName])) { + _globalEventHandlers[eventClass][eventName] = []; + } + _globalEventHandlers[eventClass][eventName].push({callback, thisArg}); + } + + public notify(data: T): void { + const eventClass = this.constructor.name; + if (_globalEventHandlers[eventClass]) { + const event = data.eventName + "First"; + const events = _globalEventHandlers[eventClass][event]; + if (events) { + Observable._handleEvent(events, data); + } + } + + const observers = >this._observers[data.eventName]; + if (observers) { + Observable._handleEvent(observers, data); + } + + if (_globalEventHandlers[eventClass]) { + const events = _globalEventHandlers[eventClass][data.eventName]; + if (events) { + Observable._handleEvent(events, data); + } + } + } + + private static _handleEvent(observers: Array, data: T): void { + if (!observers) { return; } for (let i = observers.length - 1; i >= 0; i--) { - let entry = observers[i]; + const entry = observers[i]; if (entry.once) { observers.splice(i, 1); } @@ -198,7 +322,7 @@ export class Observable implements ObservableDefinition { return list; } - private _indexOfListener(list: Array, callback: (data: EventData) => void, thisArg?: any): number { + private static _indexOfListener(list: Array, callback: (data: EventData) => void, thisArg?: any): number { for (let i = 0; i < list.length; i++) { const entry = list[i]; if (thisArg) { @@ -248,7 +372,7 @@ function defineNewProperty(target: ObservableFromObject, propertyName: string): }); } -function addPropertiesFromObject(observable: ObservableFromObject, source: any, recursive: boolean = false) { +function addPropertiesFromObject(observable: ObservableFromObject, source: any, recursive = false) { Object.keys(source).forEach((prop) => { let value = source[prop]; if (recursive && !Array.isArray(value) && value && typeof value === 'object' && !(value instanceof Observable)) { @@ -261,14 +385,14 @@ function addPropertiesFromObject(observable: ObservableFromObject, source: any, } export function fromObject(source: any): Observable { - let observable = new ObservableFromObject(); + const observable = new ObservableFromObject(); addPropertiesFromObject(observable, source, false); return observable; } export function fromObjectRecursive(source: any): Observable { - let observable = new ObservableFromObject(); + const observable = new ObservableFromObject(); addPropertiesFromObject(observable, source, true); return observable; diff --git a/packages/core/ui/bottom-navigation/index.android.ts b/packages/core/ui/bottom-navigation/index.android.ts index 049a43d94..5a2fefd91 100644 --- a/packages/core/ui/bottom-navigation/index.android.ts +++ b/packages/core/ui/bottom-navigation/index.android.ts @@ -455,8 +455,9 @@ export class BottomNavigation extends TabNavigationBase { private disposeTabFragments(): void { const fragmentManager = this._getFragmentManager(); const transaction = fragmentManager.beginTransaction(); - for (let fragment of >fragmentManager.getFragments().toArray()) { - transaction.remove(fragment); + const fragments = fragmentManager.getFragments().toArray(); + for (let i=0;i; public static initWithOwner(owner: WeakRef): UITabBarControllerImpl { - let handler = UITabBarControllerImpl.new(); + const handler = UITabBarControllerImpl.new(); handler._owner = owner; return handler; @@ -102,7 +107,7 @@ class UITabBarControllerDelegateImpl extends NSObject implements UITabBarControl private _owner: WeakRef; public static initWithOwner(owner: WeakRef): UITabBarControllerDelegateImpl { - let delegate = UITabBarControllerDelegateImpl.new(); + const delegate = UITabBarControllerDelegateImpl.new(); delegate._owner = owner; return delegate; @@ -114,10 +119,10 @@ class UITabBarControllerDelegateImpl extends NSObject implements UITabBarControl // Trace.write("TabView.delegate.SHOULD_select(" + tabBarController + ", " + viewController + ");", Trace.categories.Debug); // } - let owner = this._owner.get(); + const owner = this._owner.get(); if (owner) { // "< More" cannot be visible after clicking on the main tab bar buttons. - let backToMoreWillBeVisible = false; + const backToMoreWillBeVisible = false; owner._handleTwoNavigationBars(backToMoreWillBeVisible); if (tabBarController.viewControllers) { @@ -169,7 +174,7 @@ class UINavigationControllerDelegateImpl extends NSObject implements UINavigatio private _owner: WeakRef; public static initWithOwner(owner: WeakRef): UINavigationControllerDelegateImpl { - let delegate = UINavigationControllerDelegateImpl.new(); + const delegate = UINavigationControllerDelegateImpl.new(); delegate._owner = owner; return delegate; @@ -181,11 +186,11 @@ class UINavigationControllerDelegateImpl extends NSObject implements UINavigatio // Trace.write("TabView.moreNavigationController.WILL_show(" + navigationController + ", " + viewController + ", " + animated + ");", Trace.categories.Debug); // } - let owner = this._owner.get(); + const owner = this._owner.get(); if (owner) { // If viewController is one of our tab item controllers, then "< More" will be visible shortly. // Otherwise viewController is the UIMoreListController which shows the list of all tabs beyond the 4th tab. - let backToMoreWillBeVisible = owner._ios.viewControllers.containsObject(viewController); + const backToMoreWillBeVisible = owner._ios.viewControllers.containsObject(viewController); owner._handleTwoNavigationBars(backToMoreWillBeVisible); } } @@ -197,7 +202,7 @@ class UINavigationControllerDelegateImpl extends NSObject implements UINavigatio // } // We don't need Edit button in More screen. navigationController.navigationBar.topItem.rightBarButtonItem = null; - let owner = this._owner.get(); + const owner = this._owner.get(); if (owner) { owner._onViewControllerShown(viewController); } @@ -425,8 +430,7 @@ export class BottomNavigation extends TabNavigationBase { } public setTabBarItemTextTransform(tabStripItem: TabStripItem, value: TextTransform): void { - const title = getTransformedText(tabStripItem.label.text, value); - tabStripItem.nativeView.title = title; + tabStripItem.nativeView.title = getTransformedText(tabStripItem.label.text, value); } public getTabBarHighlightColor(): UIColor { @@ -434,8 +438,7 @@ export class BottomNavigation extends TabNavigationBase { } public setTabBarHighlightColor(value: UIColor | Color) { - const nativeColor = value instanceof Color ? value.ios : value; - this._ios.tabBar.tintColor = nativeColor; + this._ios.tabBar.tintColor = value instanceof Color ? value.ios : value; } public getTabBarSelectedItemColor(): Color { @@ -498,7 +501,7 @@ export class BottomNavigation extends TabNavigationBase { return; } - let actionBarVisible = page.frame._getNavBarVisible(page); + const actionBarVisible = page.frame._getNavBarVisible(page); if (backToMoreWillBeVisible && actionBarVisible) { page.frame.ios._disableNavBarAnimation = true; @@ -641,9 +644,7 @@ export class BottomNavigation extends TabNavigationBase { } } - const tabBarItem = UITabBarItem.alloc().initWithTitleImageTag(title, image, index); - - return tabBarItem; + return UITabBarItem.alloc().initWithTitleImageTag(title, image, index); } private getIconRenderingMode(): UIImageRenderingMode { @@ -676,7 +677,7 @@ export class BottomNavigation extends TabNavigationBase { let isFontIcon = false; let image: UIImage = this._iconsCache[iconTag]; if (!image) { - let is = new ImageSource(); + let is; if (isFontIconURI(iconSource)) { isFontIcon = true; const fontIconCode = iconSource.split('//')[1]; @@ -722,7 +723,7 @@ export class BottomNavigation extends TabNavigationBase { UIGraphicsBeginImageContextWithOptions({ width: widthPts, height: heightPts }, false, layout.getDisplayDensity()); image.drawInRect(CGRectMake(0, 0, widthPts, heightPts)); - let resultImage = UIGraphicsGetImageFromCurrentImageContext(); + const resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return resultImage; @@ -748,7 +749,7 @@ export class BottomNavigation extends TabNavigationBase { // this._updateIOSTabBarColorsAndFonts(); // } - [selectedIndexProperty.setNative](value: number) { + [selectedIndexProperty.setNative](value: number): void { // TODO // if (Trace.isEnabled()) { // Trace.write("TabView._onSelectedIndexPropertyChangedSetNativeValue(" + value + ")", Trace.categories.Debug); @@ -763,7 +764,7 @@ export class BottomNavigation extends TabNavigationBase { [itemsProperty.getDefault](): TabContentItem[] { return null; } - [itemsProperty.setNative](value: TabContentItem[]) { + [itemsProperty.setNative](value: TabContentItem[]): void { if (value) { value.forEach((item: TabContentItem, i) => { (item).index = i; @@ -778,7 +779,7 @@ export class BottomNavigation extends TabNavigationBase { return null; } - [tabStripProperty.setNative](value: TabStrip) { + [tabStripProperty.setNative](value: TabStrip): void { this.setViewControllers(this.items); selectedIndexProperty.coerce(this); } @@ -793,7 +794,7 @@ export class BottomNavigation extends TabNavigationBase { const font: UIFont = (view.style.fontInternal || Font.default).getUIFont(UIFont.systemFontOfSize(tabItemFontSize)); const tabItemTextColor = view.style.color; const textColor = tabItemTextColor instanceof Color ? tabItemTextColor.ios : null; - let attributes: any = { [NSFontAttributeName]: font }; + const attributes: any = { [NSFontAttributeName]: font }; // if selectedItemColor or unSelectedItemColor is set we don't respect the color from the style if (!this._selectedItemColor && !this._unSelectedItemColor) { diff --git a/packages/core/ui/core/view-base/index.ts b/packages/core/ui/core/view-base/index.ts index dd7e6031a..7b4714b54 100644 --- a/packages/core/ui/core/view-base/index.ts +++ b/packages/core/ui/core/view-base/index.ts @@ -214,6 +214,7 @@ namespace SuspendType { export abstract class ViewBase extends Observable implements ViewBaseDefinition { public static loadedEvent = 'loaded'; public static unloadedEvent = 'unloaded'; + public static createdEvent = 'created'; private _onLoadedCalled: boolean = false; private _onUnloadedCalled: boolean = false; @@ -304,6 +305,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition super(); this._domId = viewIdCounter++; this._style = new Style(new WeakRef(this)); + this.notify({eventName: ViewBase.createdEvent, type: this.constructor.name, object: this}); } // Used in Angular. @@ -378,7 +380,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition } } - // Overridden so we don't raise `poropertyChange` + // Overridden so we don't raise `propertyChange` // The property will raise its own event. public set(name: string, value: any) { this[name] = WrappedValue.unwrap(value); diff --git a/packages/core/ui/frame/frame-common.ts b/packages/core/ui/frame/frame-common.ts index f8b98e87e..e89038db2 100644 --- a/packages/core/ui/frame/frame-common.ts +++ b/packages/core/ui/frame/frame-common.ts @@ -296,6 +296,10 @@ export class FrameBase extends CustomLayoutView { private raiseCurrentPageNavigatedEvents(isBack: boolean) { const page = this.currentPage; if (page) { + if (page.isLoaded) { + // Forward navigation does not remove page from frame so we raise unloaded manually. + page.callUnloaded(); + } page.onNavigatedFrom(isBack); } } diff --git a/packages/core/ui/frame/index.android.ts b/packages/core/ui/frame/index.android.ts index 7a1220aab..91cd68408 100644 --- a/packages/core/ui/frame/index.android.ts +++ b/packages/core/ui/frame/index.android.ts @@ -436,7 +436,7 @@ export class Frame extends FrameBase { //transaction.setTransition(androidx.fragment.app.FragmentTransaction.TRANSIT_FRAGMENT_OPEN); } - transaction.add(this.containerViewId, newFragment, newFragmentTag); + transaction.replace(this.containerViewId, newFragment, newFragmentTag); transaction.commitAllowingStateLoss(); } @@ -458,29 +458,8 @@ export class Frame extends FrameBase { _reverseTransitions(backstackEntry, this._currentEntry); - const currentIndex = this.backStack.length; - const gotBackToIndex = this.backStack.indexOf(backstackEntry); + transaction.replace(this.containerViewId, backstackEntry.fragment, backstackEntry.fragmentTag); - for (let index = gotBackToIndex + 1; index < currentIndex; index++) { - transaction.remove(this.backStack[index].fragment); - } - if (this._currentEntry !== backstackEntry) { - // if we are going back we need to store where we are backing to - // so that we can set the current entry - if ((this._currentEntry as any).exitTransitionListener) { - (this._currentEntry as any).exitTransitionListener.backEntry = backstackEntry; - } - if ((this._currentEntry as any).returnTransitionListener) { - (this._currentEntry as any).returnTransitionListener.backEntry = backstackEntry; - } - if ((this._currentEntry as any).enterTransitionListener) { - (this._currentEntry as any).enterTransitionListener.backEntry = backstackEntry; - } - if ((this._currentEntry as any).reenterTransitionListener) { - (this._currentEntry as any).reenterTransitionListener.backEntry = backstackEntry; - } - transaction.remove(this._currentEntry.fragment); - } transaction.commitAllowingStateLoss(); } diff --git a/packages/core/ui/tab-navigation-base/tab-content-item/index.android.ts b/packages/core/ui/tab-navigation-base/tab-content-item/index.android.ts index a3f71f58f..3889a182a 100644 --- a/packages/core/ui/tab-navigation-base/tab-content-item/index.android.ts +++ b/packages/core/ui/tab-navigation-base/tab-content-item/index.android.ts @@ -53,9 +53,10 @@ export class TabContentItem extends TabContentItemBase { Trace.write(`Current TabContentItem index is not set`, traceCategory, Trace.messageType.error); } - for (let fragment of >fragmentManager.getFragments().toArray()) { - if (fragment.index === this.index) { - tabFragment = fragment; + const fragments = fragmentManager.getFragments().toArray(); + for (let i=0;i -1 ? this.items[selectedIndex].content : null; } @@ -296,9 +296,9 @@ export const selectedIndexProperty = new CoercibleProperty { - let items = target.items; + const items = target.items; if (items) { - let max = items.length - 1; + const max = items.length - 1; if (value < 0) { value = 0; } diff --git a/packages/core/ui/tab-view/index.android.ts b/packages/core/ui/tab-view/index.android.ts index a50a7a496..0bc295fae 100644 --- a/packages/core/ui/tab-view/index.android.ts +++ b/packages/core/ui/tab-view/index.android.ts @@ -365,9 +365,10 @@ export class TabViewItem extends TabViewItemBase { const tabView = this.parent as TabView; let tabFragment = null; const fragmentManager = tabView._getFragmentManager(); - for (let fragment of >fragmentManager.getFragments().toArray()) { - if (fragment.index === this.index) { - tabFragment = fragment; + const fragments = fragmentManager.getFragments().toArray(); + for (let i=0;i>fragmentManager.getFragments().toArray()) { - transaction.remove(fragment); + let fragments = >fragmentManager.getFragments().toArray(); + for (let i=0;i>fragmentManager.getFragments().toArray()) { - transaction.remove(fragment); + let fragments = >fragmentManager.getFragments().toArray(); + for (let i=0;i(); -const funcNameRegex = /function ([_a-zA-Z0-9]{1,})\(/; + +// ES3-5 type classes are "function blah()", new ES6+ classes can be "class blah" +const funcNameRegex = /(?:function|class)\s+(\w+).*/; export function getClass(object: Object): string { return getClassInfo(object).name; } @@ -74,18 +76,22 @@ export function getBaseClasses(object): Array { } export class ClassInfo { - private _typeCosntructor: Function; + private _typeConstructor: Function; private _name: string; private _baseClassInfo: ClassInfo; - constructor(typeCosntructor: Function) { - this._typeCosntructor = typeCosntructor; + constructor(typeConstructor: Function) { + this._typeConstructor = typeConstructor; } get name(): string { if (!this._name) { - const results = funcNameRegex.exec(this._typeCosntructor.toString()); - this._name = results && results.length > 1 ? results[1] : ''; + if (this._typeConstructor.name) { + this._name = this._typeConstructor.name; + } else { + const results = funcNameRegex.exec(this._typeConstructor.toString()); + this._name = results && results.length > 1 ? results[1] : ''; + } } return this._name; @@ -106,7 +112,7 @@ export class ClassInfo { private static _getBase(info: ClassInfo): ClassInfo { let result = null; - const constructorProto = info._typeCosntructor.prototype; + const constructorProto = info._typeConstructor.prototype; if (constructorProto.__proto__) { result = getClassInfo(constructorProto.__proto__); }