mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
fix: move BottomNavigation and Tabs to @nativescript-community
Cocoapods no longer required with @nativescript/core out of the box and users are no longer taxed with MaterialTabs even if they didn't use those components. BREAKING CHANGES If using `BottomNavigation`, just install `@nativescript-community/ui-material-bottom-navigation` and update your imports to use it. API is exactly the same. If using `Tabs`, just install `@nativescript-community/ui-material-tabs` and update your imports to use it. API is exactly the same.
This commit is contained in:
@@ -1,284 +0,0 @@
|
||||
import * as TKUnit from '../../tk-unit';
|
||||
import * as helper from '../../ui-helper';
|
||||
import { Label } from '@nativescript/core/ui/label';
|
||||
import { StackLayout } from '@nativescript/core/ui/layouts/stack-layout';
|
||||
import { Frame } from '@nativescript/core/ui/frame';
|
||||
import { Page } from '@nativescript/core/ui/page';
|
||||
import { ListView, ItemEventData } from '@nativescript/core/ui/list-view';
|
||||
import { BottomNavigation, TabContentItem, TabStrip, TabStripItem } from '@nativescript/core';
|
||||
import { Button } from '@nativescript/core/ui/button';
|
||||
|
||||
var ASYNC = 2;
|
||||
|
||||
function _createBottomNavigation(): BottomNavigation {
|
||||
var tabView = new BottomNavigation();
|
||||
tabView.id = 'BottomNavigation';
|
||||
|
||||
return tabView;
|
||||
}
|
||||
|
||||
function _createContentItems(count: number): Array<TabContentItem> {
|
||||
const items = new Array<TabContentItem>();
|
||||
for (let i = 0; i < count; i++) {
|
||||
const label = new Label();
|
||||
label.text = 'Tab ' + i;
|
||||
const tabEntry = new TabContentItem();
|
||||
tabEntry.content = label;
|
||||
items.push(tabEntry);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
function _createTabStrip(count: number): TabStrip {
|
||||
const items = new Array<TabStripItem>();
|
||||
for (let i = 0; i < count; i++) {
|
||||
let tabStripEntry = new TabStripItem();
|
||||
tabStripEntry.title = 'Tab ' + i;
|
||||
items.push(tabStripEntry);
|
||||
}
|
||||
|
||||
const tabStrip = new TabStrip();
|
||||
tabStrip.items = items;
|
||||
|
||||
return tabStrip;
|
||||
}
|
||||
|
||||
function _createListView(): ListView {
|
||||
var listView = new ListView();
|
||||
listView.id = 'ListView';
|
||||
var items = Array.apply(null, Array(10)).map(function (_, i) {
|
||||
return i;
|
||||
});
|
||||
|
||||
listView.on(ListView.itemLoadingEvent, function (args: ItemEventData) {
|
||||
var button = <Button>args.view;
|
||||
if (!button) {
|
||||
button = new Button();
|
||||
button.on(Button.tapEvent, _clickHandlerFactory(args.index));
|
||||
args.view = button;
|
||||
}
|
||||
|
||||
button.text = 'Button' + args.index;
|
||||
button.id = button.text;
|
||||
});
|
||||
|
||||
listView.items = items;
|
||||
|
||||
return listView;
|
||||
}
|
||||
|
||||
function _clickHandlerFactory(index: number) {
|
||||
return function () {
|
||||
var pageFactory = function (): Page {
|
||||
var detailsLabel = new Label();
|
||||
detailsLabel.text = 'Details Page ' + index;
|
||||
var detailsPage = new Page();
|
||||
detailsPage.id = 'details-page';
|
||||
detailsPage.content = detailsLabel;
|
||||
|
||||
return detailsPage;
|
||||
};
|
||||
|
||||
helper.navigateWithHistory(pageFactory);
|
||||
};
|
||||
}
|
||||
|
||||
function _createFrameView(): Frame {
|
||||
const frame = new Frame();
|
||||
frame.navigate({ create: () => new Page() });
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
export function testBackNavigationToTabViewWithNestedFramesShouldWork() {
|
||||
// https://github.com/NativeScript/NativeScript/issues/6490
|
||||
const topFrame = Frame.topmost();
|
||||
|
||||
let tabViewPage: Page;
|
||||
let tabView: BottomNavigation;
|
||||
|
||||
const pageFactory = function (): Page {
|
||||
tabView = _createBottomNavigation();
|
||||
let items = Array<TabContentItem>();
|
||||
let tabViewitem = new TabContentItem();
|
||||
// tabViewitem.title = "Item1";
|
||||
tabViewitem.content = _createFrameView();
|
||||
items.push(tabViewitem);
|
||||
|
||||
let tabViewitem2 = new TabContentItem();
|
||||
// tabViewitem2.title = "Item2";
|
||||
tabViewitem2.content = _createFrameView();
|
||||
items.push(tabViewitem2);
|
||||
|
||||
tabView.items = items;
|
||||
tabView.tabStrip = _createTabStrip(2);
|
||||
|
||||
tabViewPage = new Page();
|
||||
tabViewPage.id = 'tab-view-page';
|
||||
tabViewPage.content = tabView;
|
||||
|
||||
return tabViewPage;
|
||||
};
|
||||
|
||||
helper.waitUntilNavigatedFrom(() => topFrame.navigate(pageFactory), topFrame);
|
||||
|
||||
TKUnit.waitUntilReady(() => topFrame.currentPage === tabViewPage);
|
||||
TKUnit.waitUntilReady(() => tabViewIsFullyLoaded(tabView));
|
||||
|
||||
// navigate to a different page
|
||||
helper.waitUntilNavigatedFrom(() => topFrame.navigate({ create: () => new Page(), animated: false }), topFrame);
|
||||
|
||||
// navigate back to the page that hold the tabview with nested frames
|
||||
topFrame.goBack();
|
||||
|
||||
// make sure the app did not crash
|
||||
TKUnit.waitUntilReady(() => topFrame.navigationQueueIsEmpty());
|
||||
}
|
||||
|
||||
export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithAListViewTheListViewIsThere() {
|
||||
var topFrame = Frame.topmost();
|
||||
|
||||
let tabViewPage: Page;
|
||||
let tabView: BottomNavigation;
|
||||
|
||||
let pageFactory = function (): Page {
|
||||
tabView = _createBottomNavigation();
|
||||
let items = Array<TabContentItem>();
|
||||
let tabViewitem = new TabContentItem();
|
||||
// tabViewitem.title = "List";
|
||||
tabViewitem.content = _createListView();
|
||||
items.push(tabViewitem);
|
||||
|
||||
let label = new Label();
|
||||
label.text = 'About';
|
||||
let aboutLayout = new StackLayout();
|
||||
aboutLayout.id = 'AboutLayout';
|
||||
aboutLayout.addChild(label);
|
||||
tabViewitem = new TabContentItem();
|
||||
// tabViewitem.title = "About";
|
||||
tabViewitem.content = aboutLayout;
|
||||
items.push(tabViewitem);
|
||||
|
||||
tabView.items = items;
|
||||
tabView.tabStrip = _createTabStrip(2);
|
||||
|
||||
tabViewPage = new Page();
|
||||
tabViewPage.id = 'tab-view-page';
|
||||
tabViewPage.content = tabView;
|
||||
|
||||
return tabViewPage;
|
||||
};
|
||||
|
||||
let rootPage = helper.getCurrentPage();
|
||||
|
||||
helper.navigateWithHistory(pageFactory);
|
||||
TKUnit.waitUntilReady(() => topFrame.currentPage === tabViewPage);
|
||||
TKUnit.waitUntilReady(() => tabViewIsFullyLoaded(tabView));
|
||||
|
||||
// This will navigate to a details page. The wait is inside the method.
|
||||
_clickTheFirstButtonInTheListViewNatively(tabView);
|
||||
|
||||
Frame.goBack();
|
||||
TKUnit.waitUntilReady(() => topFrame.navigationQueueIsEmpty()); //() => topFrame.currentPage === tabViewPage);
|
||||
|
||||
Frame.goBack();
|
||||
|
||||
TKUnit.waitUntilReady(() => topFrame.currentPage === rootPage);
|
||||
|
||||
TKUnit.assert(tabView.items[0].content instanceof ListView, 'ListView should be created when navigating back to the main page.');
|
||||
}
|
||||
|
||||
function tabViewIsFullyLoaded(tabView: BottomNavigation): boolean {
|
||||
if (!tabView.isLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const i = tabView.selectedIndex;
|
||||
if (i >= 0 && !tabView.items[i].isLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tabView.android) {
|
||||
const bottomNavigationBar = <org.nativescript.widgets.BottomNavigationBar>(<any>tabView)._bottomNavigationBar;
|
||||
if (bottomNavigationBar.getItemCount() === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function testLoadedAndUnloadedAreFired_WhenNavigatingAwayAndBack() {
|
||||
let topFrame = Frame.topmost();
|
||||
let rootPage = helper.getCurrentPage();
|
||||
|
||||
let itemCount = 2;
|
||||
let loadedEventsCount = [0, 0];
|
||||
let unloadedEventsCount = [0, 0];
|
||||
|
||||
const tabView = _createBottomNavigation();
|
||||
tabView.items = _createContentItems(itemCount);
|
||||
tabView.tabStrip = _createTabStrip(itemCount);
|
||||
|
||||
function createLoadedFor(tabIndex: number) {
|
||||
return function () {
|
||||
loadedEventsCount[tabIndex] = loadedEventsCount[tabIndex] + 1;
|
||||
};
|
||||
}
|
||||
|
||||
function createUnloadedFor(tabIndex: number) {
|
||||
return function () {
|
||||
unloadedEventsCount[tabIndex] = unloadedEventsCount[tabIndex] + 1;
|
||||
};
|
||||
}
|
||||
|
||||
tabView.items.forEach((item, i) => {
|
||||
item.content.on('loaded', createLoadedFor(i));
|
||||
item.content.on('unloaded', createUnloadedFor(i));
|
||||
});
|
||||
|
||||
const tabViewPage = new Page();
|
||||
helper.navigateWithHistory(() => {
|
||||
tabViewPage.content = tabView;
|
||||
|
||||
return tabViewPage;
|
||||
});
|
||||
TKUnit.waitUntilReady(() => tabViewIsFullyLoaded(tabView), ASYNC);
|
||||
|
||||
const detailsPage = new Page();
|
||||
helper.navigateWithHistory(() => detailsPage);
|
||||
TKUnit.assertEqual(topFrame.currentPage, detailsPage);
|
||||
|
||||
helper.goBack();
|
||||
TKUnit.assertEqual(topFrame.currentPage, tabViewPage);
|
||||
|
||||
for (let i = 0; i < itemCount; i++) {
|
||||
tabView.items[i].content.off('loaded');
|
||||
tabView.items[i].content.off('unloaded');
|
||||
}
|
||||
|
||||
helper.goBack();
|
||||
TKUnit.assertEqual(topFrame.currentPage, rootPage);
|
||||
|
||||
topFrame.currentPage.id = null;
|
||||
|
||||
TKUnit.arrayAssert(loadedEventsCount, [2, 0]);
|
||||
TKUnit.arrayAssert(unloadedEventsCount, [1, 0]);
|
||||
}
|
||||
|
||||
function _clickTheFirstButtonInTheListViewNatively(tabView: BottomNavigation) {
|
||||
if (tabView.android) {
|
||||
const androidListView = <android.widget.ListView>tabView.items[0].content.nativeView;
|
||||
// var viewPager: android.support.v4.view.ViewPager = (<any>tabView)._viewPager;
|
||||
// var androidListView = <android.widget.ListView>viewPager.getChildAt(0);
|
||||
var stackLayout = <org.nativescript.widgets.StackLayout>androidListView.getChildAt(0);
|
||||
var button = <android.widget.Button>stackLayout.getChildAt(0);
|
||||
button.performClick();
|
||||
} else {
|
||||
const tableView = <UITableView>tabView.ios.selectedViewController.view.subviews[0];
|
||||
const cell = <UITableViewCell>tableView.cellForRowAtIndexPath(NSIndexPath.indexPathForItemInSection(0, 0));
|
||||
const btn = <UIButton>cell.contentView.subviews[0];
|
||||
btn.sendActionsForControlEvents(UIControlEvents.TouchUpInside);
|
||||
}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
import * as TKUnit from '../../tk-unit';
|
||||
import { isAndroid } from '@nativescript/core/platform';
|
||||
import { _resetRootView } from '@nativescript/core/application/';
|
||||
import { Frame, NavigationEntry } from '@nativescript/core/ui/frame';
|
||||
import { Page } from '@nativescript/core/ui/page';
|
||||
// import { TabView, TabViewItem } from "@nativescript/core/ui/tab-view";
|
||||
import { BottomNavigation, TabContentItem, TabStrip, TabStripItem } from '@nativescript/core';
|
||||
|
||||
function waitUntilNavigatedToMaxTimeout(pages: Page[], action: Function) {
|
||||
const maxTimeout = 8;
|
||||
let completed = 0;
|
||||
function navigatedTo(args) {
|
||||
args.object.page.off('navigatedTo', navigatedTo);
|
||||
completed++;
|
||||
}
|
||||
|
||||
pages.forEach((page) => page.on('navigatedTo', navigatedTo));
|
||||
action();
|
||||
TKUnit.waitUntilReady(() => completed === pages.length, maxTimeout);
|
||||
}
|
||||
|
||||
function waitUntilTabViewReady(page: Page, action: Function) {
|
||||
action();
|
||||
|
||||
if (isAndroid) {
|
||||
TKUnit.waitUntilReady(() => page.frame._currentEntry.fragment.isAdded());
|
||||
} else {
|
||||
TKUnit.waitUntilReady(() => page.isLoaded);
|
||||
}
|
||||
}
|
||||
|
||||
function createPage(i: number) {
|
||||
const page = new Page();
|
||||
page.id = `Tab${i} Frame${i} Page${i}`;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
function createFrame(i: number, page: Page) {
|
||||
const frame = new Frame();
|
||||
frame.navigate(() => page);
|
||||
frame.id = `Tab${i} Frame${i}`;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
function createTabItem(i: number, frame: Frame) {
|
||||
const tabEntry = new TabContentItem();
|
||||
// tabEntry.title = "Tab " + i;
|
||||
tabEntry.content = frame;
|
||||
tabEntry['index'] = i;
|
||||
|
||||
return tabEntry;
|
||||
}
|
||||
|
||||
function createTabItemsWithFrames(count: number) {
|
||||
const items = [];
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
const page = createPage(i);
|
||||
const frame = createFrame(i, page);
|
||||
const tabItem = createTabItem(i, frame);
|
||||
|
||||
items.push({ page, frame, tabItem });
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
function createTabStrip(count: number): TabStrip {
|
||||
const items = new Array<TabStripItem>();
|
||||
for (let i = 0; i < count; i++) {
|
||||
let tabStripEntry = new TabStripItem();
|
||||
tabStripEntry.title = 'Tab ' + i;
|
||||
items.push(tabStripEntry);
|
||||
}
|
||||
|
||||
const tabStrip = new TabStrip();
|
||||
tabStrip.items = items;
|
||||
|
||||
return tabStrip;
|
||||
}
|
||||
|
||||
export function test_frame_topmost_matches_selectedIndex() {
|
||||
const items = createTabItemsWithFrames(3);
|
||||
const tabView = new BottomNavigation();
|
||||
tabView.items = items.map((item) => item.tabItem);
|
||||
tabView.tabStrip = createTabStrip(3);
|
||||
|
||||
// iOS cannot preload tab items
|
||||
// Android preloads 1 tab item to the sides by default
|
||||
// set this to 0, so that both platforms behave the same.
|
||||
// tabView.androidOffscreenTabLimit = 0;
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => tabView,
|
||||
};
|
||||
|
||||
waitUntilNavigatedToMaxTimeout([items[0].page], () => _resetRootView(entry));
|
||||
TKUnit.assertEqual(Frame.topmost().id, 'Tab0 Frame0');
|
||||
|
||||
waitUntilNavigatedToMaxTimeout([items[1].page], () => (tabView.selectedIndex = 1));
|
||||
TKUnit.assertEqual(Frame.topmost().id, 'Tab1 Frame1');
|
||||
}
|
||||
|
||||
export function test_no_preloading_on_index_change() {
|
||||
let actualEventsRaised = [];
|
||||
|
||||
function resetActualEventsRaised() {
|
||||
for (var i = 0; i < actualEventsRaised.length; i++) {
|
||||
actualEventsRaised[i] = [];
|
||||
}
|
||||
}
|
||||
|
||||
function attachEventHandlers(i: number, item) {
|
||||
actualEventsRaised.push([]);
|
||||
|
||||
const page = item.page;
|
||||
page.on(Page.loadedEvent, () => actualEventsRaised[i].push(`${page.id} loaded`));
|
||||
page.on(Page.unloadedEvent, () => actualEventsRaised[i].push(`${page.id} unloaded`));
|
||||
page.on(Page.navigatingToEvent, () => actualEventsRaised[i].push(`${page.id} navigatingTo`));
|
||||
page.on(Page.navigatingFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatingFrom`));
|
||||
page.on(Page.navigatedToEvent, () => actualEventsRaised[i].push(`${page.id} navigatedTo`));
|
||||
page.on(Page.navigatedFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatedFrom`));
|
||||
|
||||
const frame = item.frame;
|
||||
frame.on(Frame.loadedEvent, () => actualEventsRaised[i].push(`${frame.id} loaded`));
|
||||
frame.on(Frame.unloadedEvent, () => actualEventsRaised[i].push(`${frame.id} unloaded`));
|
||||
}
|
||||
|
||||
const items = createTabItemsWithFrames(3);
|
||||
|
||||
items.forEach((item, i) => {
|
||||
attachEventHandlers(i, item);
|
||||
});
|
||||
|
||||
const tabView = new BottomNavigation();
|
||||
tabView.items = items.map((item) => item.tabItem);
|
||||
tabView.tabStrip = createTabStrip(3);
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => tabView,
|
||||
};
|
||||
|
||||
waitUntilNavigatedToMaxTimeout([items[0].page], () => _resetRootView(entry));
|
||||
|
||||
const expectedEventsRaisedAfterTabCreated = [['Tab0 Frame0 loaded', 'Tab0 Frame0 Page0 navigatingTo', 'Tab0 Frame0 Page0 loaded', 'Tab0 Frame0 Page0 navigatedTo'], [], []];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterTabCreated);
|
||||
|
||||
resetActualEventsRaised();
|
||||
waitUntilNavigatedToMaxTimeout([items[2].page], () => (tabView.selectedIndex = 2));
|
||||
|
||||
const expectedEventsRaisedAfterSelectThirdTab = [['Tab0 Frame0 Page0 unloaded', 'Tab0 Frame0 unloaded'], [], ['Tab2 Frame2 loaded', 'Tab2 Frame2 Page2 navigatingTo', 'Tab2 Frame2 Page2 loaded', 'Tab2 Frame2 Page2 navigatedTo']];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterSelectThirdTab);
|
||||
|
||||
resetActualEventsRaised();
|
||||
|
||||
waitUntilTabViewReady(items[0].page, () => (tabView.selectedIndex = 0));
|
||||
|
||||
const expectedEventsRaisedAfterReturnToFirstTab = [['Tab0 Frame0 Page0 loaded', 'Tab0 Frame0 loaded'], [], ['Tab2 Frame2 Page2 unloaded', 'Tab2 Frame2 unloaded']];
|
||||
|
||||
TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterReturnToFirstTab);
|
||||
}
|
||||
|
||||
export function tearDownModule() {
|
||||
const page = new Page();
|
||||
const frame = new Frame();
|
||||
frame.navigate(() => page);
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => frame,
|
||||
};
|
||||
|
||||
waitUntilNavigatedToMaxTimeout([page], () => _resetRootView(entry));
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import { BottomNavigation } from '@nativescript/core/ui/bottom-navigation';
|
||||
|
||||
export function getNativeTabCount(tabView: BottomNavigation): number {
|
||||
// there is no native tab content view implementation for Android Bottom Navigation
|
||||
return tabView.items.length;
|
||||
}
|
||||
|
||||
export function selectNativeTab(tabView: BottomNavigation, index: number): void {
|
||||
const bottomNavigationBar = <org.nativescript.widgets.BottomNavigationBar>(<any>tabView)._bottomNavigationBar;
|
||||
|
||||
if (bottomNavigationBar) {
|
||||
bottomNavigationBar.setSelectedPosition(index);
|
||||
}
|
||||
}
|
||||
|
||||
export function getNativeSelectedIndex(tabView: BottomNavigation): number {
|
||||
// there is no native tab content view implementation for Android Bottom Navigation
|
||||
return tabView.selectedIndex;
|
||||
}
|
||||
|
||||
export function getNativeFont(tabView: BottomNavigation): any {
|
||||
const tv: android.widget.TextView = (<org.nativescript.widgets.BottomNavigationBar>(<any>tabView)._bottomNavigationBar).getTextViewForItemAt(0);
|
||||
if (tv) {
|
||||
return {
|
||||
typeface: tv.getTypeface(),
|
||||
size: tv.getTextSize(),
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getOriginalFont(tabView: BottomNavigation): any {
|
||||
const tv: android.widget.TextView = (<org.nativescript.widgets.BottomNavigationBar>(<any>tabView)._bottomNavigationBar).getTextViewForItemAt(0);
|
||||
|
||||
return {
|
||||
typeface: tv.getTypeface(),
|
||||
size: tv.getTextSize(),
|
||||
};
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
//@private
|
||||
import { BottomNavigation } from '@nativescript/core/ui/bottom-navigation';
|
||||
|
||||
export function getNativeTabCount(tabView: BottomNavigation): number;
|
||||
export function selectNativeTab(tabView: BottomNavigation, index: number): void;
|
||||
export function getNativeSelectedIndex(tabView: BottomNavigation): number;
|
||||
export function getNativeFont(tabView: BottomNavigation): any;
|
||||
export function getOriginalFont(tabView: BottomNavigation): any;
|
||||
@@ -1,35 +0,0 @@
|
||||
import tabViewModule = require('@nativescript/core/ui/tab-view');
|
||||
import { Font } from '@nativescript/core/ui/styling/font';
|
||||
|
||||
export function getNativeTabCount(tabView: tabViewModule.TabView): number {
|
||||
if (!tabView.ios.viewControllers) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tabView.ios.viewControllers.count;
|
||||
}
|
||||
|
||||
export function selectNativeTab(tabView: tabViewModule.TabView, index: number): void {
|
||||
tabView.ios.selectedIndex = index;
|
||||
tabView.ios.delegate.tabBarControllerDidSelectViewController(tabView.ios, tabView.ios.selectedViewController);
|
||||
}
|
||||
|
||||
export function getNativeSelectedIndex(tabView: tabViewModule.TabView): number {
|
||||
return tabView.ios.selectedIndex;
|
||||
}
|
||||
|
||||
export function getNativeFont(tabView: tabViewModule.TabView): UIFont {
|
||||
const tabBar = <UITabBar>tabView.ios.tabBar;
|
||||
if (tabBar.items.count > 0) {
|
||||
const currentAttrs = tabBar.items[0].titleTextAttributesForState(UIControlState.Normal);
|
||||
if (currentAttrs) {
|
||||
return currentAttrs.objectForKey(NSFontAttributeName);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getOriginalFont(tabView: tabViewModule.TabView): UIFont {
|
||||
return (tabView.style.fontInternal || Font.default).getUIFont(UIFont.systemFontOfSize(10));
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import { Image, Label, BottomNavigation, Builder, TabContentItem, TabStrip, TabStripItem } from '@nativescript/core/ui';
|
||||
import * as TKUnit from '../../tk-unit';
|
||||
|
||||
export function test_lowercase_declaration() {
|
||||
const root = Builder.parse(`
|
||||
<bottom-navigation>
|
||||
<tab-strip id="tab-strip">
|
||||
<tab-strip-item id="tab-strip-item">
|
||||
<image src="res://icon" id="tab-strip-item-image" />
|
||||
<label text="test" id="tab-strip-item-label" />
|
||||
</tab-strip-item>
|
||||
</tab-strip>
|
||||
<tab-content-item id="tab-content-item">
|
||||
<label text="test" id="tab-content-item-label" />
|
||||
</tab-content-item>
|
||||
</bottom-navigation>
|
||||
`);
|
||||
|
||||
const tabStrip = root.getViewById('tab-strip');
|
||||
const tabStripItem = root.getViewById('tab-strip-item');
|
||||
const tabStripItemImage = root.getViewById('tab-strip-item-image');
|
||||
const tabStripItemLabel = root.getViewById('tab-strip-item-label');
|
||||
const tabContentItem = root.getViewById('tab-content-item');
|
||||
const tabContentItemLabel = root.getViewById('tab-content-item-label');
|
||||
|
||||
TKUnit.assert(root instanceof BottomNavigation, 'Expected result: BottomNavigation!; Actual result: ' + root);
|
||||
TKUnit.assert(tabStrip instanceof TabStrip, 'Expected result: TabStrip!; Actual result: ' + tabStrip);
|
||||
TKUnit.assert(tabStripItem instanceof TabStripItem, 'Expected result: TabStripItem!; Actual result: ' + tabStripItem);
|
||||
TKUnit.assert(tabStripItemImage instanceof Image, 'Expected result: Image!; Actual result: ' + tabStripItemImage);
|
||||
TKUnit.assert(tabStripItemLabel instanceof Label, 'Expected result: Label!; Actual result: ' + tabStripItemLabel);
|
||||
TKUnit.assert(tabContentItem instanceof TabContentItem, 'Expected result: TabContentItem!; Actual result: ' + tabContentItem);
|
||||
TKUnit.assert(tabContentItemLabel instanceof Label, 'Expected result: Label!; Actual result: ' + tabContentItemLabel);
|
||||
}
|
||||
@@ -1,347 +0,0 @@
|
||||
import { UITest } from '../../ui-test';
|
||||
import { Label } from '@nativescript/core/ui/label';
|
||||
import * as TKUnit from '../../tk-unit';
|
||||
import * as helper from '../../ui-helper';
|
||||
import * as tabViewTestsNative from './bottom-navigation-tests-native';
|
||||
|
||||
import { BottomNavigation, TabContentItem, TabStrip, TabStripItem, SelectedIndexChangedEventData } from '@nativescript/core';
|
||||
|
||||
export class BottomNavigationTest extends UITest<BottomNavigation> {
|
||||
public create(): BottomNavigation {
|
||||
var tabView = new BottomNavigation();
|
||||
tabView.id = 'TabView';
|
||||
|
||||
return tabView;
|
||||
}
|
||||
|
||||
// public test_recycling() {
|
||||
// const setters = new Map<string, Array<any>>();
|
||||
// setters.set("items", this._createItems(3));
|
||||
// helper.nativeView_recycling_test(() => new BottomNavigation(), null, null, setters);
|
||||
// }
|
||||
|
||||
_createContentItems(count: number): Array<TabContentItem> {
|
||||
const items = new Array<TabContentItem>();
|
||||
for (let i = 0; i < count; i++) {
|
||||
const label = new Label();
|
||||
label.text = 'Tab ' + i;
|
||||
const tabEntry = new TabContentItem();
|
||||
tabEntry.content = label;
|
||||
items.push(tabEntry);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
_createTabStrip(count: number): TabStrip {
|
||||
const items = new Array<TabStripItem>();
|
||||
for (let i = 0; i < count; i++) {
|
||||
let tabStripEntry = new TabStripItem();
|
||||
tabStripEntry.title = 'Tab ' + i;
|
||||
items.push(tabStripEntry);
|
||||
}
|
||||
|
||||
const tabStrip = new TabStrip();
|
||||
tabStrip.items = items;
|
||||
|
||||
return tabStrip;
|
||||
}
|
||||
|
||||
public tearDown() {
|
||||
if (this.testView && this.testView.items) {
|
||||
this.testView.items.length = 0;
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public waitUntilSelectedItemIsFullyLoaded(): boolean {
|
||||
const tabView = this.testView;
|
||||
if (!tabView.isLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const i = tabView.selectedIndex;
|
||||
if (i >= 0 && !tabView.items[i].isLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tabView.android) {
|
||||
const bottomNavigationBar = <org.nativescript.widgets.BottomNavigationBar>(<any>tabView)._bottomNavigationBar;
|
||||
if (bottomNavigationBar.getItemCount() === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public test_when_created_items_are_undefined = function () {
|
||||
TKUnit.assertEqual(this.testView.items, undefined, 'Items should be undefined initally.');
|
||||
};
|
||||
|
||||
public test_when_created_selected_index_is_undefined = function () {
|
||||
TKUnit.assertEqual(this.testView.selectedIndex, -1, 'selectedIndex should be undefined initally.');
|
||||
};
|
||||
|
||||
// TODO: Do we need this test?
|
||||
public test_when_setting_items_to_non_empty_array_the_same_amount_of_native_tabs_is_created = function () {
|
||||
this.testView.items = this._createContentItems(5);
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
let expectedValue = this.testView.items.length;
|
||||
let actualValue = tabViewTestsNative.getNativeTabCount(this.testView);
|
||||
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'NativeItems not equal to JS items.');
|
||||
};
|
||||
|
||||
// TODO: Do we need this test?
|
||||
public test_when_setting_items_to_empty_array_zero_native_tabs_are_created = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = [];
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var expectedValue = tabView.items.length;
|
||||
var actualValue = tabViewTestsNative.getNativeTabCount(tabView);
|
||||
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'Should have 0 native tabs.');
|
||||
};
|
||||
|
||||
public test_selected_index_becomes_zero_when_items_bound_to_non_empty_array = function () {
|
||||
var tabView = this.testView;
|
||||
// var items = [];
|
||||
|
||||
// var StackLayout0 = new StackLayout();
|
||||
// var label0 = new Label();
|
||||
// label0.text = "Tab 0";
|
||||
// StackLayout0.addChild(label0);
|
||||
// var tabEntry0 = new TabContentItem();
|
||||
// // tabEntry0.title = "Tab 0";
|
||||
// tabEntry0.view = StackLayout0;
|
||||
// items.push(tabEntry0);
|
||||
|
||||
// var StackLayout1 = new StackLayout();
|
||||
// var label1 = new Label();
|
||||
// label1.text = "Tab 1";
|
||||
// StackLayout1.addChild(label1);
|
||||
// var tabEntry1 = new TabContentItem();
|
||||
// // tabEntry1.title = "Tab 1";
|
||||
// tabEntry1.view = StackLayout1;
|
||||
// items.push(tabEntry1);
|
||||
|
||||
tabView.items = this._createContentItems(5);
|
||||
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var expectedValue = 0;
|
||||
var actualValue = tabView.selectedIndex;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'When bound selectedIndex should be 0.');
|
||||
};
|
||||
|
||||
public test_selected_index_becomes_undefined_when_items_bound_to_empty_array = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(5);
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
tabView.selectedIndex = 4;
|
||||
|
||||
tabView.items = [];
|
||||
|
||||
var expectedValue = -1;
|
||||
var actualValue = tabView.selectedIndex;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'selectedIndex should be undefined.');
|
||||
};
|
||||
|
||||
public test_selected_index_becomes_undefined_when_items_set_to_undefined = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(5);
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
// tabView.selectedIndex = 4;
|
||||
|
||||
tabView.items = undefined;
|
||||
|
||||
var expectedValue = -1;
|
||||
var actualValue = tabView.selectedIndex;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'selectedIndex should be undefined.');
|
||||
};
|
||||
|
||||
public test_selected_index_becomes_undefined_when_items_set_to_null = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(5);
|
||||
tabView.selectedIndex = 4;
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
tabView.items = null;
|
||||
|
||||
var expectedValue = -1;
|
||||
var actualValue = tabView.selectedIndex;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'selectedIndex should be undefined.');
|
||||
};
|
||||
|
||||
public test_items_is_resolved_correctly_if_set_before_view_is_loaded = function () {
|
||||
var tabView = this.testView;
|
||||
var expectedValue = 5;
|
||||
tabView.items = this._createContentItems(expectedValue);
|
||||
tabView.selectedIndex = 4;
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var actualValue = tabView.items.length;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'items.length should be 5');
|
||||
};
|
||||
|
||||
public test_selected_index_is_resolved_correctly_if_set_before_view_is_loaded = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(5);
|
||||
var expectedValue = 4;
|
||||
tabView.selectedIndex = expectedValue;
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var actualValue = tabView.selectedIndex;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'selectedIndex');
|
||||
};
|
||||
|
||||
public test_binding_to_tabitem_with_undefined_view_should_throw = function () {
|
||||
var tabView = this.testView;
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
TKUnit.assertThrows(() => {
|
||||
let item = new TabContentItem();
|
||||
// item.title = "Tab 0";
|
||||
item.content = undefined;
|
||||
tabView.items = [item];
|
||||
}, 'Binding TabNavigation to a TabItem with undefined view should throw.');
|
||||
};
|
||||
|
||||
public test_binding_to_tabitem_with_null_view_should_throw = function () {
|
||||
var tabView = this.testView;
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
TKUnit.assertThrows(() => {
|
||||
let item = new TabContentItem();
|
||||
// item.title = "Tab 0";
|
||||
item.content = null;
|
||||
tabView.items = [item];
|
||||
}, 'Binding TabNavigation to a TabItem with null view should throw.');
|
||||
};
|
||||
|
||||
public test_when_selecting_tab_natively_selectedIndex_is_updated_properly = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(2);
|
||||
tabView.tabStrip = this._createTabStrip(2);
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var expectedValue = 1;
|
||||
tabViewTestsNative.selectNativeTab(tabView, expectedValue);
|
||||
TKUnit.waitUntilReady(function () {
|
||||
return tabView.selectedIndex === expectedValue;
|
||||
}, helper.ASYNC);
|
||||
|
||||
var actualValue = tabView.selectedIndex;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'selectedIndex');
|
||||
};
|
||||
|
||||
public test_when_selecting_tab_natively_selectedIndexChangedEvent_is_raised = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(5);
|
||||
tabView.tabStrip = this._createTabStrip(5);
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var expectedOldIndex = 3;
|
||||
var expectedNewIndex = 4;
|
||||
var actualOldIndex;
|
||||
var actualNewIndex;
|
||||
|
||||
tabViewTestsNative.selectNativeTab(tabView, expectedOldIndex);
|
||||
TKUnit.waitUntilReady(function () {
|
||||
return tabView.selectedIndex === expectedOldIndex;
|
||||
}, helper.ASYNC);
|
||||
|
||||
tabView.on(BottomNavigation.selectedIndexChangedEvent, (args: SelectedIndexChangedEventData) => {
|
||||
actualOldIndex = args.oldIndex;
|
||||
actualNewIndex = args.newIndex;
|
||||
});
|
||||
|
||||
tabViewTestsNative.selectNativeTab(tabView, expectedNewIndex);
|
||||
TKUnit.waitUntilReady(function () {
|
||||
return tabView.selectedIndex === expectedNewIndex;
|
||||
}, helper.ASYNC);
|
||||
|
||||
TKUnit.assertEqual(actualOldIndex, expectedOldIndex, 'expectedOldIndex');
|
||||
TKUnit.assertEqual(actualNewIndex, expectedNewIndex, 'expectedNewIndex');
|
||||
};
|
||||
|
||||
// TODO: Do we need this test?
|
||||
public test_when_setting_selectedIndex_programatically_selectedIndexChangedEvent_is_raised = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(5);
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var expectedOldIndex = 2;
|
||||
var expectedNewIndex = 4;
|
||||
var actualOldIndex;
|
||||
var actualNewIndex;
|
||||
|
||||
tabView.selectedIndex = expectedOldIndex;
|
||||
TKUnit.waitUntilReady(function () {
|
||||
return tabViewTestsNative.getNativeSelectedIndex(tabView) === expectedOldIndex;
|
||||
}, helper.ASYNC);
|
||||
|
||||
tabView.on(BottomNavigation.selectedIndexChangedEvent, (args: SelectedIndexChangedEventData) => {
|
||||
actualOldIndex = args.oldIndex;
|
||||
actualNewIndex = args.newIndex;
|
||||
TKUnit.assertEqual(args.object, tabView, 'args.object should be TabView');
|
||||
});
|
||||
|
||||
tabView.selectedIndex = expectedNewIndex;
|
||||
TKUnit.waitUntilReady(function () {
|
||||
return tabViewTestsNative.getNativeSelectedIndex(tabView) === expectedNewIndex;
|
||||
}, helper.ASYNC);
|
||||
|
||||
TKUnit.assertEqual(actualOldIndex, expectedOldIndex, 'expectedOldIndex');
|
||||
TKUnit.assertEqual(actualNewIndex, expectedNewIndex, 'expectedNewIndex');
|
||||
};
|
||||
|
||||
// TODO: fonts are not yet supported
|
||||
// public test_font_is_reapplied_when_tab_items_change = function () {
|
||||
// const assertFontsAreEqual = (actual: any, expected: any, message?: string) => {
|
||||
// if (this.testView.ios) {
|
||||
// TKUnit.assertEqual(actual, expected, message);
|
||||
// } else {
|
||||
// TKUnit.assertEqual(actual.typeface, expected.typeface, `${message} [typeface]`);
|
||||
// TKUnit.assertEqual(actual.size, expected.size, `${message} [size]`);
|
||||
// }
|
||||
// }
|
||||
|
||||
// this.testView.items = this._createContentItems(1);
|
||||
// this.testView.tabStrip = this._createTabStrip(1);
|
||||
// this.waitUntilSelectedItemIsFullyLoaded();
|
||||
|
||||
// const originalFont = tabViewTestsNative.getOriginalFont(this.testView);
|
||||
// TKUnit.assertNotNull(originalFont, "Original Font should be applied");
|
||||
|
||||
// this.testView.style.font = "20 Pacifico";
|
||||
// let nativeFont = tabViewTestsNative.getNativeFont(this.testView);
|
||||
// TKUnit.assertNotNull(nativeFont, "Native Font should not be null");
|
||||
// TKUnit.assertNotEqual(originalFont, nativeFont, "Font should be changed");
|
||||
|
||||
// this.testView.items = this._createContentItems(2);
|
||||
// this.testView.tabStrip = this._createTabStrip(2);
|
||||
// this.waitUntilSelectedItemIsFullyLoaded();
|
||||
// assertFontsAreEqual(tabViewTestsNative.getNativeFont(this.testView), nativeFont, "Font must be 20 Pacifico after rebinding items.");
|
||||
|
||||
// this.testView.style.font = "bold 12 monospace";
|
||||
// nativeFont = tabViewTestsNative.getNativeFont(this.testView);
|
||||
|
||||
// this.testView.items = this._createContentItems(3);
|
||||
// this.testView.tabStrip = this._createTabStrip(3);
|
||||
// this.waitUntilSelectedItemIsFullyLoaded();
|
||||
// assertFontsAreEqual(tabViewTestsNative.getNativeFont(this.testView), nativeFont, "Font must be bold 12 monospace after rebinding items.");
|
||||
|
||||
// this.testView.style.font = unsetValue;
|
||||
// assertFontsAreEqual(tabViewTestsNative.getNativeFont(this.testView), originalFont, "Font must be the original one after resetting the style.");
|
||||
// }
|
||||
}
|
||||
|
||||
export function createTestCase(): BottomNavigationTest {
|
||||
return new BottomNavigationTest();
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
import * as TKUnit from '../../tk-unit';
|
||||
import * as helper from '../../ui-helper';
|
||||
import { Label } from '@nativescript/core/ui/label';
|
||||
import { StackLayout } from '@nativescript/core/ui/layouts/stack-layout';
|
||||
import { Frame } from '@nativescript/core/ui/frame';
|
||||
import { Page } from '@nativescript/core/ui/page';
|
||||
import { ListView, ItemEventData } from '@nativescript/core/ui/list-view';
|
||||
import { Tabs, TabContentItem, TabStrip, TabStripItem } from '@nativescript/core/ui/tabs';
|
||||
import { Button } from '@nativescript/core/ui/button';
|
||||
|
||||
var ASYNC = 2;
|
||||
|
||||
function _createTabsNavigation(): Tabs {
|
||||
var tabView = new Tabs();
|
||||
tabView.id = 'BottomNavigation';
|
||||
|
||||
return tabView;
|
||||
}
|
||||
|
||||
function _createContentItems(count: number): Array<TabContentItem> {
|
||||
const items = new Array<TabContentItem>();
|
||||
for (let i = 0; i < count; i++) {
|
||||
const label = new Label();
|
||||
label.text = 'Tab ' + i;
|
||||
const tabEntry = new TabContentItem();
|
||||
tabEntry.content = label;
|
||||
items.push(tabEntry);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
function _createTabStrip(count: number): TabStrip {
|
||||
const items = new Array<TabStripItem>();
|
||||
for (let i = 0; i < count; i++) {
|
||||
let tabStripEntry = new TabStripItem();
|
||||
tabStripEntry.title = 'Tab ' + i;
|
||||
items.push(tabStripEntry);
|
||||
}
|
||||
|
||||
const tabStrip = new TabStrip();
|
||||
tabStrip.items = items;
|
||||
|
||||
return tabStrip;
|
||||
}
|
||||
|
||||
function _createListView(): ListView {
|
||||
var listView = new ListView();
|
||||
listView.id = 'ListView';
|
||||
var items = Array.apply(null, Array(10)).map(function (_, i) {
|
||||
return i;
|
||||
});
|
||||
|
||||
listView.on(ListView.itemLoadingEvent, function (args: ItemEventData) {
|
||||
var button = <Button>args.view;
|
||||
if (!button) {
|
||||
button = new Button();
|
||||
button.on(Button.tapEvent, _clickHandlerFactory(args.index));
|
||||
args.view = button;
|
||||
}
|
||||
|
||||
button.text = 'Button' + args.index;
|
||||
button.id = button.text;
|
||||
});
|
||||
|
||||
listView.items = items;
|
||||
|
||||
return listView;
|
||||
}
|
||||
|
||||
function _clickHandlerFactory(index: number) {
|
||||
return function () {
|
||||
var pageFactory = function (): Page {
|
||||
var detailsLabel = new Label();
|
||||
detailsLabel.text = 'Details Page ' + index;
|
||||
var detailsPage = new Page();
|
||||
detailsPage.id = 'details-page';
|
||||
detailsPage.content = detailsLabel;
|
||||
|
||||
return detailsPage;
|
||||
};
|
||||
|
||||
helper.navigateWithHistory(pageFactory);
|
||||
};
|
||||
}
|
||||
|
||||
function _createFrameView(): Frame {
|
||||
const frame = new Frame();
|
||||
frame.navigate({ create: () => new Page() });
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
export function testBackNavigationToTabViewWithNestedFramesShouldWork() {
|
||||
// https://github.com/NativeScript/NativeScript/issues/6490
|
||||
const topFrame = Frame.topmost();
|
||||
|
||||
let tabViewPage: Page;
|
||||
let tabView: Tabs;
|
||||
|
||||
const pageFactory = function (): Page {
|
||||
tabView = _createTabsNavigation();
|
||||
let items = Array<TabContentItem>();
|
||||
let tabViewitem = new TabContentItem();
|
||||
// tabViewitem.title = "Item1";
|
||||
tabViewitem.content = _createFrameView();
|
||||
items.push(tabViewitem);
|
||||
|
||||
let tabViewitem2 = new TabContentItem();
|
||||
// tabViewitem2.title = "Item2";
|
||||
tabViewitem2.content = _createFrameView();
|
||||
items.push(tabViewitem2);
|
||||
|
||||
tabView.items = items;
|
||||
tabView.tabStrip = _createTabStrip(2);
|
||||
|
||||
tabViewPage = new Page();
|
||||
tabViewPage.id = 'tab-view-page';
|
||||
tabViewPage.content = tabView;
|
||||
|
||||
return tabViewPage;
|
||||
};
|
||||
|
||||
helper.waitUntilNavigatedFrom(() => topFrame.navigate(pageFactory), topFrame);
|
||||
|
||||
TKUnit.waitUntilReady(() => topFrame.currentPage === tabViewPage);
|
||||
TKUnit.waitUntilReady(() => tabViewIsFullyLoaded(tabView));
|
||||
|
||||
// navigate to a different page
|
||||
helper.waitUntilNavigatedFrom(() => topFrame.navigate({ create: () => new Page(), animated: false }), topFrame);
|
||||
|
||||
// navigate back to the page that hold the tabview with nested frames
|
||||
topFrame.goBack();
|
||||
|
||||
// make sure the app did not crash
|
||||
TKUnit.waitUntilReady(() => topFrame.navigationQueueIsEmpty());
|
||||
}
|
||||
|
||||
export function testWhenNavigatingBackToANonCachedPageContainingATabViewWithAListViewTheListViewIsThere() {
|
||||
var topFrame = Frame.topmost();
|
||||
|
||||
let tabViewPage: Page;
|
||||
let tabView: Tabs;
|
||||
|
||||
let pageFactory = function (): Page {
|
||||
tabView = _createTabsNavigation();
|
||||
let items = Array<TabContentItem>();
|
||||
let tabViewitem = new TabContentItem();
|
||||
// tabViewitem.title = "List";
|
||||
tabViewitem.content = _createListView();
|
||||
items.push(tabViewitem);
|
||||
|
||||
let label = new Label();
|
||||
label.text = 'About';
|
||||
let aboutLayout = new StackLayout();
|
||||
aboutLayout.id = 'AboutLayout';
|
||||
aboutLayout.addChild(label);
|
||||
tabViewitem = new TabContentItem();
|
||||
// tabViewitem.title = "About";
|
||||
tabViewitem.content = aboutLayout;
|
||||
items.push(tabViewitem);
|
||||
|
||||
tabView.items = items;
|
||||
tabView.tabStrip = _createTabStrip(2);
|
||||
|
||||
tabViewPage = new Page();
|
||||
tabViewPage.id = 'tab-view-page';
|
||||
tabViewPage.content = tabView;
|
||||
|
||||
return tabViewPage;
|
||||
};
|
||||
|
||||
let rootPage = helper.getCurrentPage();
|
||||
|
||||
helper.navigateWithHistory(pageFactory);
|
||||
TKUnit.waitUntilReady(() => topFrame.currentPage === tabViewPage);
|
||||
TKUnit.waitUntilReady(() => tabViewIsFullyLoaded(tabView));
|
||||
|
||||
// This will navigate to a details page. The wait is inside the method.
|
||||
_clickTheFirstButtonInTheListViewNatively(tabView);
|
||||
|
||||
Frame.goBack();
|
||||
TKUnit.waitUntilReady(() => topFrame.navigationQueueIsEmpty()); //() => topFrame.currentPage === tabViewPage);
|
||||
|
||||
Frame.goBack();
|
||||
|
||||
TKUnit.waitUntilReady(() => topFrame.currentPage === rootPage);
|
||||
|
||||
TKUnit.assert(tabView.items[0].content instanceof ListView, 'ListView should be created when navigating back to the main page.');
|
||||
}
|
||||
|
||||
function tabViewIsFullyLoaded(tabView: Tabs): boolean {
|
||||
if (!tabView.isLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const i = tabView.selectedIndex;
|
||||
if (i >= 0 && !tabView.items[i].isLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tabView.android) {
|
||||
const bottomNavigationBar = <org.nativescript.widgets.BottomNavigationBar>(<any>tabView)._bottomNavigationBar;
|
||||
if (bottomNavigationBar && bottomNavigationBar.getItemCount() === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function testLoadedAndUnloadedAreFired_WhenNavigatingAwayAndBack() {
|
||||
let topFrame = Frame.topmost();
|
||||
let rootPage = helper.getCurrentPage();
|
||||
|
||||
let itemCount = 2;
|
||||
let loadedEventsCount = [0, 0];
|
||||
let unloadedEventsCount = [0, 0];
|
||||
|
||||
const tabView = _createTabsNavigation();
|
||||
tabView.items = _createContentItems(itemCount);
|
||||
tabView.tabStrip = _createTabStrip(itemCount);
|
||||
|
||||
function createLoadedFor(tabIndex: number) {
|
||||
return function () {
|
||||
loadedEventsCount[tabIndex] = loadedEventsCount[tabIndex] + 1;
|
||||
};
|
||||
}
|
||||
|
||||
function createUnloadedFor(tabIndex: number) {
|
||||
return function () {
|
||||
unloadedEventsCount[tabIndex] = unloadedEventsCount[tabIndex] + 1;
|
||||
};
|
||||
}
|
||||
|
||||
tabView.items.forEach((item, i) => {
|
||||
item.content.on('loaded', createLoadedFor(i));
|
||||
item.content.on('unloaded', createUnloadedFor(i));
|
||||
});
|
||||
|
||||
const tabViewPage = new Page();
|
||||
helper.navigateWithHistory(() => {
|
||||
tabViewPage.content = tabView;
|
||||
|
||||
return tabViewPage;
|
||||
});
|
||||
TKUnit.waitUntilReady(() => tabViewIsFullyLoaded(tabView), ASYNC);
|
||||
|
||||
const detailsPage = new Page();
|
||||
helper.navigateWithHistory(() => detailsPage);
|
||||
TKUnit.assertEqual(topFrame.currentPage, detailsPage);
|
||||
|
||||
helper.goBack();
|
||||
TKUnit.assertEqual(topFrame.currentPage, tabViewPage);
|
||||
|
||||
for (let i = 0; i < itemCount; i++) {
|
||||
tabView.items[i].content.off('loaded');
|
||||
tabView.items[i].content.off('unloaded');
|
||||
}
|
||||
|
||||
helper.goBack();
|
||||
TKUnit.assertEqual(topFrame.currentPage, rootPage);
|
||||
|
||||
topFrame.currentPage.id = null;
|
||||
|
||||
TKUnit.arrayAssert(loadedEventsCount, [2, 2]);
|
||||
TKUnit.arrayAssert(unloadedEventsCount, [1, 1]);
|
||||
}
|
||||
|
||||
function _clickTheFirstButtonInTheListViewNatively(tabView: Tabs) {
|
||||
if (tabView.android) {
|
||||
const androidListView = <android.widget.ListView>tabView.items[0].content.nativeView;
|
||||
// var viewPager: android.support.v4.view.ViewPager = (<any>tabView)._viewPager;
|
||||
// var androidListView = <android.widget.ListView>viewPager.getChildAt(0);
|
||||
var stackLayout = <org.nativescript.widgets.StackLayout>androidListView.getChildAt(0);
|
||||
var button = <android.widget.Button>stackLayout.getChildAt(0);
|
||||
button.performClick();
|
||||
} else {
|
||||
const tableView = <UITableView>tabView.viewController.viewControllers[0].view.subviews[0];
|
||||
const cell = <UITableViewCell>tableView.cellForRowAtIndexPath(NSIndexPath.indexPathForItemInSection(0, 0));
|
||||
const btn = <UIButton>cell.contentView.subviews[0];
|
||||
btn.sendActionsForControlEvents(UIControlEvents.TouchUpInside);
|
||||
}
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
import * as TKUnit from '../../tk-unit';
|
||||
import { Page, Frame, Tabs, TabContentItem, TabStrip, TabStripItem, NavigationEntry, Application } from '@nativescript/core';
|
||||
|
||||
function waitUntilNavigatedToMaxTimeout(pages: Page[], action: Function) {
|
||||
const maxTimeout = 8;
|
||||
let completed = 0;
|
||||
function navigatedTo(args) {
|
||||
args.object.page.off('navigatedTo', navigatedTo);
|
||||
completed++;
|
||||
}
|
||||
|
||||
pages.forEach((page) => page.on('navigatedTo', navigatedTo));
|
||||
action();
|
||||
TKUnit.waitUntilReady(() => completed === pages.length, maxTimeout);
|
||||
}
|
||||
|
||||
function createPage(i: number) {
|
||||
const page = new Page();
|
||||
page.id = `Tab${i} Frame${i} Page${i}`;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
function createFrame(i: number, page: Page) {
|
||||
const frame = new Frame();
|
||||
frame.navigate(() => page);
|
||||
frame.id = `Tab${i} Frame${i}`;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
function createTabItem(i: number, frame: Frame) {
|
||||
const tabEntry = new TabContentItem();
|
||||
// tabEntry.title = "Tab " + i;
|
||||
tabEntry.content = frame;
|
||||
tabEntry['index'] = i;
|
||||
|
||||
return tabEntry;
|
||||
}
|
||||
|
||||
function createTabItemsWithFrames(count: number) {
|
||||
const items = [];
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
const page = createPage(i);
|
||||
const frame = createFrame(i, page);
|
||||
const tabItem = createTabItem(i, frame);
|
||||
|
||||
items.push({ page, frame, tabItem });
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
function createTabStrip(count: number): TabStrip {
|
||||
const items = new Array<TabStripItem>();
|
||||
for (let i = 0; i < count; i++) {
|
||||
let tabStripEntry = new TabStripItem();
|
||||
tabStripEntry.title = 'Tab ' + i;
|
||||
items.push(tabStripEntry);
|
||||
}
|
||||
|
||||
const tabStrip = new TabStrip();
|
||||
tabStrip.items = items;
|
||||
|
||||
return tabStrip;
|
||||
}
|
||||
|
||||
export function test_frame_topmost_matches_selectedIndex() {
|
||||
const items = createTabItemsWithFrames(3);
|
||||
const tabView = new Tabs();
|
||||
tabView.items = items.map((item) => item.tabItem);
|
||||
tabView.tabStrip = createTabStrip(3);
|
||||
|
||||
// iOS cannot preload tab items
|
||||
// Android preloads 1 tab item to the sides by default
|
||||
// set this to 0, so that both platforms behave the same.
|
||||
// tabView.androidOffscreenTabLimit = 0;
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => tabView,
|
||||
};
|
||||
|
||||
waitUntilNavigatedToMaxTimeout([items[0].page], () => Application.resetRootView(entry));
|
||||
TKUnit.assertEqual(Frame.topmost().id, 'Tab0 Frame0');
|
||||
|
||||
waitUntilNavigatedToMaxTimeout([items[1].page], () => (tabView.selectedIndex = 1));
|
||||
TKUnit.assertEqual(Frame.topmost().id, 'Tab1 Frame1');
|
||||
}
|
||||
|
||||
// TODO: _resetRootView doesn't work with TabView or Tabs with pre-loading. The fragments that are removed crash the app with missing reference.
|
||||
// export function test_preloading_one_to_the_side_on_index_change() {
|
||||
// let actualEventsRaised = [];
|
||||
|
||||
// function resetActualEventsRaised() {
|
||||
// for (var i = 0; i < actualEventsRaised.length; i++) {
|
||||
// actualEventsRaised[i] = [];
|
||||
// }
|
||||
// }
|
||||
|
||||
// function attachEventHandlers(i: number, item) {
|
||||
// actualEventsRaised.push([]);
|
||||
|
||||
// const page = item.page;
|
||||
// page.on(Page.loadedEvent, () => actualEventsRaised[i].push(`${page.id} loaded`));
|
||||
// page.on(Page.unloadedEvent, () => actualEventsRaised[i].push(`${page.id} unloaded`));
|
||||
// page.on(Page.navigatingToEvent, () => actualEventsRaised[i].push(`${page.id} navigatingTo`));
|
||||
// page.on(Page.navigatingFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatingFrom`));
|
||||
// page.on(Page.navigatedToEvent, () => actualEventsRaised[i].push(`${page.id} navigatedTo`));
|
||||
// page.on(Page.navigatedFromEvent, () => actualEventsRaised[i].push(`${page.id} navigatedFrom`));
|
||||
|
||||
// const frame = item.frame;
|
||||
// frame.on(Frame.loadedEvent, () => actualEventsRaised[i].push(`${frame.id} loaded`));
|
||||
// frame.on(Frame.unloadedEvent, () => actualEventsRaised[i].push(`${frame.id} unloaded`));
|
||||
// }
|
||||
|
||||
// const items = createTabItemsWithFrames(3);
|
||||
|
||||
// items.forEach((item, i) => {
|
||||
// attachEventHandlers(i, item);
|
||||
// });
|
||||
|
||||
// const tabView = new Tabs();
|
||||
// tabView.items = items.map(item => item.tabItem);
|
||||
// tabView.tabStrip = createTabStrip(3);
|
||||
|
||||
// const entry: NavigationEntry = {
|
||||
// create: () => tabView
|
||||
// };
|
||||
|
||||
// waitUntilNavigatedToMaxTimeout([items[0].page], () => Application.resetRootView(entry));
|
||||
|
||||
// const expectedEventsRaisedAfterTabCreated = [
|
||||
// [
|
||||
// "Tab0 Frame0 loaded",
|
||||
// "Tab0 Frame0 Page0 navigatingTo",
|
||||
// "Tab0 Frame0 Page0 loaded",
|
||||
// "Tab0 Frame0 Page0 navigatedTo",
|
||||
// ],
|
||||
// [],
|
||||
// []
|
||||
// ];
|
||||
|
||||
// TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterTabCreated);
|
||||
|
||||
// resetActualEventsRaised();
|
||||
// waitUntilNavigatedToMaxTimeout([items[2].page], () => tabView.selectedIndex = 2);
|
||||
|
||||
// const expectedEventsRaisedAfterSelectThirdTab = [
|
||||
// [
|
||||
// "Tab0 Frame0 Page0 unloaded",
|
||||
// "Tab0 Frame0 unloaded",
|
||||
// ],
|
||||
// [],
|
||||
// [
|
||||
// "Tab2 Frame2 loaded",
|
||||
// "Tab2 Frame2 Page2 navigatingTo",
|
||||
// "Tab2 Frame2 Page2 loaded",
|
||||
// "Tab2 Frame2 Page2 navigatedTo"
|
||||
// ]
|
||||
// ];
|
||||
|
||||
// TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterSelectThirdTab);
|
||||
|
||||
// resetActualEventsRaised();
|
||||
|
||||
// waitUntilTabViewReady(items[0].page, () => tabView.selectedIndex = 0);
|
||||
|
||||
// const expectedEventsRaisedAfterReturnToFirstTab = [
|
||||
// [
|
||||
// "Tab0 Frame0 Page0 loaded",
|
||||
// "Tab0 Frame0 loaded",
|
||||
// ],
|
||||
// [],
|
||||
// [
|
||||
// "Tab2 Frame2 Page2 unloaded",
|
||||
// "Tab2 Frame2 unloaded",
|
||||
// ]
|
||||
// ];
|
||||
|
||||
// TKUnit.assertDeepEqual(actualEventsRaised, expectedEventsRaisedAfterReturnToFirstTab);
|
||||
// }
|
||||
|
||||
export function tearDownModule() {
|
||||
const page = new Page();
|
||||
const frame = new Frame();
|
||||
frame.navigate(() => page);
|
||||
|
||||
const entry: NavigationEntry = {
|
||||
create: () => frame,
|
||||
};
|
||||
|
||||
waitUntilNavigatedToMaxTimeout([page], () => Application.resetRootView(entry));
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
import { BottomNavigation } from '@nativescript/core/ui/bottom-navigation';
|
||||
|
||||
export function getNativeTabCount(tabView: BottomNavigation): number {
|
||||
// there is no native tab content view implementation for Android Bottom Navigation
|
||||
return tabView.items.length;
|
||||
}
|
||||
|
||||
export function selectNativeTab(tabView: BottomNavigation, index: number): void {
|
||||
const bottomNavigationBar = <org.nativescript.widgets.BottomNavigationBar>(<any>tabView)._bottomNavigationBar;
|
||||
|
||||
if (bottomNavigationBar) {
|
||||
bottomNavigationBar.setSelectedPosition(index);
|
||||
}
|
||||
}
|
||||
|
||||
export function getNativeSelectedIndex(tabView: BottomNavigation): number {
|
||||
// there is no native tab content view implementation for Android Bottom Navigation
|
||||
return tabView.selectedIndex;
|
||||
}
|
||||
|
||||
export function getNativeFont(tabView: BottomNavigation): any {
|
||||
const tv: android.widget.TextView = (<org.nativescript.widgets.BottomNavigationBar>(<any>tabView)._bottomNavigationBar).getTextViewForItemAt(0);
|
||||
if (tv) {
|
||||
return {
|
||||
typeface: tv.getTypeface(),
|
||||
size: tv.getTextSize(),
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getOriginalFont(tabView: BottomNavigation): any {
|
||||
const tv: android.widget.TextView = (<org.nativescript.widgets.BottomNavigationBar>(<any>tabView)._bottomNavigationBar).getTextViewForItemAt(0);
|
||||
|
||||
return {
|
||||
typeface: tv.getTypeface(),
|
||||
size: tv.getTextSize(),
|
||||
};
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
//@private
|
||||
import { TabView } from '@nativescript/core/ui/tab-view';
|
||||
|
||||
export function getNativeTabCount(tabView: TabView): number;
|
||||
export function selectNativeTab(tabView: TabView, index: number): void;
|
||||
export function getNativeSelectedIndex(tabView: TabView): number;
|
||||
export function getNativeFont(tabView: TabView): any;
|
||||
export function getOriginalFont(tabView: TabView): any;
|
||||
@@ -1,44 +0,0 @@
|
||||
import { Tabs } from '@nativescript/core/ui/tabs';
|
||||
import { Font } from '@nativescript/core/ui/styling/font';
|
||||
|
||||
// TODO: Should we add getCount to UIPageViewController???
|
||||
export function getNativeTabCount(tabView: Tabs): number {
|
||||
if (!(<any>tabView).viewControllers) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (<any>tabView).viewControllers.length;
|
||||
}
|
||||
|
||||
// TODO: separate in another function with Tabs implementation - selectNativeTab()
|
||||
export function selectNativeTab(tabView: Tabs, index: number): void {
|
||||
const item = tabView.items[index];
|
||||
const controllers = NSMutableArray.alloc<UIViewController>().initWithCapacity(1);
|
||||
|
||||
let itemController = (<any>item).__controller;
|
||||
controllers.addObject(itemController);
|
||||
let navigationDirection = UIPageViewControllerNavigationDirection.Forward;
|
||||
tabView.viewController.setViewControllersDirectionAnimatedCompletion(controllers, navigationDirection, false, null);
|
||||
tabView.viewController.delegate.pageViewControllerDidFinishAnimatingPreviousViewControllersTransitionCompleted(tabView.viewController, true, null, true);
|
||||
}
|
||||
|
||||
// TODO: Should we add getNativeSelectedIndex to UIPageViewController???
|
||||
export function getNativeSelectedIndex(tabView: Tabs): number {
|
||||
return tabView.selectedIndex;
|
||||
}
|
||||
|
||||
export function getNativeFont(tabView: Tabs): UIFont {
|
||||
const tabBar = <UITabBar>tabView.viewController.tabBar;
|
||||
if (tabBar.items.count > 0) {
|
||||
const currentAttrs = tabBar.items[0].titleTextAttributesForState(UIControlState.Normal);
|
||||
if (currentAttrs) {
|
||||
return currentAttrs.objectForKey(NSFontAttributeName);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function getOriginalFont(tabView: Tabs): UIFont {
|
||||
return (tabView.style.fontInternal || Font.default).getUIFont(UIFont.systemFontOfSize(10));
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import { Image, Label, Builder, TabContentItem, Tabs, TabStrip, TabStripItem } from '@nativescript/core/ui';
|
||||
import * as TKUnit from '../../tk-unit';
|
||||
|
||||
export function test_lowercase_declaration() {
|
||||
const root = Builder.parse(`
|
||||
<tabs>
|
||||
<tab-strip id="tab-strip">
|
||||
<tab-strip-item id="tab-strip-item">
|
||||
<image src="res://icon" id="tab-strip-item-image" />
|
||||
<label text="test" id="tab-strip-item-label" />
|
||||
</tab-strip-item>
|
||||
</tab-strip>
|
||||
<tab-content-item id="tab-content-item">
|
||||
<label text="test" id="tab-content-item-label" />
|
||||
</tab-content-item>
|
||||
</tabs>
|
||||
`);
|
||||
|
||||
const tabStrip = root.getViewById('tab-strip');
|
||||
const tabStripItem = root.getViewById('tab-strip-item');
|
||||
const tabStripItemImage = root.getViewById('tab-strip-item-image');
|
||||
const tabStripItemLabel = root.getViewById('tab-strip-item-label');
|
||||
const tabContentItem = root.getViewById('tab-content-item');
|
||||
const tabContentItemLabel = root.getViewById('tab-content-item-label');
|
||||
|
||||
TKUnit.assert(root instanceof Tabs, 'Expected result: Tabs!; Actual result: ' + root);
|
||||
TKUnit.assert(tabStrip instanceof TabStrip, 'Expected result: TabStrip!; Actual result: ' + tabStrip);
|
||||
TKUnit.assert(tabStripItem instanceof TabStripItem, 'Expected result: TabStripItem!; Actual result: ' + tabStripItem);
|
||||
TKUnit.assert(tabStripItemImage instanceof Image, 'Expected result: Image!; Actual result: ' + tabStripItemImage);
|
||||
TKUnit.assert(tabStripItemLabel instanceof Label, 'Expected result: Label!; Actual result: ' + tabStripItemLabel);
|
||||
TKUnit.assert(tabContentItem instanceof TabContentItem, 'Expected result: TabContentItem!; Actual result: ' + tabContentItem);
|
||||
TKUnit.assert(tabContentItemLabel instanceof Label, 'Expected result: Label!; Actual result: ' + tabContentItemLabel);
|
||||
}
|
||||
@@ -1,350 +0,0 @@
|
||||
import { UITest } from '../../ui-test';
|
||||
import { Label } from '@nativescript/core/ui/label';
|
||||
import * as TKUnit from '../../tk-unit';
|
||||
import * as helper from '../../ui-helper';
|
||||
import * as tabViewTestsNative from './tabs-tests-native';
|
||||
|
||||
import { Tabs, TabContentItem, TabStrip, TabStripItem, SelectedIndexChangedEventData } from '@nativescript/core/ui/tabs';
|
||||
|
||||
export class TabsTest extends UITest<Tabs> {
|
||||
public create(): Tabs {
|
||||
var tabView = new Tabs();
|
||||
tabView.id = 'TabView';
|
||||
|
||||
return tabView;
|
||||
}
|
||||
|
||||
// public test_recycling() {
|
||||
// const setters = new Map<string, Array<any>>();
|
||||
// setters.set("items", this._createItems(3));
|
||||
// helper.nativeView_recycling_test(() => new BottomNavigation(), null, null, setters);
|
||||
// }
|
||||
|
||||
_createContentItems(count: number): Array<TabContentItem> {
|
||||
const items = new Array<TabContentItem>();
|
||||
for (let i = 0; i < count; i++) {
|
||||
const label = new Label();
|
||||
label.text = 'Tab ' + i;
|
||||
const tabEntry = new TabContentItem();
|
||||
tabEntry.content = label;
|
||||
items.push(tabEntry);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
_createTabStrip(count: number): TabStrip {
|
||||
const items = new Array<TabStripItem>();
|
||||
for (let i = 0; i < count; i++) {
|
||||
let tabStripEntry = new TabStripItem();
|
||||
tabStripEntry.title = 'Tab ' + i;
|
||||
items.push(tabStripEntry);
|
||||
}
|
||||
|
||||
const tabStrip = new TabStrip();
|
||||
tabStrip.items = items;
|
||||
|
||||
return tabStrip;
|
||||
}
|
||||
|
||||
public tearDown() {
|
||||
if (this.testView && this.testView.items) {
|
||||
this.testView.items.length = 0;
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
public waitUntilSelectedItemIsFullyLoaded(): boolean {
|
||||
const tabView = this.testView;
|
||||
if (!tabView.isLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const i = tabView.selectedIndex;
|
||||
if (i >= 0 && !tabView.items[i].isLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tabView.android) {
|
||||
const bottomNavigationBar = <org.nativescript.widgets.BottomNavigationBar>(<any>tabView)._bottomNavigationBar;
|
||||
if (bottomNavigationBar.getItemCount() === 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public test_when_created_items_are_undefined = function () {
|
||||
TKUnit.assertEqual(this.testView.items, undefined, 'Items should be undefined initally.');
|
||||
};
|
||||
|
||||
public test_when_created_selected_index_is_undefined = function () {
|
||||
TKUnit.assertEqual(this.testView.selectedIndex, -1, 'selectedIndex should be undefined initally.');
|
||||
};
|
||||
|
||||
// TODO: Do we need this test? The number of tabs is dynamic and isn't kept in the native implementation.
|
||||
// TODO: Maybe test if all native tabBarItems are created.
|
||||
public test_when_setting_items_to_non_empty_array_the_same_amount_of_native_tabs_is_created = function () {
|
||||
this.testView.items = this._createContentItems(5);
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
let expectedValue = this.testView.items.length;
|
||||
let actualValue = tabViewTestsNative.getNativeTabCount(this.testView);
|
||||
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'NativeItems not equal to JS items.');
|
||||
};
|
||||
|
||||
// TODO: Do we need this test? The number of tabs is dynamic and isn't kept in the native implementation.
|
||||
// TODO: Maybe test if all native tabBarItems are created.
|
||||
public test_when_setting_items_to_empty_array_zero_native_tabs_are_created = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = [];
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var expectedValue = tabView.items.length;
|
||||
var actualValue = tabViewTestsNative.getNativeTabCount(tabView);
|
||||
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'Should have 0 native tabs.');
|
||||
};
|
||||
|
||||
public test_selected_index_becomes_zero_when_items_bound_to_non_empty_array = function () {
|
||||
var tabView = this.testView;
|
||||
// var items = [];
|
||||
|
||||
// var StackLayout0 = new StackLayout();
|
||||
// var label0 = new Label();
|
||||
// label0.text = "Tab 0";
|
||||
// StackLayout0.addChild(label0);
|
||||
// var tabEntry0 = new TabContentItem();
|
||||
// // tabEntry0.title = "Tab 0";
|
||||
// tabEntry0.view = StackLayout0;
|
||||
// items.push(tabEntry0);
|
||||
|
||||
// var StackLayout1 = new StackLayout();
|
||||
// var label1 = new Label();
|
||||
// label1.text = "Tab 1";
|
||||
// StackLayout1.addChild(label1);
|
||||
// var tabEntry1 = new TabContentItem();
|
||||
// // tabEntry1.title = "Tab 1";
|
||||
// tabEntry1.view = StackLayout1;
|
||||
// items.push(tabEntry1);
|
||||
|
||||
tabView.items = this._createContentItems(5);
|
||||
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var expectedValue = 0;
|
||||
var actualValue = tabView.selectedIndex;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'When bound selectedIndex should be 0.');
|
||||
};
|
||||
|
||||
public test_selected_index_becomes_undefined_when_items_bound_to_empty_array = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(5);
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
tabView.selectedIndex = 4;
|
||||
|
||||
tabView.items = [];
|
||||
|
||||
var expectedValue = -1;
|
||||
var actualValue = tabView.selectedIndex;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'selectedIndex should be undefined.');
|
||||
};
|
||||
|
||||
public test_selected_index_becomes_undefined_when_items_set_to_undefined = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(5);
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
// tabView.selectedIndex = 4;
|
||||
|
||||
tabView.items = undefined;
|
||||
|
||||
var expectedValue = -1;
|
||||
var actualValue = tabView.selectedIndex;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'selectedIndex should be undefined.');
|
||||
};
|
||||
|
||||
public test_selected_index_becomes_undefined_when_items_set_to_null = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(5);
|
||||
tabView.selectedIndex = 4;
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
tabView.items = null;
|
||||
|
||||
var expectedValue = -1;
|
||||
var actualValue = tabView.selectedIndex;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'selectedIndex should be undefined.');
|
||||
};
|
||||
|
||||
public test_items_is_resolved_correctly_if_set_before_view_is_loaded = function () {
|
||||
var tabView = this.testView;
|
||||
var expectedValue = 5;
|
||||
tabView.items = this._createContentItems(expectedValue);
|
||||
tabView.selectedIndex = 4;
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var actualValue = tabView.items.length;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'items.length should be 5');
|
||||
};
|
||||
|
||||
public test_selected_index_is_resolved_correctly_if_set_before_view_is_loaded = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(5);
|
||||
var expectedValue = 4;
|
||||
tabView.selectedIndex = expectedValue;
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var actualValue = tabView.selectedIndex;
|
||||
TKUnit.assertEqual(actualValue, expectedValue, 'selectedIndex');
|
||||
};
|
||||
|
||||
public test_binding_to_tabitem_with_undefined_view_should_throw = function () {
|
||||
var tabView = this.testView;
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
TKUnit.assertThrows(() => {
|
||||
let item = new TabContentItem();
|
||||
// item.title = "Tab 0";
|
||||
item.content = undefined;
|
||||
tabView.items = [item];
|
||||
}, 'Binding TabNavigation to a TabItem with undefined view should throw.');
|
||||
};
|
||||
|
||||
public test_binding_to_tabitem_with_null_view_should_throw = function () {
|
||||
var tabView = this.testView;
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
TKUnit.assertThrows(() => {
|
||||
let item = new TabContentItem();
|
||||
// item.title = "Tab 0";
|
||||
item.content = null;
|
||||
tabView.items = [item];
|
||||
}, 'Binding TabNavigation to a TabItem with null view should throw.');
|
||||
};
|
||||
|
||||
// TODO: times out
|
||||
// public test_when_selecting_tab_natively_selectedIndex_is_updated_properly = function () {
|
||||
// var tabView = this.testView;
|
||||
// tabView.items = this._createContentItems(2);
|
||||
// this.waitUntilTestElementIsLoaded();
|
||||
|
||||
// var expectedValue = 1;
|
||||
// tabViewTestsNative.selectNativeTab(tabView, expectedValue);
|
||||
// TKUnit.waitUntilReady(function () {
|
||||
// return tabView.selectedIndex === expectedValue;
|
||||
// }, helper.ASYNC);
|
||||
|
||||
// var actualValue = tabView.selectedIndex;
|
||||
// TKUnit.assertEqual(actualValue, expectedValue, "selectedIndex");
|
||||
|
||||
// }
|
||||
|
||||
// TODO: times out
|
||||
// public test_when_selecting_tab_natively_selectedIndexChangedEvent_is_raised = function () {
|
||||
// var tabView = this.testView;
|
||||
// tabView.items = this._createContentItems(5);
|
||||
// this.waitUntilTestElementIsLoaded();
|
||||
|
||||
// var expectedOldIndex = 3;
|
||||
// var expectedNewIndex = 4;
|
||||
// var actualOldIndex;
|
||||
// var actualNewIndex;
|
||||
|
||||
// tabViewTestsNative.selectNativeTab(tabView, expectedOldIndex);
|
||||
// TKUnit.waitUntilReady(function () {
|
||||
// return tabView.selectedIndex === expectedOldIndex;
|
||||
// }, 10);
|
||||
|
||||
// tabView.on(Tabs.selectedIndexChangedEvent, (args: SelectedIndexChangedEventData) => {
|
||||
// actualOldIndex = args.oldIndex;
|
||||
// actualNewIndex = args.newIndex;
|
||||
// });
|
||||
|
||||
// tabViewTestsNative.selectNativeTab(tabView, expectedNewIndex);
|
||||
// TKUnit.waitUntilReady(function () {
|
||||
// return tabView.selectedIndex === expectedNewIndex;
|
||||
// }, helper.ASYNC);
|
||||
|
||||
// TKUnit.assertEqual(actualOldIndex, expectedOldIndex, "expectedOldIndex");
|
||||
// TKUnit.assertEqual(actualNewIndex, expectedNewIndex, "expectedNewIndex");
|
||||
// }
|
||||
|
||||
// TODO: Do we need this test?
|
||||
public test_when_setting_selectedIndex_programatically_selectedIndexChangedEvent_is_raised = function () {
|
||||
var tabView = this.testView;
|
||||
tabView.items = this._createContentItems(5);
|
||||
this.waitUntilTestElementIsLoaded();
|
||||
|
||||
var expectedOldIndex = 2;
|
||||
var expectedNewIndex = 4;
|
||||
var actualOldIndex;
|
||||
var actualNewIndex;
|
||||
|
||||
tabView.selectedIndex = expectedOldIndex;
|
||||
TKUnit.waitUntilReady(function () {
|
||||
return tabViewTestsNative.getNativeSelectedIndex(tabView) === expectedOldIndex;
|
||||
}, helper.ASYNC);
|
||||
|
||||
tabView.on(Tabs.selectedIndexChangedEvent, (args: SelectedIndexChangedEventData) => {
|
||||
actualOldIndex = args.oldIndex;
|
||||
actualNewIndex = args.newIndex;
|
||||
TKUnit.assertEqual(args.object, tabView, 'args.object should be TabView');
|
||||
});
|
||||
|
||||
tabView.selectedIndex = expectedNewIndex;
|
||||
TKUnit.waitUntilReady(function () {
|
||||
return tabViewTestsNative.getNativeSelectedIndex(tabView) === expectedNewIndex;
|
||||
}, helper.ASYNC);
|
||||
|
||||
TKUnit.assertEqual(actualOldIndex, expectedOldIndex, 'expectedOldIndex');
|
||||
TKUnit.assertEqual(actualNewIndex, expectedNewIndex, 'expectedNewIndex');
|
||||
};
|
||||
|
||||
//TODO: Font styling is not ready
|
||||
// public test_font_is_reapplied_when_tab_items_change = function () {
|
||||
// const assertFontsAreEqual = (actual: any, expected: any, message?: string) => {
|
||||
// if (this.testView.ios) {
|
||||
// TKUnit.assertEqual(actual, expected, message);
|
||||
// } else {
|
||||
// TKUnit.assertEqual(actual.typeface, expected.typeface, `${message} [typeface]`);
|
||||
// TKUnit.assertEqual(actual.size, expected.size, `${message} [size]`);
|
||||
// }
|
||||
// }
|
||||
|
||||
// this.testView.items = this._createContentItems(1);
|
||||
// this.testView.tabStrip = this._createTabStrip(1);
|
||||
// this.waitUntilSelectedItemIsFullyLoaded();
|
||||
|
||||
// const originalFont = tabViewTestsNative.getOriginalFont(this.testView);
|
||||
// TKUnit.assertNotNull(originalFont, "Original Font should be applied");
|
||||
|
||||
// this.testView.style.font = "20 Pacifico";
|
||||
// let nativeFont = tabViewTestsNative.getNativeFont(this.testView);
|
||||
// TKUnit.assertNotNull(nativeFont, "Native Font should not be null");
|
||||
// TKUnit.assertNotEqual(originalFont, nativeFont, "Font should be changed");
|
||||
|
||||
// this.testView.items = this._createContentItems(2);
|
||||
// this.testView.tabStrip = this._createTabStrip(2);
|
||||
// this.waitUntilSelectedItemIsFullyLoaded();
|
||||
// assertFontsAreEqual(tabViewTestsNative.getNativeFont(this.testView), nativeFont, "Font must be 20 Pacifico after rebinding items.");
|
||||
|
||||
// this.testView.style.font = "bold 12 monospace";
|
||||
// nativeFont = tabViewTestsNative.getNativeFont(this.testView);
|
||||
|
||||
// this.testView.items = this._createContentItems(3);
|
||||
// this.testView.tabStrip = this._createTabStrip(3);
|
||||
// this.waitUntilSelectedItemIsFullyLoaded();
|
||||
// assertFontsAreEqual(tabViewTestsNative.getNativeFont(this.testView), nativeFont, "Font must be bold 12 monospace after rebinding items.");
|
||||
|
||||
// this.testView.style.font = unsetValue;
|
||||
// assertFontsAreEqual(tabViewTestsNative.getNativeFont(this.testView), originalFont, "Font must be the original one after resetting the style.");
|
||||
// }
|
||||
}
|
||||
|
||||
export function createTestCase(): TabsTest {
|
||||
return new TabsTest();
|
||||
}
|
||||
Reference in New Issue
Block a user