test: add reset root view tests (#5437)

This commit is contained in:
Martin Yankov
2018-02-21 11:38:37 +02:00
committed by GitHub
parent c7dd02c22e
commit 4ce45666a5
9 changed files with 198 additions and 19 deletions

View File

@@ -0,0 +1,141 @@
import * as TKUnit from "../TKUnit";
import { Page } from "tns-core-modules/ui/page";
import { Frame, NavigationEntry, stack } from "tns-core-modules/ui/frame";
import { _resetRootView, getRootView } from "tns-core-modules/application";
import { TabView, TabViewItem } from "tns-core-modules/ui/tab-view";
function createTestFrameRootEntry() {
const page = new Page();
const frameRoot = new Frame();
frameRoot.navigate(() => page);
const entry: NavigationEntry = {
create: () => frameRoot
};
return {
entry: entry,
root: frameRoot,
page: page
};
}
function createTestTabRootEntry() {
const testFrameRoot1 = createTestFrameRootEntry();
const testFrameRoot2 = createTestFrameRootEntry();
const tabView = new TabView();
const tabEntry1 = new TabViewItem();
tabEntry1.title = "frameRoot1";
tabEntry1.view = testFrameRoot1.root;
const tabEntry2 = new TabViewItem();
tabEntry2.title = "frameRoot2";
tabEntry2.view = testFrameRoot2.root;
tabView.items = [tabEntry1, tabEntry2];
const entry: NavigationEntry = {
create: () => tabView
};
return {
entry: entry,
root: tabView,
page: testFrameRoot1.page
};
}
export function test_reset_frame_to_frame() {
const testFrameRoot1 = createTestFrameRootEntry();
_resetRootView(testFrameRoot1.entry);
TKUnit.waitUntilReady(() => testFrameRoot1.page.isLoaded);
const rootView1 = getRootView();
const frameStack1 = stack();
TKUnit.assertEqual(rootView1, testFrameRoot1.root);
TKUnit.assertEqual(frameStack1.length, 1);
const testFrameRoot2 = createTestFrameRootEntry();
_resetRootView(testFrameRoot2.entry);
TKUnit.waitUntilReady(() => testFrameRoot2.page.isLoaded);
const rootView2 = getRootView();
const frameStack2 = stack();
TKUnit.assertEqual(rootView2, testFrameRoot2.root);
TKUnit.assertEqual(frameStack2.length, 1);
};
export function test_reset_frame_to_tab() {
const testFrameRoot = createTestFrameRootEntry();
_resetRootView(testFrameRoot.entry);
TKUnit.waitUntilReady(() => testFrameRoot.page.isLoaded);
const rootView1 = getRootView();
const frameStack1 = stack();
TKUnit.assertEqual(rootView1, testFrameRoot.root);
TKUnit.assertEqual(frameStack1.length, 1);
const testTabRoot = createTestTabRootEntry();
_resetRootView(testTabRoot.entry);
TKUnit.waitUntilReady(() => testTabRoot.page.isLoaded);
const rootView2 = getRootView();
const frameStack2 = stack();
TKUnit.assertEqual(rootView2, testTabRoot.root);
TKUnit.assertEqual(frameStack2.length, 2);
};
export function test_reset_tab_to_frame() {
const testTabRoot = createTestTabRootEntry();
_resetRootView(testTabRoot.entry);
TKUnit.waitUntilReady(() => testTabRoot.page.isLoaded);
const rootView2 = getRootView();
const frameStack2 = stack();
TKUnit.assertEqual(rootView2, testTabRoot.root);
TKUnit.assertEqual(frameStack2.length, 2);
const testFrameRoot = createTestFrameRootEntry();
_resetRootView(testFrameRoot.entry);
TKUnit.waitUntilReady(() => testFrameRoot.page.isLoaded);
const rootView1 = getRootView();
const frameStack1 = stack();
TKUnit.assertEqual(rootView1, testFrameRoot.root);
TKUnit.assertEqual(frameStack1.length, 1);
};
export function test_reset_tab_to_tab() {
const testTabRoot1 = createTestTabRootEntry();
_resetRootView(testTabRoot1.entry);
TKUnit.waitUntilReady(() => testTabRoot1.page.isLoaded);
const rootView1 = getRootView();
const frameStack1 = stack();
TKUnit.assertEqual(rootView1, testTabRoot1.root);
TKUnit.assertEqual(frameStack1.length, 2);
const testTabRoot2 = createTestTabRootEntry();
_resetRootView(testTabRoot2.entry);
TKUnit.waitUntilReady(() => testTabRoot2.page.isLoaded);
const rootView2 = getRootView();
const frameStack2 = stack();
TKUnit.assertEqual(rootView2, testTabRoot2.root);
TKUnit.assertEqual(frameStack2.length, 2);
};
export function tearDownModule() {
// reset the root to frame for other tests
const resetFrameRoot = createTestFrameRootEntry();
_resetRootView(resetFrameRoot.entry);
TKUnit.waitUntilReady(() => resetFrameRoot.page.isLoaded);
}

View File

@@ -1,7 +1,8 @@
/* tslint:disable */
import * as TKUnit from "./TKUnit";
import { _resetRootView, getRootView } from "tns-core-modules/application";
import { messageType } from "tns-core-modules/trace";
import { topmost, Frame } from "tns-core-modules/ui/frame";
import { topmost, Frame, NavigationEntry } from "tns-core-modules/ui/frame";
import { Page } from "tns-core-modules/ui/page";
import { TextView } from "tns-core-modules/ui/text-view";
import { Button } from "tns-core-modules/ui/button";
@@ -233,6 +234,9 @@ allTests["SEARCH-BAR"] = searchBarTests;
import * as navigationTests from "./navigation/navigation-tests";
allTests["NAVIGATION"] = navigationTests;
import * as resetRootViewTests from "./navigation/reset-root-view-tests";
allTests["RESET-ROOT-VIEW"] = resetRootViewTests;
const testsSuitesWithLongDelay = {
HTTP: 15 * 1000,
}

View File

@@ -2,8 +2,6 @@
require("globals");
import { Observable, EventData } from "../data/observable";
// types
import { View } from "../ui/core/view";
import {
trace as profilingTrace,
time,

View File

@@ -126,7 +126,7 @@ setApplication(androidApp);
let mainEntry: NavigationEntry;
let started = false;
// NOTE: for backwards compatibility. Remove for 4.0.0.
let createRootFrame = true;
const createRootFrame = { value: true };
export function start(entry?: NavigationEntry | string) {
if (started) {
throw new Error("Application is already started.");
@@ -141,11 +141,11 @@ export function start(entry?: NavigationEntry | string) {
}
export function shouldCreateRootFrame(): boolean {
return createRootFrame;
return createRootFrame.value;
}
export function run(entry?: NavigationEntry | string) {
createRootFrame = false;
createRootFrame.value = false;
start(entry);
}
@@ -157,6 +157,7 @@ export function _resetRootView(entry?: NavigationEntry | string) {
throw new Error("Cannot find android activity.");
}
createRootFrame.value = false;
mainEntry = typeof entry === "string" ? { moduleName: entry } : entry;
const callbacks: AndroidActivityCallbacks = activity[CALLBACKS];
callbacks.resetActivityContent(activity);
@@ -166,7 +167,7 @@ export function getMainEntry() {
return mainEntry;
}
export function getRootView() {
export function getRootView(): View {
// Use start activity as a backup when foregroundActivity is still not set
// in cases when we are getting the root view before activity.onResumed event is fired
const activity = androidApp.foregroundActivity || androidApp.startActivity;

View File

@@ -100,7 +100,7 @@ class IOSApplication implements IOSApplicationDefinition {
}
}
get rootView() : View {
get rootView(): View {
return this._rootView;
}
@@ -213,11 +213,16 @@ class IOSApplication implements IOSApplicationDefinition {
}
public setWindowContent(view?: View): void {
if (this._rootView) {
// if we already have a root view, we reset it.
this._rootView._onRootViewReset();
}
const rootView = createRootView(view);
this._rootView = rootView;
const controller = getViewController(rootView);
if (createRootFrame) {
if (createRootFrame.value) {
// Don't setup as styleScopeHost
rootView._setupUI({});
} else {
@@ -248,7 +253,7 @@ function createRootView(v?: View) {
if (!rootView) {
// try to navigate to the mainEntry (if specified)
if (mainEntry) {
if (createRootFrame) {
if (createRootFrame.value) {
const frame = rootView = new Frame();
frame.navigate(mainEntry);
} else {
@@ -272,7 +277,7 @@ export function getRootView() {
}
// NOTE: for backwards compatibility. Remove for 4.0.0.
let createRootFrame = true;
const createRootFrame = { value: true };
let started: boolean = false;
export function start(entry?: string | NavigationEntry) {
mainEntry = typeof entry === "string" ? { moduleName: entry } : entry;
@@ -300,12 +305,12 @@ export function start(entry?: string | NavigationEntry) {
}
export function run(entry?: string | NavigationEntry) {
createRootFrame = false;
createRootFrame.value = false;
start(entry);
}
export function _resetRootView(entry?: NavigationEntry | string) {
createRootFrame = false;
createRootFrame.value = false;
mainEntry = typeof entry === "string" ? { moduleName: entry } : entry;
iosApp.setWindowContent();
}

View File

@@ -267,6 +267,10 @@ export abstract class ViewBase extends Observable {
* Method is intended to be overridden by inheritors and used as "protected"
*/
public _dialogClosed(): void;
/**
* Method is intended to be overridden by inheritors and used as "protected"
*/
public _onRootViewReset(): void;
_domId: number;

View File

@@ -961,6 +961,13 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
public _dialogClosed(): void {
return;
}
public _onRootViewReset(): void {
eachDescendant(this, (child: ViewBase) => {
child._onRootViewReset();
return true;
});
}
}
ViewBase.prototype.isCollapsed = false;

View File

@@ -58,7 +58,7 @@ export class FrameBase extends CustomLayoutView implements FrameDefinition {
@profile
public onLoaded() {
super.onLoaded();
this._processNextNavigationEntry();
}
@@ -424,10 +424,25 @@ export class FrameBase extends CustomLayoutView implements FrameDefinition {
this._isInFrameStack = false;
}
private _removeFromFrameStack() {
if (!this._isInFrameStack) {
return;
}
const index = frameStack.indexOf(this);
frameStack.splice(index, 1);
this._isInFrameStack = false;
}
public _dialogClosed(): void {
this._popFromFrameStack();
}
public _onRootViewReset(): void {
this._removeFromFrameStack();
super._onRootViewReset();
}
get _childrenCount(): number {
if (this.currentPage) {
return 1;

View File

@@ -244,7 +244,7 @@ export class Frame extends FrameBase {
this.goBack();
return true;
}
if (!this.navigationQueueIsEmpty()) {
const manager = this._getFragmentManager();
if (manager) {
@@ -935,6 +935,10 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
}
public resetActivityContent(activity: android.app.Activity): void {
if (this._rootView) {
// if we already have a root view, we reset it.
this._rootView._onRootViewReset();
}
// Delete previously cached root view in order to recreate it.
this._rootView = null;
this.setActivityContent(activity, null, false);
@@ -1020,11 +1024,11 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
const notifyLaunch = profile("notifyLaunch", function notifyLaunch(intent: android.content.Intent, savedInstanceState: android.os.Bundle): View {
const launchArgs: application.LaunchEventData = {
eventName: application.launchEvent,
object: application.android,
android: intent, savedInstanceState
eventName: application.launchEvent,
object: application.android,
android: intent, savedInstanceState
};
application.notify(launchArgs);
application.notify(<application.LoadAppCSSEventData>{ eventName: "loadAppCss", object: <any>this, cssFile: application.getCssFileName() });
return launchArgs.root;