Files
NativeScript/tests/app/ui/view/view-tests.android.ts

401 lines
15 KiB
TypeScript

import * as TKUnit from "../../TKUnit";
import * as commonTests from "./view-tests-common";
import * as helper from "../../ui/helper";
import * as view from "tns-core-modules/ui/core/view";
import { Button } from "tns-core-modules/ui/button";
import * as types from "tns-core-modules/utils/types";
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout";
import * as labelModule from "tns-core-modules/ui/label";
import * as frame from "tns-core-modules/ui/frame";
import * as trace from "tns-core-modules/trace";
import { Color } from "tns-core-modules/color";
// enable the trace, it is disabled by default
trace.enable();
global.moduleMerge(commonTests, exports);
// function setup(): StackLayout {
// const page = helper.getClearCurrentPage();
// const stack = new StackLayout();
// page.content = stack;
// return stack;
// }
// export function test_recycle_native_view_never() {
// const stack = setup();
// const btn = new Button();
// btn.recycleNativeView = 'never';
// stack.addChild(btn);
// TKUnit.assertNotNull(btn.nativeViewProtected);
// const oldNativeView = btn.nativeViewProtected;
// stack.removeChild(btn);
// stack.addChild(btn);
// const newNativeView = btn.nativeViewProtected;
// TKUnit.assertNotEqual(oldNativeView, newNativeView);
// }
// export function test_recycle_native_view_always() {
// const stack = setup();
// const btn = new Button();
// btn.recycleNativeView = 'always';
// stack.addChild(btn);
// TKUnit.assertNotNull(btn.nativeViewProtected);
// const oldNativeView = btn.nativeViewProtected;
// stack.removeChild(btn);
// stack.addChild(btn);
// const newNativeView = btn.nativeViewProtected;
// TKUnit.assertEqual(oldNativeView, newNativeView);
// }
// export function test_recycle_native_view_auto_access_nativeView() {
// const stack = setup();
// const btn = new Button();
// btn.recycleNativeView = 'auto';
// stack.addChild(btn);
// TKUnit.assertNotNull(btn.nativeView);
// const oldNativeView = btn.nativeViewProtected;
// stack.removeChild(btn);
// stack.addChild(btn);
// const newNativeView = btn.nativeViewProtected;
// TKUnit.assertNotEqual(oldNativeView, newNativeView);
// }
// export function test_recycle_native_view_auto_access_android() {
// const stack = setup();
// const btn = new Button();
// btn.recycleNativeView = 'auto';
// stack.addChild(btn);
// TKUnit.assertNotNull(btn.android);
// const oldNativeView = btn.nativeViewProtected;
// stack.removeChild(btn);
// stack.addChild(btn);
// const newNativeView = btn.nativeViewProtected;
// TKUnit.assertNotEqual(oldNativeView, newNativeView);
// }
// export function test_recycle_property_counter_few_properties() {
// const stack = setup();
// const btn = new Button();
// btn.text = "text";
// btn.recycleNativeView = 'auto';
// stack.addChild(btn);
// TKUnit.assertNotNull(btn.nativeViewProtected);
// const oldNativeView = btn.nativeViewProtected;
// stack.removeChild(btn);
// stack.addChild(btn);
// const newNativeView = btn.nativeViewProtected;
// TKUnit.assertEqual(oldNativeView, newNativeView);
// }
// export function test_recycle_property_counter_more_properties() {
// const stack = setup();
// const btn = new Button();
// btn.recyclePropertyCounter = 1;
// btn.recycleNativeView = 'auto';
// btn.text = "text";
// btn.style.margin = "20";
// stack.addChild(btn);
// TKUnit.assertNotNull(btn.nativeViewProtected);
// const oldNativeView = btn.nativeViewProtected;
// stack.removeChild(btn);
// stack.addChild(btn);
// const newNativeView = btn.nativeViewProtected;
// TKUnit.assertNotEqual(oldNativeView, newNativeView);
// }
export const test_event_setupUI_IsRaised = function () {
const listener = new Listener("_setupUI");
trace.addEventListener(listener);
const test = function (views: Array<view.View>) {
// 2 setupUI calls: stack, button
TKUnit.assertEqual(listener.receivedEvents.length, 2, "setupUI calls");
for (let i = 0; i < listener.receivedEvents.length; i++) {
TKUnit.assertEqual(listener.receivedEvents[i].sender, views[i + 1]); // 0 is Page, so start with +1.
TKUnit.assertEqual(listener.receivedEvents[i].name, "_setupUI");
}
};
helper.do_PageTest_WithStackLayout_AndButton(test);
trace.removeEventListener(listener);
};
export const test_event_setupUI_IsRaised_WhenAttached_Dynamically = function () {
const test = function (views: Array<view.View>) {
// add new button to the visual tree and ensure its _setupUI event
const listener = new Listener("_setupUI");
trace.addEventListener(listener);
const newButton = new Button();
(<StackLayout>views[1]).addChild(newButton);
TKUnit.assertEqual(listener.receivedEvents.length, 1);
TKUnit.assertEqual(listener.receivedEvents[0].name, "_setupUI");
TKUnit.assertEqual(listener.receivedEvents[0].sender, newButton);
trace.removeEventListener(listener);
};
helper.do_PageTest_WithStackLayout_AndButton(test);
};
export const test_event_onContextChanged_IsRaised_WhenAttached = function () {
const listener = new Listener("_onContextChanged");
trace.addEventListener(listener);
const test = function (views: Array<view.View>) {
// 2 onContextChanged calls: stack, button
TKUnit.assertEqual(listener.receivedEvents.length, 2, "onContextChanged calls");
for (let i = 0; i < listener.receivedEvents.length; i++) {
TKUnit.assertEqual(listener.receivedEvents[i].sender, views[i + 1]); // 0 is Page, so start with +1.
TKUnit.assertEqual(listener.receivedEvents[i].name, "_onContextChanged");
}
};
helper.do_PageTest_WithStackLayout_AndButton(test);
trace.removeEventListener(listener);
};
export const test_event_onContextChanged_IsRaised_WhenAttached_Dynamically = function () {
const test = function (views: Array<view.View>) {
// add new button to the visual tree and ensure its _onContextChanged event
const listener = new Listener("_onContextChanged");
trace.addEventListener(listener);
const newButton = new Button();
(<StackLayout>views[1]).addChild(newButton);
TKUnit.assertEqual(listener.receivedEvents.length, 1);
TKUnit.assertEqual(listener.receivedEvents[0].name, "_onContextChanged");
TKUnit.assertEqual(listener.receivedEvents[0].sender, newButton);
trace.removeEventListener(listener);
};
helper.do_PageTest_WithStackLayout_AndButton(test);
};
export const test_event_tearDownUI_IsRaised = function () {
let cachedViews: Array<view.View>;
let listener: Listener;
const test = function (views: Array<view.View>) {
cachedViews = views;
// once the above method completes goBack on the current frame is called which will detach the tested views
listener = new Listener("_tearDownUI");
trace.addEventListener(listener);
};
helper.do_PageTest_WithStackLayout_AndButton(test);
// 2 detached calls: page, stack, button, actionBar
TKUnit.assertEqual(listener.receivedEvents.length, 2, "tearDownUI calls");
// _tearDownUI event is propagated to nested children first
for (let i = 0, j = listener.receivedEvents.length - 1; i < listener.receivedEvents.length; i++ , j--) {
// check the sender and remove
const index = cachedViews.indexOf(<view.View>listener.receivedEvents[i].sender);
TKUnit.assert(index >= 0, "_tearDownUI called for unknown sender");
cachedViews.splice(index, 1);
TKUnit.assertEqual(listener.receivedEvents[i].name, "_tearDownUI");
}
trace.removeEventListener(listener);
};
export const test_event_tearDownUI_IsRaised_WhenRemoved_Dynamically = function () {
const test = function (views: Array<view.View>) {
// add new button to the visual tree and ensure its _tearDownUI event
const listener = new Listener("_tearDownUI");
trace.addEventListener(listener);
// remove the button from the layout
(<StackLayout>views[1]).removeChild(views[2]);
TKUnit.assertEqual(listener.receivedEvents.length, 1);
TKUnit.assertEqual(listener.receivedEvents[0].name, "_tearDownUI");
TKUnit.assertEqual(listener.receivedEvents[0].sender, views[2]);
trace.removeEventListener(listener);
};
helper.do_PageTest_WithStackLayout_AndButton(test);
};
export const test_events_tearDownUIAndRemovedFromNativeVisualTree_AreRaised_WhenNavigateBack = function () {
let tearDownUIListener = new Listener("_tearDownUI");
let removeFromNativeVisualTreeListener = new Listener("_removeViewFromNativeVisualTree");
let page = frame.topmost().currentPage;
let stackLayout = new StackLayout();
let btn = new Button();
stackLayout.addChild(btn);
page.content = stackLayout;
trace.addEventListener(tearDownUIListener);
trace.addEventListener(removeFromNativeVisualTreeListener);
page.content = null;
// 2 tearDownUI calls: stack, button
TKUnit.assertEqual(tearDownUIListener.receivedEvents.length, 2, "tearDownUI calls");
TKUnit.assertEqual(tearDownUIListener.receivedEvents[0].name, "_tearDownUI");
TKUnit.assertEqual(tearDownUIListener.receivedEvents[0].sender, btn); // Button
TKUnit.assertEqual(tearDownUIListener.receivedEvents[1].sender, stackLayout); // stackLayout
// this is an event fired from CustomLayoutView when a child is removed from the native visual tree
// therefore this event is fired for StackLayout and Button (which is inside StackLayout).
TKUnit.assertEqual(removeFromNativeVisualTreeListener.receivedEvents.length, 2);
TKUnit.assertEqual(removeFromNativeVisualTreeListener.receivedEvents[0].name, "_removeViewFromNativeVisualTree");
TKUnit.assertEqual(removeFromNativeVisualTreeListener.receivedEvents[0].sender, btn);
TKUnit.assertEqual(removeFromNativeVisualTreeListener.receivedEvents[1].name, "_removeViewFromNativeVisualTree");
TKUnit.assertEqual(removeFromNativeVisualTreeListener.receivedEvents[1].sender, stackLayout);
trace.removeEventListener(tearDownUIListener);
trace.removeEventListener(removeFromNativeVisualTreeListener);
};
export const test_cachedProperties_Applied_WhenNativeWidged_IsCreated = function () {
const test = function (views: Array<view.View>) {
const newButton = new Button();
newButton.text = "Test Button";
TKUnit.assert(types.isUndefined(newButton.android));
(<StackLayout>views[1]).addChild(newButton);
TKUnit.assert(types.isDefined(newButton.android));
// TODO: There is currently an issue with the getText conversion to JavaScript string
TKUnit.assertEqual(newButton.android.getText(), "Test Button");
};
helper.do_PageTest_WithStackLayout_AndButton(test);
};
export function test_automation_text_set_to_native() {
const test = function (views: Array<view.View>) {
const newButton = new Button();
newButton.automationText = "Button1";
(<StackLayout>views[1]).addChild(newButton);
TKUnit.assertEqual((<android.widget.Button>newButton.android).getContentDescription(), "Button1", "contentDescription not set to native view.");
};
helper.do_PageTest_WithStackLayout_AndButton(test);
}
export const test_event_onContextChanged_IsNotRaised_WhenAttachedToSameContext = function () {
const test = function (views: Array<view.View>) {
const listener = new Listener("_onContextChanged");
trace.addEventListener(listener);
views[2]._setupUI(views[0]._context);
TKUnit.assertEqual(listener.receivedEvents.length, 0, "listener.receivedEvents.length");
trace.removeEventListener(listener);
};
helper.do_PageTest_WithStackLayout_AndButton(test);
};
class Listener implements trace.EventListener {
public filter: string;
public receivedEvents: Array<{ sender: Object; name: string }> = [];
constructor(filter: string) {
this.filter = filter;
}
public on(object: Object, name: string) {
this.receivedEvents.push({ sender: object, name: name });
}
public reset() {
this.receivedEvents = [];
}
}
export const test_StylePropertiesDefaultValuesCache = function () {
const testValue = 35;
const test = function (views: [view.View, StackLayout, Button, view.View]) {
const testLabel = new labelModule.Label();
const testButton = new Button();
const stack = views[1];
stack.addChild(testLabel);
stack.addChild(testButton);
const defaultLabelFontSize = (<android.widget.TextView>(testLabel.android)).getTextSize();
const defaultButtonFontSize = (<android.widget.Button>(testButton.android)).getTextSize();
testLabel.style.fontSize = testValue;
testButton.style.fontSize = testValue;
let actualLabelTextSize = (<android.widget.TextView>(testLabel.android)).getTextSize();
let actualButtonTextSize = (<android.widget.Button>(testButton.android)).getTextSize();
TKUnit.assert(actualLabelTextSize !== defaultLabelFontSize, "Label text size should be different from default!");
TKUnit.assert(actualButtonTextSize !== defaultButtonFontSize, "Button text size should be different from default!");
testLabel.style.fontSize = view.unsetValue;
testButton.style.fontSize = view.unsetValue;
actualLabelTextSize = (<android.widget.TextView>(testLabel.android)).getTextSize();
actualButtonTextSize = (<android.widget.Button>(testButton.android)).getTextSize();
TKUnit.assertEqual(actualLabelTextSize, defaultLabelFontSize, "Label text size should be default!");
TKUnit.assertEqual(actualButtonTextSize, defaultButtonFontSize, "Button text size should be default!");
};
helper.do_PageTest_WithStackLayout_AndButton(test);
};
export function getUniformNativeBorderWidth(v: view.View): number {
const bkg = <org.nativescript.widgets.BorderDrawable>v.android.getBackground();
return bkg ? bkg.getUniformBorderWidth() : 0;
}
export function checkUniformNativeBorderColor(v: view.View): boolean {
const bkg = <org.nativescript.widgets.BorderDrawable>(<android.view.View>v.android).getBackground();
return bkg && bkg.getUniformBorderColor() === (<Color>v.borderColor).android;
}
export function getUniformNativeCornerRadius(v: view.View): number {
const bkg = <org.nativescript.widgets.BorderDrawable>v.android.getBackground();
return bkg ? bkg.getUniformBorderRadius() : 0;
}
export function checkNativeBackgroundColor(v: view.View): boolean {
const bkg = <org.nativescript.widgets.BorderDrawable>(<android.view.View>v.android).getBackground();
return v.backgroundColor && bkg && bkg.getBackgroundColor() === (<Color>v.backgroundColor).android;
}
export function checkNativeBackgroundImage(v: view.View): boolean {
const bkg = <org.nativescript.widgets.BorderDrawable>(<android.view.View>v.android).getBackground();
return bkg && !types.isNullOrUndefined(bkg.getBackgroundImage());
}
let SDK: number;
function getSDK() {
if (!SDK) {
SDK = android.os.Build.VERSION.SDK_INT;
}
return SDK;
}