mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
recycleNativeView filed now accepts: "always" | "never" | "auto". Always will recycle the nativeView no matter if its nativeView or android proprties are accessed. Never will disable recycling. Auto will recycle it only if nativeView and android properties are not accessed.
483 lines
17 KiB
TypeScript
483 lines
17 KiB
TypeScript
/* tslint:disable */
|
|
import * as TKUnit from "./TKUnit";
|
|
import { messageType } from "tns-core-modules/trace";
|
|
import { topmost, Frame } from "tns-core-modules/ui/frame";
|
|
import { TextView } from "tns-core-modules/ui/text-view";
|
|
import { Button } from "tns-core-modules/ui/button";
|
|
import { StackLayout } from "tns-core-modules/ui/layouts/stack-layout";
|
|
import * as platform from "tns-core-modules/platform";
|
|
import "./ui-test";
|
|
import * as fs from "tns-core-modules/file-system";
|
|
import { unsetValue } from "tns-core-modules/ui/core/properties";
|
|
import { ad } from "tns-core-modules/utils/utils";
|
|
|
|
Frame.defaultAnimatedNavigation = false;
|
|
|
|
export function isRunningOnEmulator(): boolean {
|
|
// This checks are not good enough to be added to modules but keeps unittests green.
|
|
|
|
if (platform.device.os === platform.platformNames.android) {
|
|
return android.os.Build.FINGERPRINT.indexOf("generic") > -1 ||
|
|
android.os.Build.HARDWARE.toLowerCase() === "goldfish" ||
|
|
android.os.Build.HARDWARE.toLowerCase() === "donatello" || // VS Emulator
|
|
android.os.Build.PRODUCT.toLocaleLowerCase().indexOf("sdk") > -1 ||
|
|
android.os.Build.PRODUCT.toLocaleLowerCase().indexOf("emulator") > -1; // VS Emulator
|
|
}
|
|
else if (platform.device.os === platform.platformNames.ios) {
|
|
//return platform.device.model === "iPhone Simulator";
|
|
return (__dirname.search("Simulator") > -1);
|
|
}
|
|
}
|
|
|
|
export var allTests = {};
|
|
|
|
import * as domNodeTest from "./debugger/dom-node-tests";
|
|
allTests["DOM-NODE"] = domNodeTest;
|
|
|
|
import * as profilingTests from "./profiling/profiling-tests";
|
|
allTests["PROFILING"] = profilingTests;
|
|
|
|
import * as platformTests from "./platform/platform-tests";
|
|
allTests["PLATFORM"] = platformTests;
|
|
|
|
import * as fsTests from "./file-system/file-system-tests";
|
|
allTests["FILE-SYSTEM"] = fsTests;
|
|
|
|
import * as httpTests from "./http/http-tests";
|
|
allTests["HTTP"] = httpTests;
|
|
|
|
import * as xhrTests from "./xhr/xhr-tests";
|
|
allTests["XHR"] = xhrTests;
|
|
|
|
import * as fetchTests from "./fetch/fetch-tests";
|
|
allTests["FETCH"] = fetchTests;
|
|
|
|
import * as appSettingsTests from "./application-settings/application-settings-tests";
|
|
allTests["APPLICATION-SETTINGS"] = appSettingsTests;
|
|
|
|
import * as applicationTests from "./application/application-tests";
|
|
allTests["APPLICATION"] = applicationTests;
|
|
|
|
import * as imageSourceTests from "./image-source/image-source-tests";
|
|
allTests["IMAGE-SOURCE"] = imageSourceTests;
|
|
|
|
import * as observableArrayTests from "./data/observable-array-tests";
|
|
allTests["OBSERVABLE-ARRAY"] = observableArrayTests;
|
|
|
|
import * as virtualArrayTests from "./data/virtual-array-tests";
|
|
allTests["VIRTUAL-ARRAY"] = virtualArrayTests;
|
|
|
|
import * as observableTests from "./data/observable-tests";
|
|
allTests["OBSERVABLE"] = observableTests;
|
|
|
|
import * as timerTests from "./timer/timer-tests";
|
|
allTests["TIMER"] = timerTests;
|
|
|
|
import * as colorTests from "./color/color-tests";
|
|
allTests["COLOR"] = colorTests;
|
|
|
|
import * as bindableTests from "./ui/core/bindable/bindable-tests";
|
|
allTests["BINDABLE"] = bindableTests;
|
|
|
|
import * as bindintExpressionTests from "./ui/core/bindable/binding-expressions-tests";
|
|
allTests["BINDING-EXPRESSIONS"] = bindintExpressionTests;
|
|
|
|
import * as xmlParserTests from "./xml-parser-tests/xml-parser-tests";
|
|
allTests["XML-PARSER"] = xmlParserTests;
|
|
|
|
import * as formattedStringTests from "./text/formatted-string-tests";
|
|
allTests["FORMATTEDSTRING"] = formattedStringTests;
|
|
|
|
import * as fileSystemAccessTests from "./file-system-access-tests/file-system-access-tests";
|
|
allTests["FILE-SYSTEM-ACCESS"] = fileSystemAccessTests;
|
|
|
|
import * as fileNameResolverTests from "./file-name-resolver-tests/file-name-resolver-tests";
|
|
allTests["FILE-NAME-RESOLVER"] = fileNameResolverTests;
|
|
|
|
import * as weakEventsTests from "./ui/core/weak-event-listener/weak-event-listener-tests";
|
|
allTests["WEAK-EVENTS"] = weakEventsTests;
|
|
|
|
import * as connectivityTests from "./connectivity/connectivity-tests";
|
|
allTests["CONNECTIVITY"] = connectivityTests;
|
|
|
|
import * as proxyViewContainerTests from "./ui/proxy-view-container/proxy-view-container-tests";
|
|
allTests["PROXY-VIEW-CONTAINER"] = proxyViewContainerTests;
|
|
|
|
import * as scrollViewTests from "./ui/scroll-view/scroll-view-tests";
|
|
allTests["SCROLL-VIEW"] = scrollViewTests;
|
|
|
|
import * as actionBarTests from "./ui/action-bar/action-bar-tests";
|
|
allTests["ACTION-BAR"] = actionBarTests;
|
|
|
|
import * as xmlDeclarationTests from "./xml-declaration/xml-declaration-tests";
|
|
allTests["XML-DECLARATION"] = xmlDeclarationTests;
|
|
|
|
import * as dockLayoutTests from "./ui/layouts/dock-layout-tests";
|
|
allTests["DOCKLAYOUT"] = dockLayoutTests;
|
|
|
|
import * as wrapLayoutTests from "./ui/layouts/wrap-layout-tests";
|
|
allTests["WRAPLAYOUT"] = wrapLayoutTests;
|
|
|
|
import * as absoluteLayoutTests from "./ui/layouts/absolute-layout-tests";
|
|
allTests["ABSOLUTELAYOUT"] = absoluteLayoutTests;
|
|
|
|
import * as gridLayoutTests from "./ui/layouts/grid-layout-tests";
|
|
allTests["GRIDLAYOUT"] = gridLayoutTests;
|
|
|
|
import * as stackLayoutTests from "./ui/layouts/stack-layout-tests";
|
|
allTests["STACKLAYOUT"] = stackLayoutTests;
|
|
|
|
import * as flexBoxLayoutTests from "./ui/layouts/flexbox-layout-tests";
|
|
allTests["FLEXBOXLAYOUT"] = flexBoxLayoutTests;
|
|
|
|
import * as stylePropertiesTests from "./ui/styling/style-properties-tests";
|
|
allTests["STYLE-PROPERTIES"] = stylePropertiesTests;
|
|
|
|
import * as frameTests from "./ui/frame/frame-tests";
|
|
allTests["FRAME"] = frameTests;
|
|
|
|
import * as viewTests from "./ui/view/view-tests";
|
|
allTests["VIEW"] = viewTests;
|
|
|
|
import * as styleTests from "./ui/styling/style-tests";
|
|
allTests["STYLE"] = styleTests;
|
|
|
|
import * as visualStateTests from "./ui/styling/visual-state-tests";
|
|
allTests["VISUAL-STATE"] = visualStateTests;
|
|
|
|
import * as valueSourceTests from "./ui/styling/value-source-tests";
|
|
allTests["VALUE-SOURCE"] = valueSourceTests;
|
|
|
|
import * as cssSelectorParserTests from "./ui/styling/css-selector-parser";
|
|
allTests["CSS-SELECTOR-PARSER"] = cssSelectorParserTests;
|
|
|
|
import * as cssSelectorTests from "./ui/styling/css-selector";
|
|
allTests["CSS-SELECTOR"] = cssSelectorTests;
|
|
|
|
import * as buttonTests from "./ui/button/button-tests";
|
|
allTests["BUTTON"] = buttonTests;
|
|
|
|
import * as borderTests from "./ui/border/border-tests";
|
|
allTests["BORDER"] = borderTests;
|
|
|
|
import * as labelTests from "./ui/label/label-tests";
|
|
allTests["LABEL"] = labelTests;
|
|
|
|
import * as tabViewTests from "./ui/tab-view/tab-view-tests";
|
|
allTests["TAB-VIEW"] = tabViewTests;
|
|
|
|
import * as tabViewNavigationTests from "./ui/tab-view/tab-view-navigation-tests";
|
|
allTests["TAB-VIEW-NAVIGATION"] = tabViewNavigationTests;
|
|
|
|
import * as imageTests from "./ui/image/image-tests";
|
|
allTests["IMAGE"] = imageTests;
|
|
|
|
import * as sliderTests from "./ui/slider/slider-tests";
|
|
allTests["SLIDER"] = sliderTests;
|
|
|
|
import * as switchTests from "./ui/switch/switch-tests";
|
|
allTests["SWITCH"] = switchTests;
|
|
|
|
import * as progressTests from "./ui/progress/progress-tests";
|
|
allTests["PROGRESS"] = progressTests;
|
|
|
|
import * as placeholderTests from "./ui/placeholder/placeholder-tests";
|
|
allTests["PLACEHOLDER"] = placeholderTests;
|
|
|
|
import * as pageTests from "./ui/page/page-tests";
|
|
allTests["PAGE"] = pageTests;
|
|
|
|
import * as listViewTests from "./ui/list-view/list-view-tests";
|
|
allTests["LISTVIEW"] = listViewTests;
|
|
|
|
import * as activityIndicatorTests from "./ui/activity-indicator/activity-indicator-tests";
|
|
allTests["ACTIVITY-INDICATOR"] = activityIndicatorTests;
|
|
|
|
import * as textFieldTests from "./ui/text-field/text-field-tests";
|
|
allTests["TEXT-FIELD"] = textFieldTests;
|
|
|
|
import * as textViewTests from "./ui/text-view/text-view-tests";
|
|
allTests["TEXT-VIEW"] = textViewTests;
|
|
|
|
import * as listPickerTests from "./ui/list-picker/list-picker-tests";
|
|
allTests["LIST-PICKER"] = listPickerTests;
|
|
|
|
import * as datePickerTests from "./ui/date-picker/date-picker-tests";
|
|
allTests["DATE-PICKER"] = datePickerTests;
|
|
|
|
import * as timePickerTests from "./ui/time-picker/time-picker-tests";
|
|
allTests["TIME-PICKER"] = timePickerTests;
|
|
|
|
import * as webViewTests from "./ui/web-view/web-view-tests";
|
|
allTests["WEB-VIEW"] = webViewTests;
|
|
|
|
import * as htmlViewTests from "./ui/html-view/html-view-tests";
|
|
allTests["HTML-VIEW"] = htmlViewTests;
|
|
|
|
import * as repeaterTests from "./ui/repeater/repeater-tests";
|
|
allTests["REPEATER"] = repeaterTests;
|
|
|
|
import * as segmentedBarTests from "./ui/segmented-bar/segmented-bar-tests";
|
|
allTests["SEGMENTED-BAR"] = segmentedBarTests;
|
|
|
|
import * as animationTests from "./ui/animation/animation-tests";
|
|
allTests["ANIMATION"] = animationTests;
|
|
|
|
import * as lifecycle from "./ui/lifecycle/lifecycle-tests";
|
|
allTests["LIFECYCLE"] = lifecycle;
|
|
|
|
import * as cssAnimationTests from "./ui/animation/css-animation-tests";
|
|
allTests["CSS-ANIMATION"] = cssAnimationTests;
|
|
|
|
import * as transitionTests from "./navigation/transition-tests";
|
|
// Skip transitions on android emulators with API 23
|
|
if (!(platform.device.os === platform.platformNames.android && parseInt(platform.device.sdkVersion) === 23 && isRunningOnEmulator())) {
|
|
allTests["TANSITIONS"] = transitionTests;
|
|
}
|
|
|
|
import * as searchBarTests from "./ui/search-bar/search-bar-tests";
|
|
allTests["SEARCH-BAR"] = searchBarTests;
|
|
|
|
import * as navigationTests from "./navigation/navigation-tests";
|
|
allTests["NAVIGATION"] = navigationTests;
|
|
|
|
var testsWithLongDelay = {
|
|
test_Transitions: 3 * 60 * 1000,
|
|
testLocation: 10000,
|
|
testLocationOnce: 10000,
|
|
testLocationOnceMaximumAge: 10000,
|
|
//web-view-tests
|
|
testLoadExistingUrl: 10000 * 5,
|
|
testLoadLocalFile: 10000 * 5,
|
|
testLoadInvalidUrl: 10000,
|
|
testLoadUpperCaseSrc: 10000 * 5,
|
|
test_SettingImageSrc: 30 * 1000,
|
|
test_ChainingAnimations: 30 * 1000,
|
|
test_AnimatingProperties: 30 * 1000,
|
|
test_AnimateBackgroundColor_FromString: 10 * 1000
|
|
}
|
|
|
|
var startTime;
|
|
var running = false;
|
|
var testsQueue = new Array<TestInfo>();
|
|
|
|
function printRunTestStats() {
|
|
const testCases = new Array<string>();
|
|
|
|
var failedTestCount = 0;
|
|
const failedTestInfo = [];
|
|
const slowTests = new Array<string>();
|
|
|
|
let allTests = testsQueue.filter(t => t.isTest);
|
|
|
|
allTests.forEach((testCase, i, arr) => {
|
|
let testName = testCase.testName;
|
|
if (!testCase.isPassed) {
|
|
failedTestCount++;
|
|
failedTestInfo.push(testCase.testName + " FAILED: " + testCase.errorMessage);
|
|
}
|
|
|
|
let duration = (testCase.duration / 1000).toFixed(2);
|
|
if (testCase.duration > 500) {
|
|
slowTests.push(`${testCase.testName}: ${duration}s`);
|
|
}
|
|
});
|
|
|
|
const totalTime = (TKUnit.time() - startTime).toFixed(2);
|
|
|
|
let finalMessage = `\n`+
|
|
`=== ALL TESTS COMPLETE ===\n` +
|
|
`${(allTests.length - failedTestCount)} OK, ${failedTestCount} failed\n` +
|
|
`DURATION: ${totalTime} ms\n`;
|
|
|
|
TKUnit.write(finalMessage, messageType.info);
|
|
|
|
failedTestInfo.forEach((message, i, arr) => {
|
|
TKUnit.write(message, messageType.error);
|
|
finalMessage += "\n" + message;
|
|
});
|
|
|
|
// console.log("test-result.xml:\n" + generateTestFile(allTests));
|
|
|
|
// DO NOT CHANGE THE FIRST ROW! Used as an indicator for test run pass detection.
|
|
TKUnit.write(`Tests EOF!`, messageType.info);
|
|
|
|
showReportPage(finalMessage);
|
|
}
|
|
|
|
function generateTestFile(allTests: TestInfo[]) {
|
|
let failedTestCount = 0;
|
|
|
|
const testCases = new Array<string>();
|
|
allTests.forEach((testCase, i, arr) => {
|
|
let testName = testCase.testName;
|
|
let duration = (testCase.duration / 1000).toFixed(2);
|
|
|
|
testCases.push(`<testcase classname="${platform.device.os}" name="${testName}" time="${duration}">`)
|
|
if (!testCase.isPassed) {
|
|
failedTestCount++;
|
|
testCases.push(`<failure type="exceptions.AssertionError"><![CDATA[${testCase.errorMessage}]]></failure>`)
|
|
}
|
|
testCases.push(`</testcase>`);
|
|
});
|
|
|
|
const totalTime = (TKUnit.time() - startTime).toFixed(2);
|
|
|
|
const result = [
|
|
"<testsuites>",
|
|
`<testsuite name="NativeScript Tests" timestamp="${new Date()}" hostname="hostname" time="${totalTime}" errors="0" tests="${allTests.length}" skipped="0" failures="${failedTestCount}">`,
|
|
...testCases,
|
|
"</testsuite>",
|
|
"</testsuites>"
|
|
].join("");
|
|
|
|
return result;
|
|
}
|
|
|
|
function showReportPage(finalMessage: string) {
|
|
let stack = new StackLayout();
|
|
|
|
let btn = new Button();
|
|
btn.text = "Rerun tests";
|
|
btn.on("tap", () => runAll(testsSelector));
|
|
stack.addChild(btn);
|
|
|
|
let messageContainer = new TextView();
|
|
messageContainer.editable = messageContainer.autocorrect = false;
|
|
messageContainer.text = finalMessage;
|
|
stack.addChild(messageContainer);
|
|
|
|
const page = topmost().currentPage;
|
|
page.id = unsetValue;
|
|
page.className = unsetValue;
|
|
page.bindingContext = unsetValue;
|
|
page.style.color = unsetValue;
|
|
page.style.backgroundColor = unsetValue;
|
|
page.content = stack;
|
|
messageContainer.focus();
|
|
page.style.fontSize = 11;
|
|
if (page.android) {
|
|
setTimeout(() => {
|
|
messageContainer.dismissSoftInput();
|
|
(<android.view.View>messageContainer.nativeViewProtected).scrollTo(0, 0);
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
function startLog(): void {
|
|
let testsName: string = this.name;
|
|
TKUnit.write("START " + testsName + " TESTS.", messageType.info);
|
|
this.start = TKUnit.time();
|
|
}
|
|
|
|
function log(): void {
|
|
let testsName: string = this.name;
|
|
let duration = TKUnit.time() - this.start;
|
|
TKUnit.write(testsName + " COMPLETED for " + duration.toFixed(2) + " BACKSTACK DEPTH: " + topmost().backStack.length, messageType.info);
|
|
}
|
|
|
|
let testsSelector: string
|
|
export var runAll = function (testSelector?: string) {
|
|
testsSelector = testSelector;
|
|
if (running) {
|
|
// TODO: We may schedule pending run requests
|
|
return;
|
|
}
|
|
|
|
var singleModuleName, singleTestName;
|
|
if (testSelector) {
|
|
var pair = testSelector.split(".");
|
|
singleModuleName = pair[0];
|
|
if (singleModuleName) {
|
|
if (singleModuleName.length === 0) {
|
|
singleModuleName = undefined;
|
|
} else {
|
|
singleModuleName = singleModuleName.toLowerCase();
|
|
}
|
|
}
|
|
|
|
singleTestName = pair[1];
|
|
if (singleTestName) {
|
|
if (singleTestName.length === 0) {
|
|
singleTestName = undefined;
|
|
} else {
|
|
singleTestName = singleTestName.toLowerCase();
|
|
}
|
|
}
|
|
}
|
|
|
|
console.log("TESTS: " + singleModuleName ? singleModuleName : "" + " " + singleTestName ? singleTestName : "");
|
|
|
|
var totalSuccess = 0;
|
|
var totalFailed: Array<TKUnit.TestFailure> = [];
|
|
testsQueue.push(new TestInfo(() => { running = true; startTime = TKUnit.time(); }));
|
|
for (var name in allTests) {
|
|
if (singleModuleName && (singleModuleName !== name.toLowerCase())) {
|
|
continue;
|
|
}
|
|
|
|
var testModule = allTests[name];
|
|
|
|
var test = testModule.createTestCase ? testModule.createTestCase() : testModule;
|
|
test.name = name;
|
|
|
|
testsQueue.push(new TestInfo(startLog, test));
|
|
|
|
if (test.setUpModule) {
|
|
testsQueue.push(new TestInfo(test.setUpModule, test));
|
|
}
|
|
|
|
for (var testName in test) {
|
|
if (singleTestName && (singleTestName !== testName.toLowerCase())) {
|
|
continue;
|
|
}
|
|
|
|
var testFunction = test[testName];
|
|
if ((typeof (testFunction) === "function") && (testName.substring(0, 4) == "test")) {
|
|
if (test.setUp) {
|
|
testsQueue.push(new TestInfo(test.setUp, test));
|
|
}
|
|
var testTimeout = testsWithLongDelay[testName];
|
|
testsQueue.push(new TestInfo(testFunction, test, true, name + "." + testName, false, null, testTimeout));
|
|
if (test.tearDown) {
|
|
testsQueue.push(new TestInfo(test.tearDown, test));
|
|
}
|
|
}
|
|
}
|
|
if (test.tearDownModule) {
|
|
testsQueue.push(new TestInfo(test.tearDownModule, test));
|
|
}
|
|
testsQueue.push(new TestInfo(log, test));
|
|
}
|
|
|
|
testsQueue.push(new TestInfo(printRunTestStats));
|
|
testsQueue.push(new TestInfo(function () { testsQueue = []; running = false; }));
|
|
|
|
TKUnit.runTests(testsQueue, 0);
|
|
}
|
|
|
|
|
|
|
|
class TestInfo implements TKUnit.TestInfoEntry {
|
|
testFunc: () => void;
|
|
instance: any;
|
|
isTest: boolean;
|
|
testName: string;
|
|
isPassed: boolean;
|
|
errorMessage: string;
|
|
testTimeout: number;
|
|
duration: number;
|
|
|
|
constructor(testFunc, testInstance?: any, isTest?, testName?, isPassed?, errorMessage?, testTimeout?, duration?) {
|
|
this.testFunc = testFunc;
|
|
this.instance = testInstance || null;
|
|
this.isTest = isTest || false;
|
|
this.testName = testName || "";
|
|
this.isPassed = isPassed || false;
|
|
this.errorMessage = errorMessage || "";
|
|
this.testTimeout = testTimeout;
|
|
this.duration = duration;
|
|
}
|
|
}
|