Disable recycling, refactoring & fixes (#4705)

* Added tests for native view recycling
Disabled android native view recycling
Move toString from view-common to view-base
Fix crash on application restore and navigation back on API26
Added setAsRootView method
Added missing logo into perf-tests/recycling app

* additional fix for image-source-tests. ios is case sensitive.

* Add @private to some internal properties
Fix where padding is not respected when background is reset.
This commit is contained in:
Hristo Hristov
2017-08-17 09:15:35 +03:00
committed by GitHub
parent 2701ea3c1e
commit bba7a82bdf
18 changed files with 532 additions and 251 deletions

View File

@@ -6,7 +6,7 @@ export function imageSourceFromAsset(imageAsset){
let source = new imageSource.ImageSource();
source.fromAsset(imageAsset).then((source) => {
let folder = fs.knownFolders.documents().path;
let fileName = "Test.png"
let fileName = "test.png"
let path = fs.path.join(folder, fileName);
let saved = source.saveToFile(path, "png");
if(saved){

View File

@@ -56,7 +56,7 @@ export function testSaveToFile() {
// >> imagesource-save-to
var img = imageSource.fromFile(imagePath);
var folder = fs.knownFolders.documents();
var path = fs.path.join(folder.path, "Test.png");
var path = fs.path.join(folder.path, "test.png");
var saved = img.saveToFile(path, "png");
// << imagesource-save-to
TKUnit.assert(saved, "Image not saved to file");
@@ -66,16 +66,16 @@ export function testSaveToFile() {
export function testFromFile() {
// >> imagesource-load-local
var folder = fs.knownFolders.documents();
var path = fs.path.join(folder.path, "Test.png");
var path = fs.path.join(folder.path, "test.png");
var img = imageSource.fromFile(path);
// << imagesource-load-local
TKUnit.assert(img.height > 0, "image.fromResource failed");
// remove the image from the file system
var file = folder.getFile("Test.png");
var file = folder.getFile("test.png");
file.remove();
TKUnit.assert(!fs.File.exists(path), "Test.png not removed");
TKUnit.assert(!fs.File.exists(path), "test.png not removed");
}
export function testNativeFields() {

View File

@@ -248,63 +248,65 @@ let cssSetters: Map<string, any>;
let defaultNativeGetters: Map<string, (view) => any>;
export function nativeView_recycling_test(createNew: () => View, createLayout?: () => LayoutBase, nativeGetters?: Map<string, (view) => any>, customSetters?: Map<string, any>) {
if (isIOS) {
// recycling not implemented yet.
return;
}
return;
setupSetters();
const page = getClearCurrentPage();
let layout: LayoutBase = new FlexboxLayout();
if (createLayout) {
// This is done on purpose. We need the constructor of Flexbox
// to run otherwise some module fileds stays uninitialized.
layout = createLayout();
}
// if (isIOS) {
// // recycling not implemented yet.
// return;
// }
page.content = layout;
// setupSetters();
// const page = getClearCurrentPage();
// let layout: LayoutBase = new FlexboxLayout();
// if (createLayout) {
// // This is done on purpose. We need the constructor of Flexbox
// // to run otherwise some module fileds stays uninitialized.
// layout = createLayout();
// }
const first = createNew();
const test = createNew();
// page.content = layout;
// Make sure we are not reusing a native views.
first.recycleNativeView = "never";
test.recycleNativeView = "never";
// const first = createNew();
// const test = createNew();
page.content = layout;
// // Make sure we are not reusing a native views.
// first.recycleNativeView = "never";
// test.recycleNativeView = "never";
layout.addChild(test);
// page.content = layout;
setValue(test.style, cssSetters);
setValue(test, setters, customSetters);
// Needed so we can reset formattedText
test["secure"] = false;
// layout.addChild(test);
const nativeView = test.nativeViewProtected;
// Mark so we reuse the native views.
test.recycleNativeView = "always";
layout.removeChild(test);
const newer = createNew();
newer.recycleNativeView = "always";
layout.addChild(newer);
layout.addChild(first);
// setValue(test.style, cssSetters);
// setValue(test, setters, customSetters);
// // Needed so we can reset formattedText
// test["secure"] = false;
if (first.typeName !== "SearchBar") {
// There are way too many differences in native methods for search-bar.
// There are too many methods that just throw for newly created views in API lvl 19 and 17
if (sdkVersion < 21) {
TKUnit.waitUntilReady(() => layout.isLayoutValid);
}
// const nativeView = test.nativeViewProtected;
// // Mark so we reuse the native views.
// test.recycleNativeView = "always";
// layout.removeChild(test);
// const newer = createNew();
// newer.recycleNativeView = "always";
// layout.addChild(newer);
// layout.addChild(first);
compareUsingReflection(newer, first);
}
// if (first.typeName !== "SearchBar") {
// // There are way too many differences in native methods for search-bar.
// // There are too many methods that just throw for newly created views in API lvl 19 and 17
// if (sdkVersion < 21) {
// TKUnit.waitUntilReady(() => layout.isLayoutValid);
// }
TKUnit.assertEqual(newer.nativeViewProtected, nativeView, "nativeView not reused.");
checkDefaults(newer, first, props, nativeGetters || defaultNativeGetters);
checkDefaults(newer, first, styleProps, nativeGetters || defaultNativeGetters);
// compareUsingReflection(newer, first);
// }
layout.removeChild(newer);
layout.removeChild(first);
// TKUnit.assertEqual(newer.nativeViewProtected, nativeView, "nativeView not reused.");
// checkDefaults(newer, first, props, nativeGetters || defaultNativeGetters);
// checkDefaults(newer, first, styleProps, nativeGetters || defaultNativeGetters);
// layout.removeChild(newer);
// layout.removeChild(first);
}
function compareUsingReflection(recycledNativeView: View, newNativeView: View): void {

View File

@@ -601,8 +601,12 @@ export function test_NativeSetter_called_when_add_and_remove_and_recycled() {
firstView.removeChild(secondView);
// we don't recycle nativeViews on iOS yet so reset is not called.
TKUnit.assertEqual(secondView.cssPropCounter, isIOS ? 2 : 3, "7");
TKUnit.assertEqual(secondView.viewPropCounter, isIOS ? 2 : 3, "8");
// Recycling disabled for android too
// TKUnit.assertEqual(secondView.cssPropCounter, isIOS ? 2 : 3, "7");
// TKUnit.assertEqual(secondView.viewPropCounter, isIOS ? 2 : 3, "8");
TKUnit.assertEqual(secondView.cssPropCounter, 2, "7");
TKUnit.assertEqual(secondView.viewPropCounter,2, "8");
});
};

View File

@@ -2,9 +2,9 @@
import * as commonTests from "./view-tests-common";
import * as helper from "../../ui/helper";
import * as view from "tns-core-modules/ui/core/view";
import * as button from "tns-core-modules/ui/button";
import { Button } from "tns-core-modules/ui/button";
import * as types from "tns-core-modules/utils/types";
import * as stack from "tns-core-modules/ui/layouts/stack-layout";
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";
@@ -14,6 +14,101 @@ 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);
@@ -38,8 +133,8 @@ export const test_event_setupUI_IsRaised_WhenAttached_Dynamically = function ()
const listener = new Listener("_setupUI");
trace.addEventListener(listener);
const newButton = new button.Button();
(<stack.StackLayout>views[1]).addChild(newButton);
const newButton = new Button();
(<StackLayout>views[1]).addChild(newButton);
TKUnit.assertEqual(listener.receivedEvents.length, 1);
TKUnit.assertEqual(listener.receivedEvents[0].name, "_setupUI");
@@ -75,8 +170,8 @@ export const test_event_onContextChanged_IsRaised_WhenAttached_Dynamically = fun
const listener = new Listener("_onContextChanged");
trace.addEventListener(listener);
const newButton = new button.Button();
(<stack.StackLayout>views[1]).addChild(newButton);
const newButton = new Button();
(<StackLayout>views[1]).addChild(newButton);
TKUnit.assertEqual(listener.receivedEvents.length, 1);
TKUnit.assertEqual(listener.receivedEvents[0].name, "_onContextChanged");
@@ -125,7 +220,7 @@ export const test_event_tearDownUI_IsRaised_WhenRemoved_Dynamically = function (
trace.addEventListener(listener);
// remove the button from the layout
(<stack.StackLayout>views[1]).removeChild(views[2]);
(<StackLayout>views[1]).removeChild(views[2]);
TKUnit.assertEqual(listener.receivedEvents.length, 1);
TKUnit.assertEqual(listener.receivedEvents[0].name, "_tearDownUI");
@@ -142,8 +237,8 @@ export const test_events_tearDownUIAndRemovedFromNativeVisualTree_AreRaised_When
let removeFromNativeVisualTreeListener = new Listener("_removeViewFromNativeVisualTree");
let page = frame.topmost().currentPage;
let stackLayout = new stack.StackLayout();
let btn = new button.Button();
let stackLayout = new StackLayout();
let btn = new Button();
stackLayout.addChild(btn);
page.content = stackLayout;
@@ -174,11 +269,11 @@ export const test_events_tearDownUIAndRemovedFromNativeVisualTree_AreRaised_When
export const test_cachedProperties_Applied_WhenNativeWidged_IsCreated = function () {
const test = function (views: Array<view.View>) {
const newButton = new button.Button();
const newButton = new Button();
newButton.text = "Test Button";
TKUnit.assert(types.isUndefined(newButton.android));
(<stack.StackLayout>views[1]).addChild(newButton);
(<StackLayout>views[1]).addChild(newButton);
TKUnit.assert(types.isDefined(newButton.android));
// TODO: There is currently an issue with the getText conversion to JavaScript string
@@ -190,9 +285,9 @@ export const test_cachedProperties_Applied_WhenNativeWidged_IsCreated = function
export function test_automation_text_set_to_native() {
const test = function (views: Array<view.View>) {
const newButton = new button.Button();
const newButton = new Button();
newButton.automationText = "Button1";
(<stack.StackLayout>views[1]).addChild(newButton);
(<StackLayout>views[1]).addChild(newButton);
TKUnit.assertEqual((<android.widget.Button>newButton.android).getContentDescription(), "Button1", "contentDescription not set to native view.");
};
@@ -234,9 +329,9 @@ class Listener implements trace.EventListener {
export const test_StylePropertiesDefaultValuesCache = function () {
const testValue = 35;
const test = function (views: [view.View, stack.StackLayout, button.Button, view.View]) {
const test = function (views: [view.View, StackLayout, Button, view.View]) {
const testLabel = new labelModule.Label();
const testButton = new button.Button();
const testButton = new Button();
const stack = views[1];