mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
test: add reset root view tests (#5437)
This commit is contained in:
141
tests/app/navigation/reset-root-view-tests.ts
Normal file
141
tests/app/navigation/reset-root-view-tests.ts
Normal 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);
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
require("globals");
|
||||
|
||||
import { Observable, EventData } from "../data/observable";
|
||||
// types
|
||||
import { View } from "../ui/core/view";
|
||||
import {
|
||||
trace as profilingTrace,
|
||||
time,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user