diff --git a/apps/tests/ui/button/button-tests.ts b/apps/tests/ui/button/button-tests.ts index b86f57d32..f626ba0fc 100644 --- a/apps/tests/ui/button/button-tests.ts +++ b/apps/tests/ui/button/button-tests.ts @@ -81,10 +81,10 @@ export var testNativeBackgroundColorFromLocal = function () { helper.buildUIAndRunTest(_createButtonFunc(), _testNativeBackgroundColorFromLocal); } -export var testMemoryLeak = function () { +export var testMemoryLeak = function (done) { helper.buildUIWithWeakRefAndInteract(_createButtonFunc, function (button) { buttonTestsNative.performNativeClick(button); - }); + }, done); } var _createButtonFunc = function (): buttonModule.Button { diff --git a/apps/tests/ui/helper.ts b/apps/tests/ui/helper.ts index 0932c0bff..306ca5da1 100644 --- a/apps/tests/ui/helper.ts +++ b/apps/tests/ui/helper.ts @@ -155,7 +155,7 @@ export function navigateToModuleAndRunTest(moduleName, context, testFunction) { } } -export function buildUIWithWeakRefAndInteract(createFunc: () => T, interactWithViewFunc?: (view: T) => void) { +export function buildUIWithWeakRefAndInteract(createFunc: () => T, interactWithViewFunc?: (view: T) => void, done?) { var newPage: page.Page; var testFinished = false; var pageFactory = function (): page.Page { @@ -167,23 +167,28 @@ export function buildUIWithWeakRefAndInteract(createFunc: ( newPage.on("loaded", () => { loaded = true; var weakRef = new WeakRef(createFunc()); + try { + sp.addChild(weakRef.get()); - sp.addChild(weakRef.get()); + if (interactWithViewFunc) { + interactWithViewFunc(weakRef.get()); + } - if (interactWithViewFunc) { - interactWithViewFunc(weakRef.get()); + sp.removeChild(weakRef.get()); + if (newPage.ios) { + // Could cause GC on the next call. + // NOTE: Don't replace this with forceGC(); + new ArrayBuffer(4 * 1024 * 1024); + } + utils.GC(); + + TKUnit.waitUntilReady(() => { return weakRef.get() ? !(weakRef.get().isLoaded) : true; }, MEMORY_ASYNC); + TKUnit.assert(!weakRef.get(), weakRef.get() + " leaked!"); + testFinished = true; } - - sp.removeChild(weakRef.get()); - if (newPage.ios) { - // Could cause GC on the next call. - // NOTE: Don't replace this with forceGC(); - new ArrayBuffer(4 * 1024 * 1024); + catch (e) { + done(e); } - utils.GC(); - - TKUnit.assert(!weakRef.get(), weakRef.get() + " leaked!"); - testFinished = true; }); return newPage; @@ -195,6 +200,7 @@ export function buildUIWithWeakRefAndInteract(createFunc: ( } finally { goBack(); + done(null); } } diff --git a/apps/tests/ui/list-view/list-view-tests.ts b/apps/tests/ui/list-view/list-view-tests.ts index 830661dd1..8ffe378c9 100644 --- a/apps/tests/ui/list-view/list-view-tests.ts +++ b/apps/tests/ui/list-view/list-view-tests.ts @@ -633,12 +633,7 @@ export function test_ConverterIsCalledJustOnce_onAddingItemsToListView() { helper.buildUIAndRunTest(listView, testAction); } -export function test_no_memory_leak_when_items_is_regular_array() { - if (utils.ios) { - if (testRunner.isRunningOnEmulator() || utils.ios.MajorVersion > 8) { - return; - } - } +export function test_no_memory_leak_when_items_is_regular_array(done) { var createFunc = function (): listViewModule.ListView { var listView = new listViewModule.ListView(); listView.items = FEW_ITEMS; @@ -647,15 +642,10 @@ export function test_no_memory_leak_when_items_is_regular_array() { helper.buildUIWithWeakRefAndInteract(createFunc, (list) => { TKUnit.assert(list.isLoaded, "ListView should be loaded here"); - }); + }, done); } -export function test_no_memory_leak_when_items_is_observable_array() { - if (utils.ios) { - if (testRunner.isRunningOnEmulator() || utils.ios.MajorVersion > 8) { - return; - } - } +export function test_no_memory_leak_when_items_is_observable_array(done) { // Keep the reference to the observable array to test the weakEventListener var colors = new observableArray.ObservableArray(["red", "green", "blue"]); @@ -667,7 +657,7 @@ export function test_no_memory_leak_when_items_is_observable_array() { helper.buildUIWithWeakRefAndInteract(createFunc, (list) => { TKUnit.assert(list.isLoaded, "ListView should be loaded here"); - }); + }, done); } function loadViewWithItemNumber(args: listViewModule.ItemEventData) { diff --git a/apps/tests/ui/repeater/repeater-tests.ts b/apps/tests/ui/repeater/repeater-tests.ts index 979d690f8..044577520 100644 --- a/apps/tests/ui/repeater/repeater-tests.ts +++ b/apps/tests/ui/repeater/repeater-tests.ts @@ -456,7 +456,7 @@ export function test_ChildrenAreNotCreatedUntilTheRepeaterIsLoaded() { } /* -export function test_no_memory_leak_when_items_is_regular_array() { +export function test_no_memory_leak_when_items_is_regular_array(done) { var createFunc = function (): repeaterModule.Repeater { var repeater = new repeaterModule.Repeater(); repeater.items = FEW_ITEMS; @@ -465,10 +465,10 @@ export function test_no_memory_leak_when_items_is_regular_array() { helper.buildUIWithWeakRefAndInteract(createFunc,(list) => { TKUnit.assert(list.isLoaded, "Repeater should be loaded here"); - }); + }, done); } -export function test_no_memory_leak_when_items_is_observable_array() { +export function test_no_memory_leak_when_items_is_observable_array(done) { // Keep the reference to the observable array to test the weakEventListener var colors = new observableArray.ObservableArray(["red", "green", "blue"]); @@ -480,7 +480,7 @@ export function test_no_memory_leak_when_items_is_observable_array() { helper.buildUIWithWeakRefAndInteract(createFunc,(list) => { TKUnit.assert(list.isLoaded, "Repeater should be loaded here"); - }); + }, done); } */ function getChildrenCount(repeater: repeaterModule.Repeater): number { diff --git a/apps/tests/ui/text-field/text-field-tests.ts b/apps/tests/ui/text-field/text-field-tests.ts index 585a4da47..22a26719f 100644 --- a/apps/tests/ui/text-field/text-field-tests.ts +++ b/apps/tests/ui/text-field/text-field-tests.ts @@ -6,7 +6,6 @@ import pagesModule = require("ui/page"); import textFieldTestsNative = require("./text-field-tests-native"); import colorModule = require("color"); import enums = require("ui/enums"); -import utils = require("utils/utils"); // // # TextField @@ -428,13 +427,8 @@ export var testNativeTextAlignmentFromLocal = function () { }); } -export var testMemoryLeak = function () { - if (utils.ios) { - if (testRunner.isRunningOnEmulator() || utils.ios.MajorVersion > 8) { - return; - } - } +export var testMemoryLeak = function (done) { helper.buildUIWithWeakRefAndInteract(_createTextFieldFunc, function (textField) { textFieldTestsNative.typeTextNatively(textField, "Hello, world!"); - }); + }, done); } \ No newline at end of file diff --git a/apps/tests/ui/text-view/text-view-tests.ts b/apps/tests/ui/text-view/text-view-tests.ts index 4b57ebd72..1c5b05cf6 100644 --- a/apps/tests/ui/text-view/text-view-tests.ts +++ b/apps/tests/ui/text-view/text-view-tests.ts @@ -6,7 +6,6 @@ import pagesModule = require("ui/page"); import textViewTestsNative = require("./text-view-tests-native"); import colorModule = require("color"); import enums = require("ui/enums"); -import utils = require("utils/utils"); // // # TextView @@ -469,13 +468,8 @@ export var testNativeTextAlignmentFromLocal = function () { }); } -export var testMemoryLeak = function () { - if (utils.ios) { - if (testRunner.isRunningOnEmulator() || utils.ios.MajorVersion > 8) { - return; - } - } +export var testMemoryLeak = function (done) { helper.buildUIWithWeakRefAndInteract(_createTextViewFunc, function (textView) { textViewTestsNative.typeTextNatively(textView, "Hello, world!"); - }); + }, done); } diff --git a/apps/tests/weak-event-listener-tests.ts b/apps/tests/weak-event-listener-tests.ts index c4108468d..25d00e649 100644 --- a/apps/tests/weak-event-listener-tests.ts +++ b/apps/tests/weak-event-listener-tests.ts @@ -135,21 +135,28 @@ export function test_handlerIsDetached_WhenAllListenersAreRemoved() { TKUnit.assert(!source.hasListeners(observable.Observable.propertyChangeEvent), "All events should be detached"); } -export function test_autoDetachingOfDeadReferences() { +export function test_autoDetachingOfDeadReferences(done) { var source = new observable.Observable(); for (var i = 0; i < 100; i++) { addListenerWithSource(source); } + try { + helper.forceGC(); - helper.forceGC(); + var target = new Target(); - var target = new Target(); + weakEvents.addWeakEventListener(source, observable.Observable.propertyChangeEvent, target.onEvent, target); + weakEvents.removeWeakEventListener(source, observable.Observable.propertyChangeEvent, target.onEvent, target) - weakEvents.addWeakEventListener(source, observable.Observable.propertyChangeEvent, target.onEvent, target); - weakEvents.removeWeakEventListener(source, observable.Observable.propertyChangeEvent, target.onEvent, target) - - TKUnit.assert(!source.hasListeners(observable.Observable.propertyChangeEvent), "All events should be detached"); + TKUnit.waitUntilReady(() => { return !source.hasListeners(observable.Observable.propertyChangeEvent); }); + var testPass = (source)._observers[observable.Observable.propertyChangeEvent] ? (source)._observers[observable.Observable.propertyChangeEvent].length <= 1 : true; + TKUnit.assert(testPass, "All events should be detached"); + done(null); + } + catch (e) { + done(e); + } } function addListenerWithSource(source: observable.Observable) { diff --git a/ui/styling/font.ios.ts b/ui/styling/font.ios.ts index 4cb301bd4..ee9123e30 100644 --- a/ui/styling/font.ios.ts +++ b/ui/styling/font.ios.ts @@ -169,16 +169,18 @@ export module ios { function registerCustomFonts() { var fontsFolderPath = fs.path.join(__dirname.substring(0, __dirname.indexOf("/tns_modules")), "fonts"); - var fontsFolder = fs.Folder.fromPath(fontsFolderPath); - var onEachEntityFunc = function (fileEntity: fs.FileSystemEntity): boolean { - if (fs.Folder.exists(fs.path.join(fontsFolderPath, fileEntity.name))) { + if (fs.Folder.exists(fontsFolderPath)) { + var fontsFolder = fs.Folder.fromPath(fontsFolderPath); + var onEachEntityFunc = function (fileEntity: fs.FileSystemEntity): boolean { + if (fs.Folder.exists(fs.path.join(fontsFolderPath, fileEntity.name))) { + return true; + } + ios.registerFont(fileEntity.name); return true; } - ios.registerFont(fileEntity.name); - return true; - } - fontsFolder.eachEntity(onEachEntityFunc); + fontsFolder.eachEntity(onEachEntityFunc); + } } registerCustomFonts(); \ No newline at end of file