Files
NativeScript/tests/app/testRunner.ts
Panayot Cankov f7a3a36b9c Housekeeping node tests, renamed to unit-tests (#4936)
Add parsers for the background css shorthand property, make ViewBase unit testable in node environment

Add background parser and linear-gradient parser

Use sticky regexes

Simplify some types, introduce generic Parsed<T> instead of & TokenRange

Apply each parser to return a { start, end, value } object

Move the css selector parser to the css/parser and unify types

Add the first steps toward building homegrown css parser

Add somewhat standards compliant tokenizer, add baseline, rework and shady css parsers

Enable all tests again, skip flaky perf test

Improve css parser tokenizer by converting some char token types to simple string

Implement 'parse a stylesheet'

Add gonzales css-parser

Add parseLib and css-tree perf

Add a thin parser layer that will convert CSS3 tokens to values, for now output is compatible with rework

Make root tsc green

Return the requires of tns-core-modules to use relative paths for webpack to work

Implement support for '@import 'url-string';

Fix function parser, function-token is no-longer neglected

Make the style-scope be able to load from "css" and "css-ast" modules

Add a loadAppCss event so theme can be added to snapshot separately from loaded
2017-10-20 10:42:07 +03:00

473 lines
16 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 const 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 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";
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;
const testsSuitesWithLongDelay = {
HTTP: 15 * 1000,
}
const testsWithLongDelay = {
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
}
let startTime;
let running = false;
let testsQueue = new Array<TestInfo>();
function printRunTestStats() {
const testCases = new Array<string>();
let 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) {
const stack = new StackLayout();
const btn = new Button();
btn.text = "Rerun tests";
btn.on("tap", () => runAll(testsSelector));
stack.addChild(btn);
const 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);
}, 10);
}
}
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 function runAll(testSelector?: string) {
testsSelector = testSelector;
if (running) {
// TODO: We may schedule pending run requests
return;
}
let singleModuleName, singleTestName;
if (testSelector) {
const 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 : "");
const totalSuccess = 0;
const totalFailed: Array<TKUnit.TestFailure> = [];
testsQueue.push(new TestInfo(() => { running = true; startTime = TKUnit.time(); }));
for (const name in allTests) {
if (singleModuleName && (singleModuleName !== name.toLowerCase())) {
continue;
}
const testModule = allTests[name];
const 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 (const testName in test) {
if (singleTestName && (singleTestName !== testName.toLowerCase())) {
continue;
}
const testFunction = test[testName];
if ((typeof (testFunction) === "function") && (testName.substring(0, 4) == "test")) {
if (test.setUp) {
testsQueue.push(new TestInfo(test.setUp, test));
}
const testTimeout = testsWithLongDelay[testName] || testsSuitesWithLongDelay[name];
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;
}
}