chore: cleanup
6
.gitignore
vendored
@@ -35,8 +35,10 @@ npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
**/__tests__/e2e/**/*/platforms
|
||||
**/__tests__/**/*/webpack.*.js
|
||||
apps/**/*/*.js
|
||||
apps/**/*/*.map
|
||||
apps/**/*/platforms
|
||||
apps/**/*/webpack.*.js
|
||||
*.tgz
|
||||
|
||||
# System Files
|
||||
|
||||
10
README.md
@@ -31,6 +31,16 @@ npm run setup
|
||||
## @nativescript/core
|
||||
|
||||
```
|
||||
npx apps:playground:ios
|
||||
npm run apps:playground:android
|
||||
|
||||
|
||||
npm run packages:core:build
|
||||
npm run packages:core:test
|
||||
|
||||
|
||||
|
||||
|
||||
// livesync develop changes
|
||||
nx run core-e2e-playground:ios
|
||||
nx run core-e2e-playground:android
|
||||
|
||||
2
apps/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
## Apps configured for workspace development
|
||||
|
||||
85
apps/automated/app/animation-frame/animation-frame.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import * as animationFrame from '@nativescript/core/animation-frame';
|
||||
import * as fpsNative from '@nativescript/core/fps-meter/fps-native';
|
||||
|
||||
export function test_requestAnimationFrame_isDefined() {
|
||||
TKUnit.assertNotEqual(animationFrame.requestAnimationFrame, undefined, 'Method animationFrame.requestAnimationFrame() should be defined!');
|
||||
}
|
||||
|
||||
export function test_cancelAnimationFrame_isDefined() {
|
||||
TKUnit.assertNotEqual(animationFrame.cancelAnimationFrame, undefined, 'Method animationFrame.cancelAnimationFrame() should be defined!');
|
||||
}
|
||||
|
||||
export function test_requestAnimationFrame() {
|
||||
let completed: boolean;
|
||||
|
||||
const id = animationFrame.requestAnimationFrame(() => {
|
||||
completed = true;
|
||||
});
|
||||
|
||||
TKUnit.waitUntilReady(() => completed, 0.5, false);
|
||||
animationFrame.cancelAnimationFrame(id);
|
||||
TKUnit.assert(completed, 'Callback should be called!');
|
||||
}
|
||||
|
||||
export function test_requestAnimationFrame_callbackCalledInCurrentFrame() {
|
||||
let completed: boolean;
|
||||
let currentFrameTime = 0;
|
||||
const frameCb = new fpsNative.FPSCallback((time) => {
|
||||
currentFrameTime = time;
|
||||
});
|
||||
frameCb.start();
|
||||
|
||||
TKUnit.waitUntilReady(() => currentFrameTime > 0, 0.5);
|
||||
let calledTime = 0;
|
||||
animationFrame.requestAnimationFrame((frameTime) => {
|
||||
calledTime = frameTime;
|
||||
completed = calledTime >= frameTime;
|
||||
});
|
||||
|
||||
TKUnit.waitUntilReady(() => completed, 0.5, false);
|
||||
frameCb.stop();
|
||||
TKUnit.assert(completed, 'Callback should be called in current frame!');
|
||||
}
|
||||
|
||||
export function test_requestAnimationFrame_nextCallbackCalledInNextFrame() {
|
||||
let completed: boolean;
|
||||
let currentFrameTime = 0;
|
||||
const frameCb = new fpsNative.FPSCallback((time) => {
|
||||
currentFrameTime = time;
|
||||
});
|
||||
frameCb.start();
|
||||
|
||||
TKUnit.waitUntilReady(() => currentFrameTime > 0, 0.5);
|
||||
animationFrame.requestAnimationFrame((firstFrameTime) => {
|
||||
animationFrame.requestAnimationFrame((frameTime) => {
|
||||
frameCb.stop();
|
||||
completed = frameTime > firstFrameTime && frameTime === currentFrameTime;
|
||||
});
|
||||
});
|
||||
|
||||
TKUnit.waitUntilReady(() => completed, 0.5, false);
|
||||
frameCb.stop();
|
||||
TKUnit.assert(completed, 'Callback should be called in next frame!');
|
||||
}
|
||||
|
||||
export function test_requestAnimationFrame_shouldBeCancelled() {
|
||||
let completed: boolean;
|
||||
let currentFrameTime = 0;
|
||||
const frameCb = new fpsNative.FPSCallback((time) => {
|
||||
currentFrameTime = time;
|
||||
});
|
||||
frameCb.start();
|
||||
|
||||
TKUnit.waitUntilReady(() => currentFrameTime > 0, 0.5);
|
||||
animationFrame.requestAnimationFrame((firstFrameTime) => {
|
||||
const cbId = animationFrame.requestAnimationFrame((frameTime) => {
|
||||
completed = true;
|
||||
});
|
||||
animationFrame.cancelAnimationFrame(cbId);
|
||||
});
|
||||
|
||||
TKUnit.wait(1);
|
||||
frameCb.stop();
|
||||
TKUnit.assert(!completed, 'Callback should not be called');
|
||||
}
|
||||
146
apps/automated/app/app.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
let start;
|
||||
if (typeof NSDate !== 'undefined') {
|
||||
start = NSDate.date();
|
||||
} else {
|
||||
start = java.lang.System.currentTimeMillis();
|
||||
}
|
||||
|
||||
import { Application, ApplicationEventData, UnhandledErrorEventData, DiscardedErrorEventData, AndroidActivityBundleEventData, AndroidActivityEventData, AndroidApplication, AndroidActivityNewIntentEventData, AndroidActivityResultEventData, AndroidActivityBackPressedEventData } from '@nativescript/core';
|
||||
|
||||
if (Application.ios) {
|
||||
// Observe application notifications.
|
||||
Application.ios.addNotificationObserver(UIApplicationDidFinishLaunchingNotification, (notification: NSNotification) => {
|
||||
console.log('UIApplicationDidFinishLaunchingNotification: ' + notification);
|
||||
});
|
||||
}
|
||||
|
||||
// Common events for both Android and iOS.
|
||||
Application.on(Application.displayedEvent, function (args: ApplicationEventData) {
|
||||
(<any>global).isDisplayedEventFired = true;
|
||||
|
||||
if (args.android) {
|
||||
// For Android applications, args.android is an Android activity class.
|
||||
console.log('Displayed Activity: ' + args.android);
|
||||
} else if (args.ios) {
|
||||
// For iOS applications, args.ios is UIApplication.
|
||||
console.log('Displayed UIApplication: ' + args.ios);
|
||||
}
|
||||
});
|
||||
|
||||
Application.on(Application.launchEvent, function (args: ApplicationEventData) {
|
||||
if (args.android) {
|
||||
// For Android applications, args.android is an android.content.Intent class.
|
||||
console.log('Launched Android application with the following intent: ' + args.android + '.');
|
||||
} else if (args.ios !== undefined) {
|
||||
// For iOS applications, args.ios is NSDictionary (launchOptions).
|
||||
console.log('Launched iOS application with options: ' + args.ios);
|
||||
}
|
||||
});
|
||||
|
||||
Application.on(Application.suspendEvent, function (args: ApplicationEventData) {
|
||||
if (args.android) {
|
||||
// For Android applications, args.android is an Android activity class.
|
||||
console.log('Suspend Activity: ' + args.android);
|
||||
} else if (args.ios) {
|
||||
// For iOS applications, args.ios is UIApplication.
|
||||
console.log('Suspend UIApplication: ' + args.ios);
|
||||
}
|
||||
});
|
||||
|
||||
Application.on(Application.resumeEvent, function (args: ApplicationEventData) {
|
||||
if (args.android) {
|
||||
// For Android applications, args.android is an Android activity class.
|
||||
console.log('Resume Activity: ' + args.android);
|
||||
} else if (args.ios) {
|
||||
// For iOS applications, args.ios is UIApplication.
|
||||
console.log('Resume UIApplication: ' + args.ios);
|
||||
}
|
||||
});
|
||||
|
||||
Application.on(Application.exitEvent, function (args: ApplicationEventData) {
|
||||
if (args.android) {
|
||||
// For Android applications, args.android is an Android activity class.
|
||||
console.log('Exit Activity: ' + args.android);
|
||||
} else if (args.ios) {
|
||||
// For iOS applications, args.ios is UIApplication.
|
||||
console.log('Exit UIApplication: ' + args.ios);
|
||||
}
|
||||
});
|
||||
|
||||
Application.on(Application.lowMemoryEvent, function (args: ApplicationEventData) {
|
||||
if (args.android) {
|
||||
// For Android applications, args.android is an Android activity class.
|
||||
console.log('Low Memory: ' + args.android);
|
||||
} else if (args.ios) {
|
||||
// For iOS applications, args.ios is UIApplication.
|
||||
console.log('Low Memory: ' + args.ios);
|
||||
}
|
||||
});
|
||||
|
||||
// Error events.
|
||||
Application.on(Application.uncaughtErrorEvent, function (args: UnhandledErrorEventData) {
|
||||
console.log('NativeScriptError: ' + args.error);
|
||||
console.log((<any>args.error).nativeException || (<any>args.error).nativeError);
|
||||
console.log((<any>args.error).stackTrace || (<any>args.error).stack);
|
||||
});
|
||||
|
||||
Application.on(Application.discardedErrorEvent, function (args: DiscardedErrorEventData) {
|
||||
console.log('[Discarded] NativeScriptError: ' + args.error);
|
||||
console.log((<any>args.error).nativeException || (<any>args.error).nativeError);
|
||||
console.log((<any>args.error).stackTrace || (<any>args.error).stack);
|
||||
});
|
||||
|
||||
// Android activity events.
|
||||
if (Application.android) {
|
||||
Application.android.on(AndroidApplication.activityCreatedEvent, function (args: AndroidActivityBundleEventData) {
|
||||
console.log('Event: ' + args.eventName + ', Activity: ' + args.activity + ', Bundle: ' + args.bundle);
|
||||
});
|
||||
|
||||
Application.android.on(AndroidApplication.activityDestroyedEvent, function (args: AndroidActivityEventData) {
|
||||
console.log('Event: ' + args.eventName + ', Activity: ' + args.activity);
|
||||
});
|
||||
|
||||
Application.android.on(AndroidApplication.activityStartedEvent, function (args: AndroidActivityEventData) {
|
||||
console.log('Event: ' + args.eventName + ', Activity: ' + args.activity);
|
||||
});
|
||||
|
||||
Application.android.on(AndroidApplication.activityPausedEvent, function (args: AndroidActivityEventData) {
|
||||
console.log('Event: ' + args.eventName + ', Activity: ' + args.activity);
|
||||
});
|
||||
|
||||
Application.android.on(AndroidApplication.activityResumedEvent, function (args: AndroidActivityEventData) {
|
||||
console.log('Event: ' + args.eventName + ', Activity: ' + args.activity);
|
||||
});
|
||||
|
||||
Application.android.on(AndroidApplication.activityStoppedEvent, function (args: AndroidActivityEventData) {
|
||||
console.log('Event: ' + args.eventName + ', Activity: ' + args.activity);
|
||||
});
|
||||
|
||||
Application.android.on(AndroidApplication.saveActivityStateEvent, function (args: AndroidActivityBundleEventData) {
|
||||
console.log('Event: ' + args.eventName + ', Activity: ' + args.activity + ', Bundle: ' + args.bundle);
|
||||
});
|
||||
|
||||
Application.android.on(AndroidApplication.activityResultEvent, function (args: AndroidActivityResultEventData) {
|
||||
console.log('Event: ' + args.eventName + ', Activity: ' + args.activity + ', requestCode: ' + args.requestCode + ', resultCode: ' + args.resultCode + ', Intent: ' + args.intent);
|
||||
});
|
||||
|
||||
Application.android.on(AndroidApplication.activityBackPressedEvent, function (args: AndroidActivityBackPressedEventData) {
|
||||
console.log('Event: ' + args.eventName + ', Activity: ' + args.activity);
|
||||
// Set args.cancel = true to cancel back navigation and do something custom.
|
||||
});
|
||||
|
||||
Application.android.on(AndroidApplication.activityNewIntentEvent, function (args: AndroidActivityNewIntentEventData) {
|
||||
console.log('Event: ' + args.eventName + ', Activity: ' + args.activity + ', Intent: ' + args.intent);
|
||||
});
|
||||
}
|
||||
|
||||
let time;
|
||||
if (typeof NSDate !== 'undefined') {
|
||||
time = NSDate.date().timeIntervalSinceDate(start) * 1000;
|
||||
} else {
|
||||
time = java.lang.System.currentTimeMillis() - start;
|
||||
}
|
||||
|
||||
console.log(`TIME TO LOAD APP: ${time} ms`);
|
||||
|
||||
Application.run({ moduleName: 'app-root' });
|
||||
@@ -0,0 +1,178 @@
|
||||
var appSettings = require('@nativescript/core/application-settings');
|
||||
import * as TKUnit from '../tk-unit';
|
||||
|
||||
var stringKey: string = 'stringKey';
|
||||
var boolKey: string = 'boolKey';
|
||||
var numberKey: string = 'numberKey';
|
||||
var noStringKey: string = 'noStringKey';
|
||||
var noBoolKey: string = 'noBoolKey';
|
||||
var noNumberKey: string = 'noNumberKey';
|
||||
|
||||
export var testBoolean = function () {
|
||||
appSettings.setBoolean(boolKey, false);
|
||||
var boolValueBefore = appSettings.getBoolean(boolKey);
|
||||
TKUnit.assert(false === boolValueBefore, 'Cannot set boolean to false, currently it is: ' + appSettings.getBoolean(boolKey));
|
||||
|
||||
appSettings.setBoolean('boolKey', true);
|
||||
var boolValue = appSettings.getBoolean('boolKey', false);
|
||||
|
||||
TKUnit.assert(true === boolValue, 'Cannot set boolean to true');
|
||||
|
||||
TKUnit.assert(true === appSettings.getBoolean(boolKey), 'Cannot set boolean to true (no default)');
|
||||
};
|
||||
|
||||
export var testString = function () {
|
||||
appSettings.setString('stringKey', 'String value');
|
||||
var stringValue = appSettings.getString('stringKey');
|
||||
|
||||
TKUnit.assert('String value' === stringValue, 'Cannot set string value');
|
||||
};
|
||||
|
||||
export var testNumber = function () {
|
||||
appSettings.setNumber('numberKey', 54.321);
|
||||
var value = parseFloat(appSettings.getNumber('numberKey').toFixed(3));
|
||||
|
||||
TKUnit.assert(54.321 === value, 'Cannot set number value 54.321 != ' + value);
|
||||
};
|
||||
|
||||
export var testDefaults = function () {
|
||||
var defaultValue = appSettings.getString('noStringKey', 'No string value');
|
||||
// will return "No string value" if there is no value for "noStringKey"
|
||||
|
||||
TKUnit.assert('No string value' === defaultValue, 'Bad default string value');
|
||||
TKUnit.assert(true === appSettings.getBoolean(noBoolKey, true), 'Bad default boolean value');
|
||||
TKUnit.assert(123.45 === appSettings.getNumber(noNumberKey, 123.45), 'Bad default number value');
|
||||
};
|
||||
|
||||
export var testDefaultsWithNoDefaultValueProvided = function () {
|
||||
var defaultValue = appSettings.getString('noStringKey');
|
||||
// will return undefined if there is no value for "noStringKey"
|
||||
|
||||
TKUnit.assertEqual(defaultValue, undefined, 'Default string value is not undefined');
|
||||
|
||||
TKUnit.assertEqual(appSettings.getBoolean(noBoolKey), undefined, 'Default boolean value is not undefined');
|
||||
TKUnit.assertEqual(appSettings.getNumber(noNumberKey), undefined, 'Default number value is not undefined');
|
||||
};
|
||||
|
||||
export var testHasKey = function () {
|
||||
var hasKey = appSettings.hasKey('noBoolKey');
|
||||
// will return false if there is no value for "noBoolKey"
|
||||
|
||||
TKUnit.assert(!hasKey, 'There is a key: ' + noBoolKey);
|
||||
TKUnit.assert(!appSettings.hasKey(noStringKey), 'There is a key: ' + noStringKey);
|
||||
TKUnit.assert(!appSettings.hasKey(noNumberKey), 'There is a key: ' + noNumberKey);
|
||||
|
||||
TKUnit.assert(appSettings.hasKey(boolKey), 'There is no key: ' + boolKey);
|
||||
TKUnit.assert(appSettings.hasKey(stringKey), 'There is no key: ' + stringKey);
|
||||
TKUnit.assert(appSettings.hasKey(numberKey), 'There is no key: ' + numberKey);
|
||||
};
|
||||
|
||||
export var testRemove = function () {
|
||||
appSettings.remove('boolKey');
|
||||
|
||||
TKUnit.assert(!appSettings.hasKey(boolKey), 'Failed to remove key: ' + boolKey);
|
||||
|
||||
appSettings.remove(stringKey);
|
||||
TKUnit.assert(!appSettings.hasKey(stringKey), 'Failed to remove key: ' + stringKey);
|
||||
|
||||
appSettings.remove(numberKey);
|
||||
TKUnit.assert(!appSettings.hasKey(numberKey), 'Failed to remove key: ' + numberKey);
|
||||
};
|
||||
|
||||
export var testClear = function () {
|
||||
appSettings.clear();
|
||||
|
||||
TKUnit.assert(!appSettings.hasKey(boolKey), 'Failed to remove key: ' + boolKey);
|
||||
TKUnit.assert(!appSettings.hasKey(stringKey), 'Failed to remove key: ' + stringKey);
|
||||
TKUnit.assert(!appSettings.hasKey(numberKey), 'Failed to remove key: ' + numberKey);
|
||||
};
|
||||
|
||||
export var testFlush = function () {
|
||||
appSettings.setString(stringKey, 'String value');
|
||||
|
||||
var flushed = appSettings.flush();
|
||||
// will return boolean indicating whether flush to disk was successful
|
||||
|
||||
TKUnit.assert(flushed, 'Flush failed: ' + flushed);
|
||||
TKUnit.assert(appSettings.hasKey(stringKey), 'There is no key: ' + stringKey);
|
||||
};
|
||||
|
||||
export var testAllKeys = function () {
|
||||
appSettings.setString(stringKey, 'String value');
|
||||
appSettings.setBoolean(boolKey, true);
|
||||
appSettings.setNumber(numberKey, 22);
|
||||
|
||||
var allKeys = appSettings.getAllKeys();
|
||||
TKUnit.assert(allKeys.indexOf(stringKey) !== -1, `${stringKey} is missing from .allKeys()`);
|
||||
TKUnit.assert(allKeys.indexOf(boolKey) !== -1, `${boolKey} is missing from .allKeys()`);
|
||||
TKUnit.assert(allKeys.indexOf(numberKey) !== -1, `${numberKey} is missing from .allKeys()`);
|
||||
};
|
||||
|
||||
export var testInvalidKey = function () {
|
||||
try {
|
||||
appSettings.hasKey(undefined);
|
||||
TKUnit.assert(false, 'There is a key undefined');
|
||||
} catch (e) {
|
||||
// we should receive an exception here
|
||||
}
|
||||
|
||||
try {
|
||||
appSettings.hasKey(null);
|
||||
TKUnit.assert(false, 'There is a key null');
|
||||
} catch (e) {
|
||||
// we should receive an exception here
|
||||
}
|
||||
|
||||
try {
|
||||
appSettings.hasKey(123);
|
||||
TKUnit.assert(false, 'There is a key number');
|
||||
} catch (e) {
|
||||
// we should receive an exception here
|
||||
}
|
||||
|
||||
appSettings.hasKey('string');
|
||||
};
|
||||
|
||||
export var testInvalidValue = function () {
|
||||
try {
|
||||
appSettings.setBoolean(boolKey, 'str');
|
||||
TKUnit.assert(false, 'There is a key undefined');
|
||||
} catch (e) {
|
||||
// we should receive an exception here
|
||||
}
|
||||
|
||||
try {
|
||||
appSettings.setBoolean(boolKey, 123);
|
||||
TKUnit.assert(false, 'There is a key undefined');
|
||||
} catch (e) {
|
||||
// we should receive an exception here
|
||||
}
|
||||
|
||||
try {
|
||||
appSettings.setString(boolKey, true);
|
||||
TKUnit.assert(false, 'There is a key undefined');
|
||||
} catch (e) {
|
||||
// we should receive an exception here
|
||||
}
|
||||
|
||||
try {
|
||||
appSettings.setString(boolKey, 123);
|
||||
TKUnit.assert(false, 'There is a key undefined');
|
||||
} catch (e) {
|
||||
// we should receive an exception here
|
||||
}
|
||||
|
||||
try {
|
||||
appSettings.setNumber(boolKey, true);
|
||||
TKUnit.assert(false, 'There is a key undefined');
|
||||
} catch (e) {
|
||||
// we should receive an exception here
|
||||
}
|
||||
|
||||
try {
|
||||
appSettings.setNumber(boolKey, '123');
|
||||
TKUnit.assert(false, 'There is a key undefined');
|
||||
} catch (e) {
|
||||
// we should receive an exception here
|
||||
}
|
||||
};
|
||||
27
apps/automated/app/application/application-tests-common.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import * as app from '@nativescript/core/application';
|
||||
import { isAndroid, isIOS, Device, Application, platformNames } from '@nativescript/core';
|
||||
|
||||
import * as TKUnit from '../tk-unit';
|
||||
|
||||
if (isAndroid) {
|
||||
console.log('We are running on an Android device!');
|
||||
} else if (isIOS) {
|
||||
console.log('We are running on an iOS device!');
|
||||
}
|
||||
|
||||
export function testInitialized() {
|
||||
if (Device.os === platformNames.android) {
|
||||
TKUnit.assert(app.android, 'Application module not properly intialized');
|
||||
} else if (Device.os === platformNames.ios) {
|
||||
TKUnit.assert(app.ios, 'Application module not properly intialized');
|
||||
}
|
||||
}
|
||||
|
||||
export function testDisplayedEvent() {
|
||||
// global.isDisplayedEventFired flag is set in app.ts application.displayedEvent handler
|
||||
TKUnit.assert((<any>global).isDisplayedEventFired, 'application.displayedEvent not fired');
|
||||
}
|
||||
|
||||
export function testOrientation() {
|
||||
TKUnit.assert(Application.orientation(), 'Orientation not initialized.');
|
||||
}
|
||||
53
apps/automated/app/application/application-tests.android.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
/* tslint:disable:no-unused-variable */
|
||||
import { Application, isAndroid } from '@nativescript/core';
|
||||
import * as TKUnit from '../tk-unit';
|
||||
|
||||
export * from './application-tests-common';
|
||||
|
||||
// >> application-app-android
|
||||
var androidApp = Application.android;
|
||||
// << application-app-android
|
||||
|
||||
// >> application-app-android-context
|
||||
var context = Application.android.context;
|
||||
//// get the Files (Documents) folder (directory)
|
||||
var dir = context.getFilesDir();
|
||||
// << application-app-android-context
|
||||
|
||||
// >> application-app-android-current
|
||||
if (androidApp.foregroundActivity === androidApp.startActivity) {
|
||||
////console.log("We are currently in the main (start) activity of the application");
|
||||
}
|
||||
// << application-app-android-current
|
||||
|
||||
// >> application-app-android-broadcast
|
||||
//// Register the broadcast receiver
|
||||
if (isAndroid) {
|
||||
Application.android.registerBroadcastReceiver(android.content.Intent.ACTION_BATTERY_CHANGED, function onReceiveCallback(context: android.content.Context, intent: android.content.Intent) {
|
||||
var level = intent.getIntExtra(android.os.BatteryManager.EXTRA_LEVEL, -1);
|
||||
var scale = intent.getIntExtra(android.os.BatteryManager.EXTRA_SCALE, -1);
|
||||
var percent = (level / scale) * 100.0;
|
||||
////console.log("Battery: " + percent + "%");
|
||||
});
|
||||
}
|
||||
//// When no longer needed, unregister the broadcast receiver
|
||||
if (isAndroid) {
|
||||
Application.android.unregisterBroadcastReceiver(android.content.Intent.ACTION_BATTERY_CHANGED);
|
||||
}
|
||||
// << application-app-android-broadcast
|
||||
|
||||
export function testAndroidApplicationInitialized() {
|
||||
TKUnit.assert(Application.android, 'Android application not initialized.');
|
||||
TKUnit.assert(Application.android.context, 'Android context not initialized.');
|
||||
TKUnit.assert(Application.android.foregroundActivity, 'Android foregroundActivity not initialized.');
|
||||
TKUnit.assert(Application.android.foregroundActivity.isNativeScriptActivity, 'Android foregroundActivity.isNativeScriptActivity is false.');
|
||||
TKUnit.assert(Application.android.startActivity, 'Android startActivity not initialized.');
|
||||
TKUnit.assert(Application.android.nativeApp, 'Android nativeApp not initialized.');
|
||||
TKUnit.assert(Application.android.orientation, 'Android orientation not initialized.');
|
||||
TKUnit.assert(Application.android.packageName, 'Android packageName not initialized.');
|
||||
TKUnit.assert(Application.android.systemAppearance, 'Android system appearance not initialized.');
|
||||
}
|
||||
|
||||
export function testSystemAppearance() {
|
||||
TKUnit.assert(Application.android.systemAppearance, 'System appearance not initialized.');
|
||||
}
|
||||
2
apps/automated/app/application/application-tests.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import * as android from './application-tests.android';
|
||||
import * as iOS from './application-tests.ios';
|
||||
64
apps/automated/app/application/application-tests.ios.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Application, Utils, isIOS } from '@nativescript/core';
|
||||
import * as TKUnit from '../tk-unit';
|
||||
|
||||
export * from './application-tests-common';
|
||||
|
||||
// >> application-ios-observer
|
||||
//// Add the notification observer
|
||||
if (Application.ios) {
|
||||
var observer = Application.ios.addNotificationObserver(UIDeviceBatteryLevelDidChangeNotification, function onReceiveCallback(notification: NSNotification) {
|
||||
var percent = UIDevice.currentDevice.batteryLevel * 100;
|
||||
var message = 'Battery: ' + percent + '%';
|
||||
////console.log(message);
|
||||
});
|
||||
}
|
||||
//// When no longer needed, remove the notification observer
|
||||
if (isIOS) {
|
||||
Application.ios.removeNotificationObserver(observer, UIDeviceBatteryLevelDidChangeNotification);
|
||||
}
|
||||
// << application-ios-observer
|
||||
|
||||
// >> application-ios-delegate
|
||||
//// Add custom application delegate
|
||||
if (isIOS) {
|
||||
class MyDelegate extends UIResponder implements UIApplicationDelegate {
|
||||
public static ObjCProtocols = [UIApplicationDelegate];
|
||||
|
||||
applicationDidFinishLaunchingWithOptions(application: UIApplication, launchOptions: NSDictionary<any, any>): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
applicationDidBecomeActive(application: UIApplication): void {
|
||||
// Get reference to the application window.
|
||||
//console.log("keyWindow: " + application.keyWindow);
|
||||
}
|
||||
}
|
||||
|
||||
Application.ios.delegate = MyDelegate;
|
||||
}
|
||||
|
||||
// << application-ios-delegate
|
||||
|
||||
export function testIOSApplicationInitialized() {
|
||||
TKUnit.assert(Application.ios, 'iOS application not initialized.');
|
||||
TKUnit.assert(Application.ios.delegate, 'iOS delegate not initialized.');
|
||||
TKUnit.assert(Application.ios.nativeApp, 'iOS nativeApp not initialized.');
|
||||
TKUnit.assert(Application.ios.orientation, 'iOS orientation not initialized.');
|
||||
|
||||
if (Utils.ios.MajorVersion <= 11) {
|
||||
TKUnit.assertNull(Application.ios.systemAppearance, 'iOS system appearance should be `null` on iOS <= 11.');
|
||||
} else {
|
||||
TKUnit.assert(Application.ios.systemAppearance, 'iOS system appearance not initialized.');
|
||||
}
|
||||
|
||||
TKUnit.assert(Application.ios.window, 'iOS window not initialized.');
|
||||
TKUnit.assert(Application.ios.rootController, 'iOS root controller not initialized.');
|
||||
}
|
||||
|
||||
export function testSystemAppearance() {
|
||||
if (Utils.ios.MajorVersion <= 11) {
|
||||
TKUnit.assertNull(Application.ios.systemAppearance, 'System appearance should be `null` on iOS <= 11.');
|
||||
} else {
|
||||
TKUnit.assert(Application.ios.systemAppearance, 'System appearance not initialized.');
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 150 B After Width: | Height: | Size: 150 B |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
91
apps/automated/app/color/color-tests.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
// >> color-require
|
||||
import * as colorModule from '@nativescript/core/color';
|
||||
var Color = colorModule.Color;
|
||||
// << color-require
|
||||
import * as TKUnit from '../tk-unit';
|
||||
|
||||
export var test_Hex_Color = function () {
|
||||
// >> color-hex
|
||||
// Creates the red color
|
||||
var color = new Color('#FF0000');
|
||||
// << color-hex
|
||||
TKUnit.assertEqual(color.a, 255, 'Color.a not properly parsed');
|
||||
TKUnit.assertEqual(color.r, 255, 'Color.r not properly parsed');
|
||||
TKUnit.assertEqual(color.g, 0, 'Color.g not properly parsed');
|
||||
TKUnit.assertEqual(color.b, 0, 'Color.b not properly parsed');
|
||||
TKUnit.assertEqual(color.hex, '#FF0000', 'Color.hex not properly parsed');
|
||||
TKUnit.assertEqual(color.argb, 0xffff0000, 'Color.argb not properly parsed');
|
||||
};
|
||||
|
||||
export var test_ShortHex_Color = function () {
|
||||
// >> color-hex-short
|
||||
// Creates the color #FF8800
|
||||
var color = new Color('#F80');
|
||||
// << color-hex-short
|
||||
TKUnit.assertEqual(color.a, 255, 'Color.a not properly parsed');
|
||||
TKUnit.assertEqual(color.r, 255, 'Color.r not properly parsed');
|
||||
TKUnit.assertEqual(color.g, 136, 'Color.g not properly parsed'); // 0x88 == 136
|
||||
TKUnit.assertEqual(color.b, 0, 'Color.b not properly parsed');
|
||||
TKUnit.assertEqual(color.hex, '#FF8800', 'Color.hex not properly parsed');
|
||||
TKUnit.assertEqual(color.argb, 0xffff8800, 'Color.argb not properly parsed');
|
||||
};
|
||||
|
||||
export var test_Argb_Color = function () {
|
||||
// >> color-rgb
|
||||
// Creates the color with 100 alpha, 255 red, 100 green, 100 blue
|
||||
var color = new Color(100, 255, 100, 100);
|
||||
// << color-rgb
|
||||
TKUnit.assertEqual(color.a, 100, 'Color.a not properly parsed');
|
||||
TKUnit.assertEqual(color.r, 255, 'Color.r not properly parsed');
|
||||
TKUnit.assertEqual(color.g, 100, 'Color.g not properly parsed');
|
||||
TKUnit.assertEqual(color.b, 100, 'Color.b not properly parsed');
|
||||
TKUnit.assertEqual(color.hex, '#64FF6464', 'Color.hex not properly parsed');
|
||||
TKUnit.assertEqual(color.argb, 0x64ff6464, 'Color.argb not properly parsed');
|
||||
};
|
||||
|
||||
export var test_ArgbInt_Color = function () {
|
||||
// >> color-rgb-single
|
||||
// Creates the color with 100 alpha, 100 red, 100 green, 100 blue
|
||||
var color = new Color(0x64646464);
|
||||
// << color-rgb-single
|
||||
TKUnit.assertEqual(color.a, 100, 'Color.a not properly parsed');
|
||||
TKUnit.assertEqual(color.r, 100, 'Color.r not properly parsed');
|
||||
TKUnit.assertEqual(color.g, 100, 'Color.g not properly parsed');
|
||||
TKUnit.assertEqual(color.b, 100, 'Color.b not properly parsed');
|
||||
TKUnit.assertEqual(color.hex, '#64646464', 'Color.hex not properly parsed');
|
||||
TKUnit.assertEqual(color.argb, 0x64646464, 'Color.argb not properly parsed');
|
||||
};
|
||||
|
||||
export var test_rgb_Color_CSS = function () {
|
||||
// <snippet module="color" title="color">
|
||||
// ### Creating a Color from four RGB values
|
||||
// ``` JavaScript
|
||||
// Creates the color with 255 red, 100 green, 100 blue
|
||||
var color = new Color('rgb(255, 100, 100)');
|
||||
// ```
|
||||
// </snippet>
|
||||
TKUnit.assertEqual(color.a, 255, 'Color.a not properly parsed');
|
||||
TKUnit.assertEqual(color.r, 255, 'Color.r not properly parsed');
|
||||
TKUnit.assertEqual(color.g, 100, 'Color.g not properly parsed');
|
||||
TKUnit.assertEqual(color.b, 100, 'Color.b not properly parsed');
|
||||
TKUnit.assertEqual(color.hex, '#FF6464', 'Color.hex not properly parsed');
|
||||
TKUnit.assertEqual(color.argb, 0xffff6464, 'Color.argb not properly parsed');
|
||||
};
|
||||
|
||||
export var test_rgba_Color_CSS = function () {
|
||||
var alpha = 0.5;
|
||||
var expected = 0x80;
|
||||
// <snippet module="color" title="color">
|
||||
// ### Creating a Color from four RGB values
|
||||
// ``` JavaScript
|
||||
// Creates the color with 255 red, 100 green, 100 blue and 0 alpha
|
||||
var color = new Color(`rgba(255, 100, 100, ${alpha})`);
|
||||
// ```
|
||||
// </snippet>
|
||||
TKUnit.assertEqual(color.a, expected, 'Color.a not properly parsed');
|
||||
TKUnit.assertEqual(color.r, 255, 'Color.r not properly parsed');
|
||||
TKUnit.assertEqual(color.g, 100, 'Color.g not properly parsed');
|
||||
TKUnit.assertEqual(color.b, 100, 'Color.b not properly parsed');
|
||||
TKUnit.assertEqual(color.hex, '#80FF6464', 'Color.hex not properly parsed');
|
||||
TKUnit.assertEqual(color.argb, 0x80ff6464, 'Color.argb not properly parsed');
|
||||
};
|
||||
40
apps/automated/app/connectivity/connectivity-tests.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
// >> connectivity-require
|
||||
import * as connectivity from '@nativescript/core/connectivity';
|
||||
// << connectivity-require
|
||||
|
||||
export var test_DummyTestForSnippetOnly0 = function () {
|
||||
// >> connectivity-type
|
||||
var connectionType = connectivity.getConnectionType();
|
||||
switch (connectionType) {
|
||||
case connectivity.connectionType.none:
|
||||
//console.log("No connection");
|
||||
break;
|
||||
case connectivity.connectionType.wifi:
|
||||
//console.log("WiFi connection");
|
||||
break;
|
||||
case connectivity.connectionType.mobile:
|
||||
//console.log("Mobile connection");
|
||||
break;
|
||||
}
|
||||
// << connectivity-type
|
||||
};
|
||||
|
||||
export var test_DummyTestForSnippetOnly1 = function () {
|
||||
// >> connectivity-monitoring
|
||||
connectivity.startMonitoring(function onConnectionTypeChanged(newConnectionType: number) {
|
||||
switch (newConnectionType) {
|
||||
case connectivity.connectionType.none:
|
||||
//console.log("Connection type changed to none.");
|
||||
break;
|
||||
case connectivity.connectionType.wifi:
|
||||
//console.log("Connection type changed to WiFi.");
|
||||
break;
|
||||
case connectivity.connectionType.mobile:
|
||||
//console.log("Connection type changed to mobile.");
|
||||
break;
|
||||
}
|
||||
});
|
||||
//...
|
||||
connectivity.stopMonitoring();
|
||||
// << connectivity-monitoring
|
||||
};
|
||||
36
apps/automated/app/console/console-tests.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
export var test_DummyTestForSnippetOnly0 = function () {
|
||||
// >> console-log
|
||||
console.log('Hello, world!');
|
||||
console.info('I am NativeScript');
|
||||
console.warn('Low memory');
|
||||
console.error('Uncaught Application Exception');
|
||||
// << console-log
|
||||
};
|
||||
|
||||
export var test_DummyTestForSnippetOnly1 = function () {
|
||||
// >> console-time
|
||||
console.time('LoadTime');
|
||||
// << console-time
|
||||
// >> console-timeend
|
||||
console.timeEnd('LoadTime');
|
||||
// << console-timeend
|
||||
};
|
||||
|
||||
export var test_DummyTestForSnippetOnly2 = function () {
|
||||
// >> console-assert
|
||||
console.assert(2 === 2, '2 equals 2');
|
||||
// << console-assert
|
||||
};
|
||||
|
||||
export var test_DummyTestForSnippetOnly3 = function () {
|
||||
// >> console-dir
|
||||
var obj = { name: 'John', age: 34 };
|
||||
console.dir(obj);
|
||||
// << console-dir
|
||||
};
|
||||
|
||||
export var test_DummyTestForSnippetOnly5 = function () {
|
||||
// >> console-trace
|
||||
console.trace();
|
||||
// << console-trace
|
||||
};
|
||||
669
apps/automated/app/data/observable-array-tests.ts
Normal file
@@ -0,0 +1,669 @@
|
||||
import * as TKUnit from '../tk-unit';
|
||||
// >> observable-array-require
|
||||
import { Label, ObservableArray, ChangedData, ChangeType } from '@nativescript/core';
|
||||
// << observable-array-require
|
||||
|
||||
export const test_ObservableArray_shouldCopySourceArrayItems = function () {
|
||||
// >> observable-array-create
|
||||
const sa = [1, 2, 3];
|
||||
const array = new ObservableArray(sa);
|
||||
// << observable-array-create
|
||||
|
||||
TKUnit.assertEqual(array.length, 3, 'ObservableArray length should be 3');
|
||||
TKUnit.assertEqual(sa.length, array.length, 'ObservableArray should copy all source array items!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_shouldCopyMultipleItemsAsSource = function () {
|
||||
// // >> observable-array-arguments
|
||||
// const array = new ObservableArray(1, 2, 3);
|
||||
// // << observable-array-arguments
|
||||
|
||||
// TKUnit.assertEqual(array.length, 3, "ObservableArray length should be 3");
|
||||
// TKUnit.assertEqual(array.getItem(1), 2, "ObservableArray should copy multiple items from source!");
|
||||
TKUnit.assertEqual(true, true);
|
||||
};
|
||||
|
||||
export const test_ObservableArray_shouldCreateArrayFromSpecifiedLength = function () {
|
||||
// >> observable-array-length
|
||||
const array = new ObservableArray(100);
|
||||
// << observable-array-length
|
||||
|
||||
TKUnit.assertEqual(array.length, 100, 'ObservableArray should create array from specified length!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_shouldBeAbleToSetLength = function () {
|
||||
// >> observable-array-newvalue
|
||||
const array = new ObservableArray(100);
|
||||
// >> (hide)
|
||||
TKUnit.assertEqual(array.length, 100, 'ObservableArray should create array from specified length!');
|
||||
// << (hide)
|
||||
array.length = 50;
|
||||
// << observable-array-newvalue
|
||||
|
||||
TKUnit.assertEqual(array.length, 50, 'ObservableArray should respect new length!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_getItemShouldReturnCorrectItem = function () {
|
||||
// >> observable-array-getitem
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
const firstItem = array.getItem(0);
|
||||
const secondItem = array.getItem(1);
|
||||
const thirdItem = array.getItem(2);
|
||||
// << observable-array-getitem
|
||||
|
||||
TKUnit.assert(firstItem === 1 && secondItem === 2 && thirdItem === 3, 'ObservableArray getItem() should return correct item!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_setItemShouldSetCorrectItem = function () {
|
||||
// >> observable-array-setitem
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
array.setItem(1, 5);
|
||||
// << observable-array-setitem
|
||||
TKUnit.assert(array.getItem(1) === 5, 'ObservableArray setItem() should set correct item!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_setItemShouldRaiseCorrectEvent = function () {
|
||||
// >> observable-array-eventdata
|
||||
let index: number;
|
||||
let action: string;
|
||||
let addedCount: number;
|
||||
let removed: Array<number>;
|
||||
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
array.on('change', (args) => {
|
||||
index = args.index; // Index of the changed item.
|
||||
action = args.action; // Action. In this case Update.
|
||||
addedCount = args.addedCount; // Number of added items. In this case 1.
|
||||
removed = args.removed; // Array of removed items. In this case with single item (2).
|
||||
});
|
||||
array.setItem(1, 5);
|
||||
// << observable-array-eventdata
|
||||
TKUnit.assertEqual(index, 1);
|
||||
TKUnit.assertEqual(action, ChangeType.Update);
|
||||
TKUnit.assertEqual(addedCount, 1);
|
||||
TKUnit.assertEqual(removed[0], 2);
|
||||
};
|
||||
|
||||
export const test_ObservableArray_concatShouldReturnNewArrayWithNewItemsAtTheEnd = function () {
|
||||
// >> observable-array-combine
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
const result = array.concat([4, 5, 6]);
|
||||
// << observable-array-combine
|
||||
TKUnit.assert(result.length === 6 && result[4] === 5, 'ObservableArray concat() should add items at the end!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_joinShouldReturnStringWithAllItemsSeparatedWithComma = function () {
|
||||
// >> observable-array-join
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
const result = array.join();
|
||||
// << observable-array-join
|
||||
TKUnit.assert(result === '1,2,3', 'ObservableArray join() should return string with all items separated with comma!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_joinShouldReturnStringWithAllItemsSeparatedWithDot = function () {
|
||||
// >> observable-array-join-separator
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
const result = array.join('.');
|
||||
// << observable-array-join-separator
|
||||
TKUnit.assert(result === '1.2.3', 'ObservableArray join() should return string with all items separated with dot!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_popShouldRemoveTheLastElement = function () {
|
||||
// >> observable-array-join-pop
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
// >> (hide)
|
||||
const viewBase = new Label();
|
||||
viewBase.set('testProperty', 0);
|
||||
viewBase.bind({ sourceProperty: 'length', targetProperty: 'testProperty' }, array);
|
||||
// << (hide)
|
||||
const result = array.pop();
|
||||
// << observable-array-join-pop
|
||||
TKUnit.assert(result === 3 && array.length === 2, 'ObservableArray pop() should remove last element!');
|
||||
TKUnit.assert(viewBase.get('testProperty') === array.length, 'Expected: ' + array.length + ', Actual: ' + viewBase.get('testProperty'));
|
||||
};
|
||||
|
||||
export const test_ObservableArray_popShouldRemoveTheLastElementAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
let result: ChangedData<number>;
|
||||
|
||||
// >> observable-array-join-change
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
// >> (hide)
|
||||
const index = array.length - 1;
|
||||
// << (hide)
|
||||
|
||||
array.on(ObservableArray.changeEvent, (args: ChangedData<number>) => {
|
||||
// Argument (args) is ChangedData<T>.
|
||||
// args.eventName is "change".
|
||||
// args.action is "delete".
|
||||
// args.index is equal to the array length - 1.
|
||||
// args.removed.length is 1.
|
||||
// args.addedCount is 0.
|
||||
|
||||
// >> (hide)
|
||||
result = args;
|
||||
// << (hide)
|
||||
});
|
||||
|
||||
array.pop();
|
||||
// << observable-array-join-change
|
||||
|
||||
TKUnit.assert(result.eventName === ObservableArray.changeEvent && result.action === ChangeType.Delete && result.removed.length === 1 && result.index === index && result.addedCount === 0, "ObservableArray pop() should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export const test_ObservableArray_pushShouldAppendNewElement = function () {
|
||||
// >> observable-array-push
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
// >> (hide)
|
||||
const viewBase = new Label();
|
||||
viewBase.set('testProperty', 0);
|
||||
viewBase.bind({ sourceProperty: 'length', targetProperty: 'testProperty' }, array);
|
||||
// << (hide)
|
||||
const result = array.push(4);
|
||||
// << observable-array-push
|
||||
TKUnit.assert(result === 4 && array.getItem(3) === 4, 'ObservableArray push() should append new element!');
|
||||
TKUnit.assert(viewBase.get('testProperty') === array.length, 'Expected: ' + array.length + ', Actual: ' + viewBase.get('testProperty'));
|
||||
};
|
||||
|
||||
export const test_ObservableArray_pushShouldAppendNewElementAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
let result: ChangedData<number>;
|
||||
|
||||
// >> observable-array-change-push
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
array.on(ObservableArray.changeEvent, (args: ChangedData<number>) => {
|
||||
// Argument (args) is ChangedData<T>.
|
||||
// args.eventName is "change".
|
||||
// args.action is "add".
|
||||
// args.index is equal to the array length.
|
||||
// args.removed.length is 0.
|
||||
// args.addedCount is 1.
|
||||
|
||||
// >> (hide)
|
||||
result = args;
|
||||
// << (hide)
|
||||
});
|
||||
|
||||
array.push(4);
|
||||
// << observable-array-change-push
|
||||
|
||||
TKUnit.assert(result.eventName === ObservableArray.changeEvent && result.action === ChangeType.Add && result.removed.length === 0 && result.index === 3 && result.addedCount === 1, "ObservableArray push() should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export const test_ObservableArray_pushShouldAppendNewElements = function () {
|
||||
// >> observable-array-push-multiple
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
// >> (hide)
|
||||
const viewBase = new Label();
|
||||
viewBase.set('testProperty', 0);
|
||||
viewBase.bind({ sourceProperty: 'length', targetProperty: 'testProperty' }, array);
|
||||
// << (hide)
|
||||
const result = array.push(4, 5, 6);
|
||||
// << observable-array-push-multiple
|
||||
TKUnit.assert(result === 6 && array.getItem(5) === 6, 'ObservableArray push() should append new elements!');
|
||||
TKUnit.assert(viewBase.get('testProperty') === array.length, 'Expected: ' + array.length + ', Actual: ' + viewBase.get('testProperty'));
|
||||
};
|
||||
|
||||
export const test_ObservableArray_pushShouldAppendNewElementsAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
let result: ChangedData<number>;
|
||||
|
||||
// >> observable-array-push-multiple-info
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
array.on(ObservableArray.changeEvent, (args: ChangedData<number>) => {
|
||||
// Argument (args) is ChangedData<T>.
|
||||
// args.eventName is "change".
|
||||
// args.action is "add".
|
||||
// args.index is equal to the array length.
|
||||
// args.removed.length is 0.
|
||||
// args.addedCount is equal to the number of added items.
|
||||
|
||||
// >> (hide)
|
||||
result = args;
|
||||
// << (hide)
|
||||
});
|
||||
|
||||
array.push(4, 5, 6);
|
||||
// << observable-array-push-multiple-info
|
||||
|
||||
TKUnit.assert(result.eventName === ObservableArray.changeEvent && result.action === ChangeType.Add && result.removed.length === 0 && result.index === 3 && result.addedCount === 3, "ObservableArray push() should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export const test_ObservableArray_pushShouldAppendNewElementsFromSourceArray = function () {
|
||||
// >> observable-array-push-source
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
// >> (hide)
|
||||
const viewBase = new Label();
|
||||
viewBase.set('testProperty', 0);
|
||||
viewBase.bind({ sourceProperty: 'length', targetProperty: 'testProperty' }, array);
|
||||
// << (hide)
|
||||
const result = array.push([4, 5, 6]);
|
||||
// << observable-array-push-source
|
||||
TKUnit.assert(result === 6 && array.getItem(5) === 6, 'ObservableArray push() should append new elements from source array!');
|
||||
TKUnit.assert(viewBase.get('testProperty') === array.length, 'Expected: ' + array.length + ', Actual: ' + viewBase.get('testProperty'));
|
||||
};
|
||||
|
||||
export const test_ObservableArray_pushShouldAppendNewElementsFromSourceArrayAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
let result: ChangedData<number>;
|
||||
|
||||
// >> observable-array-push-source-info
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
array.on(ObservableArray.changeEvent, (args: ChangedData<number>) => {
|
||||
// Argument (args) is ChangedData<T>.
|
||||
// args.eventName is "change".
|
||||
// args.action is "add".
|
||||
// args.index is equal to the array length.
|
||||
// args.removed.length is 0.
|
||||
// args.addedCount is equal to the number of added items.
|
||||
|
||||
// >> (hide)
|
||||
result = args;
|
||||
// << (hide)
|
||||
});
|
||||
|
||||
array.push([4, 5, 6]);
|
||||
// << observable-array-push-source-info
|
||||
|
||||
TKUnit.assert(result.eventName === ObservableArray.changeEvent && result.action === ChangeType.Add && result.removed.length === 0 && result.index === 3 && result.addedCount === 3, "ObservableArray push() should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export const test_ObservableArray_reverseShouldReturnNewReversedArray = function () {
|
||||
// >> observable-array-reverse
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
const result = array.reverse();
|
||||
// << observable-array-reverse
|
||||
TKUnit.assert(result.length === 3 && result[0] === 3, 'ObservableArray reverse() should return new reversed array!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_shiftShouldRemoveTheFirstElement = function () {
|
||||
// >> observable-array-shift
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
// >> (hide)
|
||||
const viewBase = new Label();
|
||||
viewBase.set('testProperty', 0);
|
||||
viewBase.bind({ sourceProperty: 'length', targetProperty: 'testProperty' }, array);
|
||||
// << (hide)
|
||||
const result = array.shift();
|
||||
// << observable-array-shift
|
||||
TKUnit.assert(result === 1 && array.length === 2, 'ObservableArray shift() should remove first element!');
|
||||
TKUnit.assert(viewBase.get('testProperty') === array.length, 'Expected: ' + array.length + ', Actual: ' + viewBase.get('testProperty'));
|
||||
};
|
||||
|
||||
export const test_ObservableArray_shiftShouldRemoveTheFirstElementAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
let result: ChangedData<number>;
|
||||
|
||||
// >> observable-array-shift-change
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
|
||||
array.on(ObservableArray.changeEvent, (args: ChangedData<number>) => {
|
||||
// Argument (args) is ChangedData<T>.
|
||||
// args.eventName is "change".
|
||||
// args.action is "delete".
|
||||
// args.index is 0.
|
||||
// args.removed.length is 1.
|
||||
// args.addedCount is 0.
|
||||
|
||||
// >> (hide)
|
||||
result = args;
|
||||
// << (hide)
|
||||
});
|
||||
|
||||
array.shift();
|
||||
// << observable-array-shift-change
|
||||
|
||||
TKUnit.assert(result.eventName === ObservableArray.changeEvent && result.action === ChangeType.Delete && result.removed.length === 1 && result.index === 0 && result.addedCount === 0, "ObservableArray shift() should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export const test_ObservableArray_sliceShouldReturnSectionAsNewArray = function () {
|
||||
// >> observable-array-slice
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
const result = array.slice();
|
||||
// << observable-array-slice
|
||||
TKUnit.assert(result[2] === 3 && result.length === 3, 'ObservableArray slice() should return section!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_sliceWithParamsShouldReturnSectionAsNewArray = function () {
|
||||
// >> observable-array-slice-args
|
||||
const array = new ObservableArray([1, 2, 3, 4, 5]);
|
||||
const result = array.slice(2, 4);
|
||||
// << observable-array-slice-args
|
||||
TKUnit.assert(result[1] === 4 && result.length === 2, 'ObservableArray slice() should return section according to specified arguments!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_sortShouldReturnNewSortedArray = function () {
|
||||
// >> observable-array-sort
|
||||
const array = new ObservableArray([3, 2, 1]);
|
||||
const result = array.sort();
|
||||
// << observable-array-sort
|
||||
TKUnit.assert(result[0] === 1 && result.length === 3, 'ObservableArray sort() should return new sorted array!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_sortShouldReturnNewSortedArrayAccordingSpecifiedOrder = function () {
|
||||
// >> observable-array-sort-comparer
|
||||
const array = new ObservableArray([10, 100, 1]);
|
||||
const result = array.sort((a: number, b: number) => a - b);
|
||||
// << observable-array-sort-comparer
|
||||
TKUnit.assert(result[2] === 100 && result.length === 3, 'ObservableArray sort() should return new sorted array according to specified order!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_spliceShouldRemoveSpecifiedNumberOfElementsStartingFromSpecifiedIndex = function () {
|
||||
// >> observable-array-splice
|
||||
const array = new ObservableArray(['one', 'two', 'three']);
|
||||
// >> (hide)
|
||||
const viewBase = new Label();
|
||||
viewBase.set('testProperty', 0);
|
||||
viewBase.bind({ sourceProperty: 'length', targetProperty: 'testProperty' }, array);
|
||||
// << (hide)
|
||||
const result = array.splice(1, 2);
|
||||
// << observable-array-splice
|
||||
TKUnit.assert(result.length === 2 && result[0] === 'two' && array.length === 1 && array.getItem(0) === 'one', 'ObservableArray splice() should remove specified number of elements starting from specified index!');
|
||||
TKUnit.assert(viewBase.get('testProperty') === array.length, 'Expected: ' + array.length + ', Actual: ' + viewBase.get('testProperty'));
|
||||
};
|
||||
|
||||
export const test_ObservableArray_spliceShouldRemoveSpecifiedNumberOfElementsStartingFromSpecifiedIndexAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
let result: ChangedData<number>;
|
||||
|
||||
// >> observable-array-splice-change
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
|
||||
array.on(ObservableArray.changeEvent, (args: ChangedData<number>) => {
|
||||
// Argument (args) is ChangedData<T>.
|
||||
// args.eventName is "change".
|
||||
// args.action is "splice".
|
||||
// args.index is the start index.
|
||||
// args.removed.length is equal to the number of deleted items.
|
||||
// args.addedCount is 0.
|
||||
|
||||
// >> (hide)
|
||||
result = args;
|
||||
// << (hide)
|
||||
});
|
||||
|
||||
array.splice(1, 2);
|
||||
// << observable-array-splice-change
|
||||
|
||||
TKUnit.assert(result.eventName === ObservableArray.changeEvent && result.action === ChangeType.Splice && result.removed.length === 2 && result.index === 1 && result.addedCount === 0, "ObservableArray splice() should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export const test_ObservableArray_spliceShouldInsertNewItemsInPlaceOfRemovedItemsStartingFromSpecifiedIndex = function () {
|
||||
// >> observable-array-splice-args
|
||||
const array = new ObservableArray(['one', 'two', 'three']);
|
||||
const result = array.splice(1, 2, 'six', 'seven');
|
||||
// << observable-array-splice-args
|
||||
TKUnit.assert(result.length === 2 && result[0] === 'two' && array.length === 3 && array.getItem(2) === 'seven', 'ObservableArray splice() should insert new items in place of removed!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_spliceShouldRemoveAndInertSpecifiedNumberOfElementsStartingFromSpecifiedIndexAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
let result: ChangedData<number>;
|
||||
|
||||
// >> observable-array-splice-args-change
|
||||
const array = new ObservableArray(['one', 'two', 'three']);
|
||||
|
||||
array.on(ObservableArray.changeEvent, (args: ChangedData<number>) => {
|
||||
// Argument (args) is ChangedData<T>.
|
||||
// args.eventName is "change".
|
||||
// args.action is "splice".
|
||||
// args.index is the start index.
|
||||
// args.removed.length is equal to the number of deleted items.
|
||||
// args.addedCount is equal to the amount of added and replaced items.
|
||||
|
||||
// >> (hide)
|
||||
result = args;
|
||||
// << (hide)
|
||||
});
|
||||
|
||||
array.splice(1, 2, 'six', 'seven', 'eight');
|
||||
// << observable-array-splice-args-change
|
||||
|
||||
TKUnit.assert(result.eventName === ObservableArray.changeEvent && result.action === ChangeType.Splice && result.removed.length === 2 && result.index === 1 && result.addedCount === 3, "ObservableArray splice() should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export const test_ObservableArray_unshiftShouldInsertNewElementsFromTheStart = function () {
|
||||
// >> observable-array-unshift
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
// >> (hide)
|
||||
const viewBase = new Label();
|
||||
viewBase.set('testProperty', 0);
|
||||
viewBase.bind({ sourceProperty: 'length', targetProperty: 'testProperty' }, array);
|
||||
// << (hide)
|
||||
const result = array.unshift(4, 5);
|
||||
// << observable-array-unshift
|
||||
|
||||
TKUnit.assert(array.getItem(0) === 4 && result === 5 && array.length === 5, 'ObservableArray unshift() should insert new elements from the start!');
|
||||
TKUnit.assert(viewBase.get('testProperty') === array.length, 'Expected: ' + array.length + ', Actual: ' + viewBase.get('testProperty'));
|
||||
};
|
||||
|
||||
export const test_ObservableArray_unshiftShouldInsertNewElementsFromTheStartAndRaiseChangeEventWithCorrectArgs = function () {
|
||||
let result: ChangedData<number>;
|
||||
|
||||
// >> observable-array-unshift-change
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
array.on(ObservableArray.changeEvent, (args: ChangedData<number>) => {
|
||||
//// Argument (args) is ChangedData<T>.
|
||||
//// args.eventName is "change".
|
||||
//// args.action is "add".
|
||||
//// args.index is 0.
|
||||
//// args.removed.length is 0.
|
||||
//// args.addedCount is equal to the number of inserted items.
|
||||
|
||||
// >> (hide)
|
||||
result = args;
|
||||
// << (hide)
|
||||
});
|
||||
|
||||
array.unshift(4, 5);
|
||||
// << observable-array-unshift-change
|
||||
|
||||
TKUnit.assert(result.eventName === ObservableArray.changeEvent && result.action === ChangeType.Add && result.removed.length === 0 && result.index === 0 && result.addedCount === 2, "ObservableArray unshift() should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export const test_ObservableArray_indexOfShouldReturnCorrectIndex = function () {
|
||||
// >> observable-array-indexof
|
||||
const array = new ObservableArray(['one', 'two', 'three']);
|
||||
const result = array.indexOf('two');
|
||||
// << observable-array-indexof
|
||||
TKUnit.assert(result === 1, 'ObservableArray indexOf() should return correct index!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_indexOfShouldReturnCorrectIndexStartingFrom = function () {
|
||||
// >> observable-array-indexof-args
|
||||
const array = new ObservableArray(['one', 'two', 'three']);
|
||||
const result = array.indexOf('two', 2);
|
||||
// << observable-array-indexof-args
|
||||
TKUnit.assert(result === -1, 'ObservableArray indexOf() should return correct index!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_lastIndexOfShouldReturnCorrectIndex = function () {
|
||||
const array = new ObservableArray(['one', 'two', 'two', 'three']);
|
||||
// >> observable-array-lastindexof
|
||||
const result = array.lastIndexOf('two');
|
||||
// << observable-array-lastindexof
|
||||
TKUnit.assert(result === 2, 'ObservableArray lastIndexOf() should return correct index!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_lastIndexOfShouldReturnCorrectIndexStartingFrom = function () {
|
||||
// >> observable-array-lastindexof-args
|
||||
const array = new ObservableArray(['one', 'two', 'two', 'one', 'three']);
|
||||
const result = array.lastIndexOf('two', 1);
|
||||
// << observable-array-lastindexof-args
|
||||
TKUnit.assert(result === 1, 'ObservableArray lastIndexOf() should return correct index!');
|
||||
};
|
||||
|
||||
export const test_ObservableArray_settingLengthToZeroPerformsSplice = function () {
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
|
||||
let changeRaised = false;
|
||||
array.on('change', (args: ChangedData<number>) => {
|
||||
changeRaised = true;
|
||||
TKUnit.assertEqual(args.object, array);
|
||||
TKUnit.assertEqual(args.eventName, 'change');
|
||||
TKUnit.assertEqual(args.action, ChangeType.Splice);
|
||||
TKUnit.assertEqual(args.index, 0);
|
||||
TKUnit.assertEqual(args.addedCount, 0);
|
||||
TKUnit.arrayAssert(args.removed, [1, 2, 3]);
|
||||
});
|
||||
|
||||
array.length = 0;
|
||||
|
||||
TKUnit.assertEqual(array.length, 0);
|
||||
TKUnit.assertTrue(changeRaised);
|
||||
};
|
||||
|
||||
export const test_ObservableArray_settingLengthToSomethingPerformsSplice = function () {
|
||||
const array = new ObservableArray([1, 2, 3]);
|
||||
let changeRaised = false;
|
||||
|
||||
array.on('change', (args: ChangedData<number>) => {
|
||||
changeRaised = true;
|
||||
TKUnit.assertEqual(args.object, array);
|
||||
TKUnit.assertEqual(args.eventName, 'change');
|
||||
TKUnit.assertEqual(args.action, ChangeType.Splice);
|
||||
TKUnit.assertEqual(args.index, 1);
|
||||
TKUnit.assertEqual(args.addedCount, 0);
|
||||
TKUnit.arrayAssert(args.removed, [2, 3]);
|
||||
});
|
||||
|
||||
array.length = 1;
|
||||
|
||||
TKUnit.assertEqual(array.length, 1);
|
||||
TKUnit.assertTrue(changeRaised);
|
||||
};
|
||||
|
||||
const array = new ObservableArray();
|
||||
|
||||
// We do not have indexer!
|
||||
export const test_getItem_isDefined = function () {
|
||||
TKUnit.assert(typeof array.getItem === 'function', "Method 'getItem()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_setItem_isDefined = function () {
|
||||
TKUnit.assert(typeof array.setItem === 'function', "Method 'setItem()' should be defined!");
|
||||
};
|
||||
|
||||
// Standard array properties and methods
|
||||
export const test_length_isDefined = function () {
|
||||
TKUnit.assert(typeof array.length === 'number', "Property 'length' should be defined!");
|
||||
};
|
||||
|
||||
export const test_toString_isDefined = function () {
|
||||
TKUnit.assert(typeof array.toString === 'function', "Method 'toString()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_toLocaleString_isDefined = function () {
|
||||
TKUnit.assert(typeof array.toLocaleString === 'function', "Method 'toString()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_concat_isDefined = function () {
|
||||
TKUnit.assert(typeof array.concat === 'function', "Method 'concat()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_join_isDefined = function () {
|
||||
TKUnit.assert(typeof array.join === 'function', "Method 'join()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_pop_isDefined = function () {
|
||||
TKUnit.assert(typeof array.pop === 'function', "Method 'pop()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_push_isDefined = function () {
|
||||
TKUnit.assert(typeof array.push === 'function', "Method 'push()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_reverse_isDefined = function () {
|
||||
TKUnit.assert(typeof array.reverse === 'function', "Method 'reverse()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_shift_isDefined = function () {
|
||||
TKUnit.assert(typeof array.shift === 'function', "Method 'shift()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_slice_isDefined = function () {
|
||||
TKUnit.assert(typeof array.slice === 'function', "Method 'slice()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_sort_isDefined = function () {
|
||||
TKUnit.assert(typeof array.sort === 'function', "Method 'sort()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_splice_isDefined = function () {
|
||||
TKUnit.assert(typeof array.splice === 'function', "Method 'splice()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_unshift_isDefined = function () {
|
||||
TKUnit.assert(typeof array.unshift === 'function', "Method 'unshift()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_indexOf_isDefined = function () {
|
||||
TKUnit.assert(typeof array.indexOf === 'function', "Method 'indexOf()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_lastIndexOf_isDefined = function () {
|
||||
TKUnit.assert(typeof array.lastIndexOf === 'function', "Method 'lastIndexOf()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_every_isDefined = function () {
|
||||
TKUnit.assert(typeof array.every === 'function', "Method 'every()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_some_isDefined = function () {
|
||||
TKUnit.assert(typeof array.some === 'function', "Method 'some()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_forEach_isDefined = function () {
|
||||
TKUnit.assert(typeof array.forEach === 'function', "Method 'forEach()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_map_isDefined = function () {
|
||||
TKUnit.assert(typeof array.map === 'function', "Method 'map()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_filter_isDefined = function () {
|
||||
TKUnit.assert(typeof array.filter === 'function', "Method 'filter()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_reduce_isDefined = function () {
|
||||
TKUnit.assert(typeof array.reduce === 'function', "Method 'reduce()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_reduce_without_initial_value = function () {
|
||||
const sa = [1, 2, 3];
|
||||
let array: ObservableArray<number> = new ObservableArray(sa);
|
||||
const result = array.reduce((a, b) => a + b);
|
||||
TKUnit.assertEqual(result, 6, 'ObservableArray reduce function broken when initialValue is missing');
|
||||
};
|
||||
|
||||
export const test_reduce_with_initial_value = function () {
|
||||
const sa = [1, 2, 3];
|
||||
let array: ObservableArray<number> = new ObservableArray(sa);
|
||||
const result = array.reduce((a, b) => a + b, 5);
|
||||
TKUnit.assertEqual(result, 11, 'ObservableArray reduce function broken when Initial Value is passed.');
|
||||
};
|
||||
|
||||
export const test_reduce_with_zero_as_initial_value = function () {
|
||||
const sa = [{ prop: 1 }, { prop: 2 }, { prop: 3 }];
|
||||
let array: ObservableArray<any> = new ObservableArray(sa);
|
||||
const result = array.reduce((a, b) => a + b.prop, 0);
|
||||
TKUnit.assertEqual(result, 6, 'ObservableArray reduce function broken when Initial Value is zero.');
|
||||
};
|
||||
|
||||
export const test_reduceRight_isDefined = function () {
|
||||
TKUnit.assert(typeof array.reduceRight === 'function', "Method 'reduceRight()' should be defined!");
|
||||
};
|
||||
|
||||
export const test_reduceRight_without_initial_value = function () {
|
||||
const sa = [1, 2, 3];
|
||||
let array: ObservableArray<number> = new ObservableArray(sa);
|
||||
const result = array.reduceRight((a, b) => a + b);
|
||||
TKUnit.assertEqual(result, 6, 'ObservableArray reduceRight function broken when initialValue is missing');
|
||||
};
|
||||
|
||||
export const test_reduceRight_with_initial_value = function () {
|
||||
const sa = [1, 2, 3];
|
||||
let array: ObservableArray<number> = new ObservableArray(sa);
|
||||
const result = array.reduceRight((a, b) => a + b, 5);
|
||||
TKUnit.assertEqual(result, 11, 'ObservableArray reduceRight function broken when Initial Value is passed.');
|
||||
};
|
||||
|
||||
export const test_reduceRight_with_zero_as_initial_value = function () {
|
||||
const sa = [{ prop: 1 }, { prop: 2 }, { prop: 3 }];
|
||||
let array: ObservableArray<any> = new ObservableArray(sa);
|
||||
const result = array.reduceRight((a, b) => a + b.prop, 0);
|
||||
TKUnit.assertEqual(result, 6, 'ObservableArray reduceRight function broken when Initial Value is zero.');
|
||||
};
|
||||
580
apps/automated/app/data/observable-tests.ts
Normal file
@@ -0,0 +1,580 @@
|
||||
// >> observable-require
|
||||
import { Observable, PropertyChangeData, EventData, WrappedValue, fromObject, fromObjectRecursive } from '@nativescript/core';
|
||||
// << observable-require
|
||||
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import * as types from '@nativescript/core/utils/types';
|
||||
import { ObservableArray } from '@nativescript/core';
|
||||
|
||||
var TESTED_NAME = 'tested';
|
||||
class TestObservable extends Observable {
|
||||
public test() {
|
||||
this._emit(TESTED_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
export var test_Observable_Constructor = function () {
|
||||
// >> observable-creating
|
||||
var json = {
|
||||
Name: 'John',
|
||||
Age: 34,
|
||||
Married: true,
|
||||
};
|
||||
var person = fromObject(json);
|
||||
var name = person.get('Name');
|
||||
var age = person.get('Age');
|
||||
var married = person.get('Married');
|
||||
// console.log(name + " " + age + " " + married); // Prints out "John 34 true" if uncommented.
|
||||
// << observable-creating
|
||||
TKUnit.assert(name === 'John', 'Expected name is John');
|
||||
TKUnit.assert(age === 34, 'Expected age is 34');
|
||||
TKUnit.assert(married === true, 'Expected married is true');
|
||||
};
|
||||
|
||||
export var tests_DummyTestForCodeSnippet = function () {
|
||||
// >> observable-property-change
|
||||
var person = new Observable();
|
||||
person.set('Name', 'John');
|
||||
person.set('Age', 34);
|
||||
person.set('Married', true);
|
||||
person.addEventListener(Observable.propertyChangeEvent, function (pcd: PropertyChangeData) {
|
||||
//console.log(pcd.eventName.toString() + " " + pcd.propertyName.toString() + " " + pcd.value.toString());
|
||||
});
|
||||
person.set('Age', 35);
|
||||
person.set('Married', false);
|
||||
// If uncommented, the console.log above produces the following output:
|
||||
// propertyChange Age 35
|
||||
// propertyChange Married false
|
||||
// << observable-property-change
|
||||
};
|
||||
|
||||
export var test_Observable_Members = function () {
|
||||
var obj = new Observable();
|
||||
TKUnit.assert(types.isDefined(obj.addEventListener), 'Observable.addEventListener not defined');
|
||||
TKUnit.assert(types.isDefined(obj._createPropertyChangeData), 'Observable.createPropertyChangeData not defined');
|
||||
TKUnit.assert(types.isDefined(obj._emit), 'Observable.emit not defined');
|
||||
TKUnit.assert(types.isDefined(obj.get), 'Observable.get not defined');
|
||||
TKUnit.assert(types.isDefined(obj.hasListeners), 'Observable.hasListeners not defined');
|
||||
TKUnit.assert(types.isDefined(obj.notify), 'Observable.notify not defined');
|
||||
TKUnit.assert(types.isDefined(obj.off), 'Observable.off not defined');
|
||||
TKUnit.assert(types.isDefined(obj.on), 'Observable.on not defined');
|
||||
TKUnit.assert(types.isDefined(obj.removeEventListener), 'Observable.removeEventListener not defined');
|
||||
TKUnit.assert(types.isDefined(obj.set), 'Observable.set not defined');
|
||||
};
|
||||
|
||||
export var test_Observable_UpdateAnotherPropertyWithinChangedCallback = function () {
|
||||
var obj = new Observable();
|
||||
|
||||
var changedCallback = function (pcd: PropertyChangeData) {
|
||||
if (pcd.propertyName === 'name') {
|
||||
pcd.object.set('test', 'Changed test');
|
||||
}
|
||||
};
|
||||
|
||||
obj.addEventListener(Observable.propertyChangeEvent, changedCallback);
|
||||
|
||||
obj.set('name', 'Initial name');
|
||||
obj.set('test', 'Initial test');
|
||||
|
||||
TKUnit.assert(obj.get('name') === 'Initial name', 'Initial value for property name is not correct!');
|
||||
TKUnit.assert(obj.get('test') === 'Initial test', 'Initial value for property test is not correct!');
|
||||
|
||||
obj.set('name', 'Changed name');
|
||||
|
||||
TKUnit.assert(obj.get('name') === 'Changed name', 'Changed value for property name is not correct!');
|
||||
TKUnit.assert(obj.get('test') === 'Changed test', 'Changed value for property test is not correct!');
|
||||
};
|
||||
|
||||
// export var test_DependencyObservable_UpdateAnotherPropertyWithinChangedCallback = function () {
|
||||
// var obj = new dependencyObservable.DependencyObservable();
|
||||
|
||||
// function onFirstPropertyChanged(data: dependencyObservable.PropertyChangeData) {
|
||||
// var testObj = <dependencyObservable.DependencyObservable>data.object;
|
||||
// testObj._setValue(secondProperty, "Changed test");
|
||||
// };
|
||||
|
||||
// var firstProperty = new dependencyObservable.Property(
|
||||
// "first",
|
||||
// "obj",
|
||||
// new proxy.PropertyMetadata(
|
||||
// "",
|
||||
// dependencyObservable.PropertyMetadataSettings.None,
|
||||
// onFirstPropertyChanged
|
||||
// )
|
||||
// );
|
||||
|
||||
// var secondProperty = new dependencyObservable.Property(
|
||||
// "second",
|
||||
// "obj",
|
||||
// new proxy.PropertyMetadata(
|
||||
// "",
|
||||
// dependencyObservable.PropertyMetadataSettings.None,
|
||||
// null
|
||||
// )
|
||||
// );
|
||||
|
||||
// obj._setValue(firstProperty, "Initial name");
|
||||
// obj._setValue(secondProperty, "Initial test");
|
||||
|
||||
// TKUnit.assert(obj._getValue(firstProperty) === "Initial name", "Initial value for property name is not correct!");
|
||||
// TKUnit.assert(obj._getValue(secondProperty) === "Initial test", "Initial value for property test is not correct!");
|
||||
|
||||
// obj._setValue(firstProperty, "Changed name");
|
||||
|
||||
// TKUnit.assert(obj._getValue(firstProperty) === "Changed name", "Changed value for property name is not correct!");
|
||||
// TKUnit.assert(obj._getValue(secondProperty) === "Changed test", "Changed value for property test is not correct!");
|
||||
// }
|
||||
|
||||
export var test_Observable_addEventListener_SingleEvent = function () {
|
||||
var obj = new Observable();
|
||||
|
||||
var receivedCount = 0;
|
||||
var callback = function (data: PropertyChangeData) {
|
||||
receivedCount++;
|
||||
TKUnit.assert(data.eventName === Observable.propertyChangeEvent, 'Expected event name ' + Observable.propertyChangeEvent);
|
||||
TKUnit.assert(data.object === obj, 'PropertyChangeData.object value not valid.');
|
||||
TKUnit.assert(data.propertyName === 'testName', 'PropertyChangeData.propertyName value not valid.');
|
||||
TKUnit.assert(data.value === 1, 'PropertyChangeData.value value not valid.');
|
||||
};
|
||||
|
||||
obj.addEventListener(Observable.propertyChangeEvent, callback);
|
||||
obj.set('testName', 1);
|
||||
TKUnit.assert(receivedCount === 1, 'PropertyChanged event not raised properly.');
|
||||
};
|
||||
|
||||
export var test_Observable_addEventListener_MultipleEvents = function () {
|
||||
var obj = new TestObservable();
|
||||
|
||||
var receivedCount = 0;
|
||||
var callback = function (data: EventData) {
|
||||
receivedCount++;
|
||||
TKUnit.assert(data.object === obj, 'EventData.object value not valid.');
|
||||
|
||||
if (data.eventName === Observable.propertyChangeEvent) {
|
||||
var propertyData = <PropertyChangeData>data;
|
||||
TKUnit.assert(propertyData.eventName === Observable.propertyChangeEvent, 'Expected event name ' + Observable.propertyChangeEvent);
|
||||
TKUnit.assert(propertyData.propertyName === 'testName', 'PropertyChangeData.propertyName value not valid.');
|
||||
TKUnit.assert(propertyData.value === 1, 'PropertyChangeData.value value not valid.');
|
||||
} else {
|
||||
TKUnit.assert(data.eventName === TESTED_NAME, 'Expected event name ' + TESTED_NAME);
|
||||
}
|
||||
};
|
||||
|
||||
var events = Observable.propertyChangeEvent + ',' + TESTED_NAME;
|
||||
obj.addEventListener(events, callback);
|
||||
obj.set('testName', 1);
|
||||
obj.test();
|
||||
TKUnit.assert(receivedCount === 2, 'Callbacks not raised properly.');
|
||||
};
|
||||
|
||||
export var test_Observable_addEventListener_MultipleEvents_ShouldTrim = function () {
|
||||
var obj = new TestObservable();
|
||||
|
||||
var receivedCount = 0;
|
||||
var callback = function (data: EventData) {
|
||||
receivedCount++;
|
||||
};
|
||||
|
||||
var events = Observable.propertyChangeEvent + ' , ' + TESTED_NAME;
|
||||
obj.addEventListener(events, callback);
|
||||
TKUnit.assert(obj.hasListeners(Observable.propertyChangeEvent), 'Observable.addEventListener for multiple events should trim each event name.');
|
||||
TKUnit.assert(obj.hasListeners(TESTED_NAME), 'Observable.addEventListener for multiple events should trim each event name.');
|
||||
|
||||
obj.set('testName', 1);
|
||||
obj.test();
|
||||
|
||||
TKUnit.assert(receivedCount === 2, 'Callbacks not raised properly.');
|
||||
};
|
||||
|
||||
export var test_Observable_addEventListener_MultipleCallbacks = function () {
|
||||
var obj = new TestObservable();
|
||||
|
||||
var receivedCount = 0;
|
||||
var callback1 = function (data: EventData) {
|
||||
receivedCount++;
|
||||
};
|
||||
|
||||
var callback2 = function (data: EventData) {
|
||||
receivedCount++;
|
||||
};
|
||||
|
||||
obj.addEventListener(Observable.propertyChangeEvent, callback1);
|
||||
obj.addEventListener(Observable.propertyChangeEvent, callback2);
|
||||
|
||||
obj.set('testName', 1);
|
||||
TKUnit.assert(receivedCount === 2, 'The propertyChanged notification should be raised twice.');
|
||||
};
|
||||
|
||||
export var test_Observable_addEventListener_MultipleCallbacks_MultipleEvents = function () {
|
||||
var obj = new TestObservable();
|
||||
|
||||
var receivedCount = 0;
|
||||
var callback1 = function (data: EventData) {
|
||||
receivedCount++;
|
||||
};
|
||||
|
||||
var callback2 = function (data: EventData) {
|
||||
receivedCount++;
|
||||
};
|
||||
|
||||
var events = Observable.propertyChangeEvent + ' , ' + TESTED_NAME;
|
||||
obj.addEventListener(events, callback1);
|
||||
obj.addEventListener(events, callback2);
|
||||
|
||||
obj.set('testName', 1);
|
||||
obj.test();
|
||||
|
||||
TKUnit.assert(receivedCount === 4, 'The propertyChanged notification should be raised twice.');
|
||||
};
|
||||
|
||||
export var test_Observable_removeEventListener_SingleEvent_SingleCallback = function () {
|
||||
var obj = new Observable();
|
||||
|
||||
var receivedCount = 0;
|
||||
var callback = function (data: EventData) {
|
||||
receivedCount++;
|
||||
};
|
||||
|
||||
obj.addEventListener(Observable.propertyChangeEvent, callback);
|
||||
obj.set('testName', 1);
|
||||
|
||||
obj.removeEventListener(Observable.propertyChangeEvent, callback);
|
||||
TKUnit.assert(!obj.hasListeners(Observable.propertyChangeEvent), 'Observable.removeEventListener not working properly.');
|
||||
|
||||
obj.set('testName', 2);
|
||||
TKUnit.assert(receivedCount === 1, 'Observable.removeEventListener not working properly.');
|
||||
};
|
||||
|
||||
export var test_Observable_removeEventListener_SingleEvent_MultipleCallbacks = function () {
|
||||
var obj = new Observable();
|
||||
|
||||
var receivedCount = 0;
|
||||
var callback1 = function (data: EventData) {
|
||||
receivedCount++;
|
||||
};
|
||||
|
||||
var callback2 = function (data: EventData) {
|
||||
receivedCount++;
|
||||
};
|
||||
|
||||
obj.addEventListener(Observable.propertyChangeEvent, callback1);
|
||||
obj.addEventListener(Observable.propertyChangeEvent, callback2);
|
||||
obj.set('testName', 1);
|
||||
|
||||
obj.removeEventListener(Observable.propertyChangeEvent, callback1);
|
||||
TKUnit.assert(obj.hasListeners(Observable.propertyChangeEvent), 'Observable.removeEventListener not working properly with multiple listeners.');
|
||||
|
||||
obj.set('testName', 2);
|
||||
TKUnit.assert(receivedCount === 3, 'Observable.removeEventListener not working properly with multiple listeners.');
|
||||
|
||||
obj.removeEventListener(Observable.propertyChangeEvent, callback2);
|
||||
TKUnit.assert(!obj.hasListeners(Observable.propertyChangeEvent), 'Observable.removeEventListener not working properly with multiple listeners.');
|
||||
|
||||
obj.set('testName', 3);
|
||||
TKUnit.assert(receivedCount === 3, 'Observable.removeEventListener not working properly with multiple listeners.');
|
||||
};
|
||||
|
||||
export var test_Observable_removeEventListener_MutlipleEvents_SingleCallback = function () {
|
||||
var obj = new TestObservable();
|
||||
|
||||
var receivedCount = 0;
|
||||
var callback = function (data: EventData) {
|
||||
receivedCount++;
|
||||
};
|
||||
|
||||
var events = Observable.propertyChangeEvent + ' , ' + TESTED_NAME;
|
||||
obj.addEventListener(events, callback);
|
||||
|
||||
obj.set('testName', 1);
|
||||
obj.test();
|
||||
|
||||
obj.removeEventListener(events, callback);
|
||||
|
||||
TKUnit.assert(!obj.hasListeners(Observable.propertyChangeEvent), 'Expected result for hasObservers is false');
|
||||
TKUnit.assert(!obj.hasListeners(TESTED_NAME), 'Expected result for hasObservers is false.');
|
||||
|
||||
obj.set('testName', 2);
|
||||
obj.test();
|
||||
|
||||
TKUnit.assert(receivedCount === 2, 'Expected receive count is 2');
|
||||
};
|
||||
|
||||
export var test_Observable_removeEventListener_SingleEvent_NoCallbackSpecified = function () {
|
||||
var obj = new TestObservable();
|
||||
|
||||
var receivedCount = 0;
|
||||
var callback1 = function (data: EventData) {
|
||||
receivedCount++;
|
||||
};
|
||||
|
||||
var callback2 = function (data: EventData) {
|
||||
receivedCount++;
|
||||
};
|
||||
|
||||
obj.addEventListener(Observable.propertyChangeEvent, callback1);
|
||||
obj.addEventListener(Observable.propertyChangeEvent, callback2);
|
||||
|
||||
obj.set('testName', 1);
|
||||
obj.removeEventListener(Observable.propertyChangeEvent);
|
||||
|
||||
TKUnit.assert(!obj.hasListeners(Observable.propertyChangeEvent), 'Expected result for hasObservers is false.');
|
||||
|
||||
obj.set('testName', 2);
|
||||
TKUnit.assert(receivedCount === 2, 'Expected receive count is 2');
|
||||
};
|
||||
|
||||
export var test_Observable_WhenCreatedWithJSON_PropertyChangedWithDotNotation_RaisesPropertyChangedEvent = function () {
|
||||
var json = {
|
||||
count: 5,
|
||||
};
|
||||
var obj = fromObject(json);
|
||||
|
||||
var receivedCount = 0;
|
||||
var callback = function (data: PropertyChangeData) {
|
||||
receivedCount++;
|
||||
TKUnit.assert(data.eventName === Observable.propertyChangeEvent, 'Expected event name ' + Observable.propertyChangeEvent);
|
||||
TKUnit.assert(data.object === obj, 'PropertyChangeData.object value not valid.');
|
||||
TKUnit.assert(data.propertyName === 'count', 'PropertyChangeData.propertyName value not valid.');
|
||||
TKUnit.assert(data.value === 6, 'PropertyChangeData.value value not valid.');
|
||||
};
|
||||
|
||||
obj.addEventListener(Observable.propertyChangeEvent, callback);
|
||||
|
||||
(<any>obj).count++;
|
||||
|
||||
TKUnit.assert(receivedCount === 1, 'PropertyChanged event not raised properly.');
|
||||
};
|
||||
|
||||
export var test_Observable_WhenCreatedWithJSON_PropertyChangedWithBracketsNotation_RaisesPropertyChangedEvent = function () {
|
||||
var json = {
|
||||
count: 5,
|
||||
};
|
||||
var obj = fromObject(json);
|
||||
|
||||
var receivedCount = 0;
|
||||
var callback = function (data: PropertyChangeData) {
|
||||
receivedCount++;
|
||||
TKUnit.assert(data.eventName === Observable.propertyChangeEvent, 'Expected event name ' + Observable.propertyChangeEvent);
|
||||
TKUnit.assert(data.object === obj, 'PropertyChangeData.object value not valid.');
|
||||
TKUnit.assert(data.propertyName === 'count', 'PropertyChangeData.propertyName value not valid.');
|
||||
TKUnit.assert(data.value === 6, 'PropertyChangeData.value value not valid.');
|
||||
};
|
||||
|
||||
obj.addEventListener(Observable.propertyChangeEvent, callback);
|
||||
|
||||
obj['count']++;
|
||||
|
||||
TKUnit.assert(receivedCount === 1, 'PropertyChanged event not raised properly.');
|
||||
};
|
||||
|
||||
export var test_AddingTwoEventHandlersAndRemovingWithinHandlerShouldRaiseAllEvents = function () {
|
||||
var observableInstance = new Observable();
|
||||
var firstHandlerCalled = false;
|
||||
var secondHandlerCalled = false;
|
||||
|
||||
var firstHandler = function (args) {
|
||||
observableInstance.off(Observable.propertyChangeEvent, firstHandler, firstObserver);
|
||||
firstHandlerCalled = true;
|
||||
};
|
||||
|
||||
var secondHandler = function (args) {
|
||||
observableInstance.off(Observable.propertyChangeEvent, secondHandler, secondObserver);
|
||||
secondHandlerCalled = true;
|
||||
};
|
||||
|
||||
var firstObserver = new Observable();
|
||||
var secondObserver = new Observable();
|
||||
|
||||
observableInstance.on(Observable.propertyChangeEvent, firstHandler, firstObserver);
|
||||
observableInstance.on(Observable.propertyChangeEvent, secondHandler, secondObserver);
|
||||
|
||||
observableInstance.set('someProperty', 'some value');
|
||||
|
||||
TKUnit.assertEqual(firstHandlerCalled, true);
|
||||
TKUnit.assertEqual(secondHandlerCalled, true);
|
||||
};
|
||||
|
||||
export var test_ObservableCreatedWithJSON_shouldDistinguishSeparateObjects = function () {
|
||||
var obj1 = { val: 1 };
|
||||
var obj2 = { val: 2 };
|
||||
var observable1 = fromObject(obj1);
|
||||
var observable2 = fromObject(obj2);
|
||||
|
||||
var val1 = observable1.get('val');
|
||||
var val2 = observable2.get('val');
|
||||
TKUnit.assert(val1 === 1 && val2 === 2, `Observable should keep separate objects separate! val1: ${val1}; val2: ${val2};`);
|
||||
|
||||
var propName1;
|
||||
var newValue1;
|
||||
observable1.on(Observable.propertyChangeEvent, (data: PropertyChangeData) => {
|
||||
propName1 = data.propertyName;
|
||||
newValue1 = data.value;
|
||||
});
|
||||
|
||||
var propName2;
|
||||
var newValue2;
|
||||
observable2.on(Observable.propertyChangeEvent, (data: PropertyChangeData) => {
|
||||
propName2 = data.propertyName;
|
||||
newValue2 = data.value;
|
||||
});
|
||||
|
||||
observable1.set('val', 10);
|
||||
TKUnit.assert(propName1 === 'val', "propName1 should be 'val'");
|
||||
TKUnit.assert(newValue1 === 10, 'newValue1 should be 10');
|
||||
|
||||
observable2.set('val', 20);
|
||||
TKUnit.assert(propName2 === 'val', "propName2 should be 'val'");
|
||||
TKUnit.assert(newValue2 === 20, 'newValue2 should be 20');
|
||||
|
||||
val1 = observable1.get('val');
|
||||
val2 = observable2.get('val');
|
||||
TKUnit.assert(val1 === 10 && val2 === 20, `Observable should keep separate objects separate! val1: ${val1}; val2: ${val2};`);
|
||||
};
|
||||
|
||||
export var test_ObservablesCreatedWithJSON_shouldNotInterfereWithOneAnother = function () {
|
||||
var observable1 = fromObject({ property1: 1 });
|
||||
var observable2 = fromObject({ property2: 2 });
|
||||
|
||||
TKUnit.assert(observable1.get('property1') === 1, `Expected: 1; Actual: ${observable1.get('property1')}`);
|
||||
TKUnit.assert(observable1.get('property2') === undefined, `Expected: undefined; Actual: ${observable1.get('property2')}`);
|
||||
|
||||
TKUnit.assert(observable2.get('property1') === undefined, `Expected: undefined; Actual: ${observable2.get('property1')}`);
|
||||
TKUnit.assert(observable2.get('property2') === 2, `Expected: 2; Actual: ${observable2.get('property2')}`);
|
||||
|
||||
var propName1;
|
||||
var newValue1;
|
||||
observable1.on(Observable.propertyChangeEvent, (data: PropertyChangeData) => {
|
||||
propName1 = data.propertyName;
|
||||
newValue1 = data.value;
|
||||
});
|
||||
|
||||
var propName2;
|
||||
var newValue2;
|
||||
observable2.on(Observable.propertyChangeEvent, (data: PropertyChangeData) => {
|
||||
propName2 = data.propertyName;
|
||||
newValue2 = data.value;
|
||||
});
|
||||
|
||||
observable1.set('property1', 10);
|
||||
TKUnit.assert(propName1 === 'property1', "propName1 should be 'property1'");
|
||||
TKUnit.assert(newValue1 === 10, 'newValue1 should be 10');
|
||||
|
||||
observable2.set('property2', 20);
|
||||
TKUnit.assert(propName2 === 'property2', "propName2 should be 'property2'");
|
||||
TKUnit.assert(newValue2 === 20, 'newValue2 should be 20');
|
||||
};
|
||||
|
||||
export function test_ObservablesCreatedWithJSON_shouldNotEmitTwoTimesPropertyChangeEvent() {
|
||||
var testObservable = fromObject({ property1: 1 });
|
||||
var propertyChangeCounter = 0;
|
||||
var propertyChangeHandler = function (args) {
|
||||
propertyChangeCounter++;
|
||||
};
|
||||
testObservable.on(Observable.propertyChangeEvent, propertyChangeHandler);
|
||||
testObservable.set('property1', 2);
|
||||
|
||||
TKUnit.assertEqual(propertyChangeCounter, 1, 'PropertyChange event should be fired only once for a single change.');
|
||||
}
|
||||
|
||||
export function test_ObservableShouldEmitPropertyChangeWithSameObjectUsingWrappedValue() {
|
||||
var testArray = [1];
|
||||
var testObservable = fromObject({ property1: testArray });
|
||||
var propertyChangeCounter = 0;
|
||||
var propertyChangeHandler = function (args) {
|
||||
propertyChangeCounter++;
|
||||
};
|
||||
testObservable.on(Observable.propertyChangeEvent, propertyChangeHandler);
|
||||
testArray.push(2);
|
||||
|
||||
testObservable.set('property1', testArray);
|
||||
|
||||
TKUnit.assertEqual(propertyChangeCounter, 0, 'PropertyChange event should not be fired when the same object instance is passed.');
|
||||
|
||||
testObservable.set('property1', WrappedValue.wrap(testArray));
|
||||
|
||||
TKUnit.assertEqual(propertyChangeCounter, 1, 'PropertyChange event should be fired only once for a single change.');
|
||||
}
|
||||
|
||||
export function test_CorrectEventArgsWhenWrappedValueIsUsed() {
|
||||
let testArray = [1];
|
||||
let testObservable = fromObject({ property1: testArray });
|
||||
let actualArgsValue;
|
||||
let propertyChangeHandler = function (args) {
|
||||
actualArgsValue = args.value;
|
||||
};
|
||||
|
||||
testObservable.on(Observable.propertyChangeEvent, propertyChangeHandler);
|
||||
testArray.push(2);
|
||||
|
||||
let wrappedArray = WrappedValue.wrap(testArray);
|
||||
|
||||
testObservable.set('property1', wrappedArray);
|
||||
|
||||
TKUnit.assertEqual(actualArgsValue, testArray, 'PropertyChange event should be fired with correct value in arguments.');
|
||||
}
|
||||
|
||||
export function test_CorrectPropertyValueAfterUsingWrappedValue() {
|
||||
let testArray = [1];
|
||||
let testObservable = fromObject({ property1: testArray });
|
||||
|
||||
let wrappedArray = WrappedValue.wrap(testArray);
|
||||
|
||||
testObservable.set('property1', wrappedArray);
|
||||
|
||||
TKUnit.assertEqual(testObservable.get('property1'), testArray, 'WrappedValue is used only to execute property change logic and unwrapped value should be used as property value.');
|
||||
}
|
||||
|
||||
export function test_CorrectPropertyValueAfterUsingStringEmptyWrappedValue() {
|
||||
const emptyString = '';
|
||||
let testObservable = fromObject({ property1: emptyString });
|
||||
|
||||
let wrappedEmptyString = WrappedValue.wrap(emptyString);
|
||||
|
||||
testObservable.set('property1', wrappedEmptyString);
|
||||
|
||||
TKUnit.assertEqual(testObservable.get('property1'), emptyString, 'WrappedValue is used only to execute property change logic and unwrapped value should be used as property value.');
|
||||
}
|
||||
|
||||
export function test_NestedObservablesWithObservableArrayShouldNotCrash() {
|
||||
let someObservableArray = new ObservableArray<any>();
|
||||
let testObservable = fromObjectRecursive({
|
||||
firstProp: 'test string',
|
||||
secondProp: someObservableArray,
|
||||
});
|
||||
TKUnit.assert(testObservable !== undefined);
|
||||
}
|
||||
|
||||
export function test_NestedObservableWithNullShouldNotCrash() {
|
||||
let testObservable = fromObjectRecursive({
|
||||
someProperty: null,
|
||||
});
|
||||
TKUnit.assert(testObservable !== undefined);
|
||||
}
|
||||
|
||||
export function test_get_set_on_observables_fromObject_without_property_in_json() {
|
||||
const array = new ObservableArray<any>();
|
||||
const vm = fromObject({});
|
||||
vm.set('p', array);
|
||||
const value1 = vm.get('p');
|
||||
const value2 = (<any>vm).p;
|
||||
TKUnit.assertEqual(value1, array);
|
||||
TKUnit.assertNull(value2);
|
||||
}
|
||||
|
||||
export function test_get_set_on_observables_fromObject_with_property_in_json() {
|
||||
const array = new ObservableArray<any>();
|
||||
const vm = fromObject({ p: null });
|
||||
vm.set('p', array);
|
||||
const value1 = vm.get('p');
|
||||
const value2 = (<any>vm).p;
|
||||
TKUnit.assertEqual(value1, array);
|
||||
TKUnit.assertEqual(value2, array);
|
||||
}
|
||||
|
||||
export function test_fromObjectRecursive_does_not_override_source_object_property() {
|
||||
const myObj = {};
|
||||
const source = { name: 'a', value: myObj };
|
||||
const observable = fromObjectRecursive(source);
|
||||
TKUnit.assertNotNull(observable);
|
||||
TKUnit.assertEqual(source.value, myObj);
|
||||
}
|
||||
172
apps/automated/app/data/virtual-array-tests.ts
Normal file
@@ -0,0 +1,172 @@
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import * as types from '@nativescript/core/utils/types';
|
||||
import { VirtualArray, ChangeType, ChangedData, ItemsLoading } from '@nativescript/core';
|
||||
|
||||
export var test_VirtualArray_shouldCreateArrayFromSpecifiedLength = function () {
|
||||
var array = new VirtualArray<number>(100);
|
||||
|
||||
TKUnit.assert(array.length === 100, 'VirtualArray<T> should create array from specified length!');
|
||||
};
|
||||
|
||||
export var test_VirtualArray_setItemShouldSetCorrectItem = function () {
|
||||
var array = new VirtualArray<number>(100);
|
||||
array.setItem(0, 0);
|
||||
TKUnit.assert(array.getItem(0) === 0, 'VirtualArray<T> setItem() should set correct item!');
|
||||
};
|
||||
|
||||
export var test_VirtualArray_setItemShouldRaiseChangeEventWhenYouSetDifferentItem = function () {
|
||||
var array = new VirtualArray<number>(100);
|
||||
array.loadSize = 15;
|
||||
|
||||
var result: ChangedData<number>;
|
||||
var index = 0;
|
||||
|
||||
array.on(VirtualArray.changeEvent, (args: ChangedData<number>) => {
|
||||
result = args;
|
||||
});
|
||||
|
||||
array.setItem(index, 0);
|
||||
|
||||
TKUnit.assert(result && result.eventName === 'change' && result.action === ChangeType.Update && result.removed.length === 1 && result.index === index && result.addedCount === 1, "VirtualArray<T> setItem() should raise 'change' event with correct args!");
|
||||
|
||||
result = undefined;
|
||||
|
||||
array.setItem(index, 1);
|
||||
|
||||
TKUnit.assert(result && result.eventName === 'change' && result.action === ChangeType.Update && result.removed.length === 1 && result.index === index && result.addedCount === 1, "VirtualArray<T> setItem() should raise 'change' event with correct args!");
|
||||
|
||||
array.on(VirtualArray.itemsLoadingEvent, (args: ItemsLoading) => {
|
||||
// Argument (args) is ItemsLoading.
|
||||
// args.index is start index of the page where the requested index is located.
|
||||
// args.count number of requested items.
|
||||
//
|
||||
// Note: Virtual array will divide total number of items to pages using "loadSize" property value. When you request an
|
||||
// item at specific index the array will raise "itemsLoading" event with "ItemsLoading" argument index set to the first index of the requested page
|
||||
// and count set to number of items in this page.
|
||||
//
|
||||
// Important: If you have already loaded items in the requested page the array will raise multiple times "itemsLoading" event to request
|
||||
// all ranges of still not loaded items in this page.
|
||||
|
||||
var itemsToLoad = new Array<number>();
|
||||
for (var i = 0; i < args.count; i++) {
|
||||
itemsToLoad.push(i + args.index);
|
||||
}
|
||||
|
||||
array.load(args.index, itemsToLoad);
|
||||
});
|
||||
};
|
||||
|
||||
export var test_VirtualArray_loadShouldRaiseChangeEventWithCorrectArgs = function () {
|
||||
var array = new VirtualArray<number>(100);
|
||||
array.loadSize = 15;
|
||||
|
||||
var result: ChangedData<number>;
|
||||
var index = 0;
|
||||
|
||||
array.on(VirtualArray.changeEvent, (args: ChangedData<number>) => {
|
||||
// Argument (args) is ChangedData<T>.
|
||||
// args.eventName is "change".
|
||||
// args.action is "update".
|
||||
// args.removed.length and result.addedCount are equal to number of loaded items with load() method.
|
||||
|
||||
result = args;
|
||||
});
|
||||
|
||||
var itemsToLoad = [0, 1, 2];
|
||||
|
||||
array.load(index, itemsToLoad);
|
||||
|
||||
TKUnit.assert(result && result.eventName === 'change' && result.action === ChangeType.Update && result.removed.length === itemsToLoad.length && result.index === index && result.addedCount === itemsToLoad.length, "VirtualArray<T> load() should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export var test_VirtualArray_lengthIncreaseShouldRaiseChangeEventWithCorrectArgs = function () {
|
||||
var array = new VirtualArray<number>(100);
|
||||
array.loadSize = 15;
|
||||
|
||||
var result: ChangedData<number>;
|
||||
var index = array.length;
|
||||
|
||||
array.on(VirtualArray.changeEvent, (args: ChangedData<number>) => {
|
||||
// Argument (args) is ChangedData<T>.
|
||||
// args.eventName is "change".
|
||||
// args.action is "add".
|
||||
// args.removed.length is 0, result.addedCount is equal to the delta between new and old "length" property values.
|
||||
|
||||
result = args;
|
||||
});
|
||||
|
||||
array.length += array.loadSize;
|
||||
|
||||
TKUnit.assert(result && result.eventName === 'change' && result.action === ChangeType.Add && result.index === index && result.addedCount === array.loadSize && result.removed.length === 0, "VirtualArray<T> length++ should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export var test_VirtualArray_lengthDecreaseShouldRaiseChangeEventWithCorrectArgs = function () {
|
||||
var array = new VirtualArray<number>(100);
|
||||
array.loadSize = 15;
|
||||
|
||||
var result: ChangedData<number>;
|
||||
var index = array.length;
|
||||
|
||||
array.on(VirtualArray.changeEvent, (args: ChangedData<number>) => {
|
||||
// Argument (args) is ChangedData<T>.
|
||||
// args.eventName is "change".
|
||||
// args.action is "remove".
|
||||
// result.addedCount is 0, args.removed.length is equal to the delta between new and old "length" property values.
|
||||
|
||||
result = args;
|
||||
});
|
||||
|
||||
array.length -= array.loadSize;
|
||||
|
||||
TKUnit.assert(result && result.eventName === 'change' && result.action === ChangeType.Delete && result.index === index && result.removed.length === array.loadSize && result.addedCount === 0, "VirtualArray<T> length++ should raise 'change' event with correct args!");
|
||||
};
|
||||
|
||||
export var test_VirtualArray_shouldRaiseItemsLoadingIfIndexIsNotLoadedAndGetItemIsCalled = function () {
|
||||
var array = new VirtualArray<number>(100);
|
||||
array.loadSize = 15;
|
||||
|
||||
var result: ItemsLoading;
|
||||
|
||||
array.on(VirtualArray.itemsLoadingEvent, (args: ItemsLoading) => {
|
||||
result = args;
|
||||
});
|
||||
|
||||
array.getItem(0);
|
||||
|
||||
TKUnit.assert(result.eventName === VirtualArray.itemsLoadingEvent && result.index === 0 && result.count === array.loadSize, "VirtualArray<T> getItem() should raise 'itemsLoading' event with correct args if item is not loaded!");
|
||||
};
|
||||
|
||||
export var test_VirtualArray_shouldNotRaiseItemsLoadingIfIndexIsLoadedAndGetItemIsCalled = function () {
|
||||
var array = new VirtualArray<number>(100);
|
||||
array.setItem(0, 0);
|
||||
array.loadSize = 15;
|
||||
|
||||
var result: ItemsLoading;
|
||||
|
||||
array.on(VirtualArray.itemsLoadingEvent, (args: ItemsLoading) => {
|
||||
result = args;
|
||||
});
|
||||
|
||||
array.getItem(0);
|
||||
|
||||
TKUnit.assert(types.isUndefined(result), "VirtualArray<T> getItem() should not raise 'itemsLoading' event if item is loaded!");
|
||||
};
|
||||
|
||||
export var test_VirtualArray_shouldRaiseItemsLoadingIfIndexIsNotLoadedAndGetItemIsCalledCorrectNumberOfTimesWithCorrectArgs = function () {
|
||||
var array = new VirtualArray<number>(100);
|
||||
array.loadSize = 15;
|
||||
|
||||
array.setItem(0, 0);
|
||||
|
||||
array.setItem(5, 5);
|
||||
|
||||
var result = new Array<ItemsLoading>();
|
||||
|
||||
array.on(VirtualArray.itemsLoadingEvent, (args: ItemsLoading) => {
|
||||
result.push(args);
|
||||
});
|
||||
|
||||
array.getItem(1);
|
||||
|
||||
TKUnit.assert(result.length === 2 && result[0].eventName === VirtualArray.itemsLoadingEvent && result[0].index === 1 && result[0].count === 4 && result[1].eventName === VirtualArray.itemsLoadingEvent && result[1].index === 6 && result[1].count === 9, "VirtualArray<T> getItem() should raise 'itemsLoading' event with correct args!");
|
||||
};
|
||||
395
apps/automated/app/debugger/dom-node-tests.ts
Normal file
@@ -0,0 +1,395 @@
|
||||
import { assert, assertEqual } from '../tk-unit';
|
||||
import { DOMNode } from '@nativescript/core/debugger/dom-node';
|
||||
import { attachDOMInspectorCommandCallbacks, attachCSSInspectorCommandCallbacks, attachDOMInspectorEventCallbacks } from '@nativescript/core/debugger/devtools-elements';
|
||||
import { InspectorCommands, InspectorEvents } from '@nativescript/core/debugger/devtools-elements';
|
||||
import { unsetValue } from '@nativescript/core/ui/core/properties';
|
||||
import { Button } from '@nativescript/core/ui/button';
|
||||
import { Slider } from '@nativescript/core/ui/slider';
|
||||
import { Label } from '@nativescript/core/ui/label';
|
||||
import { textProperty } from '@nativescript/core/ui/text-base';
|
||||
import { TextView } from '@nativescript/core/ui/text-view';
|
||||
import { StackLayout } from '@nativescript/core/ui/layouts/stack-layout';
|
||||
import { isAndroid } from '@nativescript/core/platform';
|
||||
|
||||
let originalInspectorGlobal: InspectorCommands & InspectorEvents;
|
||||
|
||||
let currentInspector: InspectorCommands & InspectorEvents;
|
||||
function getTestInspector(): InspectorCommands & InspectorEvents {
|
||||
let inspector = {
|
||||
getDocument(): any {
|
||||
return {};
|
||||
},
|
||||
removeNode(nodeId: number): void {
|
||||
/* */
|
||||
},
|
||||
getComputedStylesForNode(nodeId: number): any {
|
||||
return [];
|
||||
},
|
||||
setAttributeAsText(nodeId: number, text: string, name: string): void {
|
||||
/* */
|
||||
},
|
||||
|
||||
childNodeInserted(parentId: number, lastId: number, node: string | DOMNode): void {
|
||||
/* to be replaced */
|
||||
},
|
||||
childNodeRemoved(parentId: number, nodeId: number): void {
|
||||
/* to be replaced */
|
||||
},
|
||||
attributeModified(nodeId: number, attrName: string, attrValue: string) {
|
||||
/* to be replaced */
|
||||
},
|
||||
attributeRemoved(nodeId: number, attrName: string) {
|
||||
/* to be replaced */
|
||||
},
|
||||
};
|
||||
|
||||
attachDOMInspectorCommandCallbacks(inspector);
|
||||
attachDOMInspectorEventCallbacks(inspector);
|
||||
attachCSSInspectorCommandCallbacks(inspector);
|
||||
|
||||
return inspector;
|
||||
}
|
||||
|
||||
function getIOSDOMInspector() {
|
||||
return {
|
||||
events: {
|
||||
childNodeInserted(parentId: number, lastId: number, node: DOMNode): void {
|
||||
return;
|
||||
},
|
||||
childNodeRemoved(parentId: number, nodeId: number): void {
|
||||
return;
|
||||
},
|
||||
attributeModified(nodeId: number, attrName: string, attrValue: string): void {
|
||||
return;
|
||||
},
|
||||
attributeRemoved(nodeId: number, attrName: string): void {
|
||||
return;
|
||||
},
|
||||
},
|
||||
commands: {
|
||||
getDocument(): any {
|
||||
return {};
|
||||
},
|
||||
removeNode(nodeId: number): void {
|
||||
/* */
|
||||
},
|
||||
getComputedStylesForNode(nodeId: number): any {
|
||||
return [];
|
||||
},
|
||||
setAttributeAsText(nodeId: number, text: string, name: string): void {
|
||||
/* */
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function setUp(): void {
|
||||
if (isAndroid) {
|
||||
originalInspectorGlobal = global.__inspector;
|
||||
currentInspector = getTestInspector();
|
||||
global.__inspector = currentInspector;
|
||||
} else {
|
||||
let domInspector = getIOSDOMInspector();
|
||||
currentInspector = getTestInspector();
|
||||
domInspector.events = currentInspector;
|
||||
}
|
||||
}
|
||||
|
||||
export function tearDown(): void {
|
||||
if (isAndroid) {
|
||||
global.__inspector = originalInspectorGlobal;
|
||||
}
|
||||
}
|
||||
|
||||
function assertAttribute(domNode: DOMNode, name: string, value: any) {
|
||||
const propIdx = domNode.attributes.indexOf(name);
|
||||
assert(propIdx >= 0, `Attribute ${name} not found`);
|
||||
assertEqual(domNode.attributes[propIdx + 1], value);
|
||||
}
|
||||
|
||||
export function test_custom_attribute_is_reported_in_dom_node() {
|
||||
const btn = new Button();
|
||||
btn['test_prop'] = 'test_value';
|
||||
btn.ensureDomNode();
|
||||
const domNode = btn.domNode;
|
||||
assertAttribute(domNode, 'test_prop', 'test_value');
|
||||
}
|
||||
|
||||
export function test_custom__falsy_attribute_is_reported_in_dom_node() {
|
||||
const btn = new Button();
|
||||
btn['test_prop_null'] = null;
|
||||
btn['test_prop_0'] = 0;
|
||||
btn['test_prop_undefined'] = undefined;
|
||||
btn['test_prop_empty_string'] = '';
|
||||
|
||||
btn.ensureDomNode();
|
||||
const domNode = btn.domNode;
|
||||
assertAttribute(domNode, 'test_prop_null', null + '');
|
||||
assertAttribute(domNode, 'test_prop_0', 0 + '');
|
||||
assertAttribute(domNode, 'test_prop_undefined', undefined + '');
|
||||
assertAttribute(domNode, 'test_prop_empty_string', '');
|
||||
}
|
||||
|
||||
export function test_property_is_reported_in_dom_node() {
|
||||
const btn = new Button();
|
||||
btn.text = 'test_value';
|
||||
btn.ensureDomNode();
|
||||
const domNode = btn.domNode;
|
||||
assertAttribute(domNode, 'text', 'test_value');
|
||||
}
|
||||
|
||||
export function test_childNodeInserted_in_dom_node() {
|
||||
let childNodeInsertedCalled = false;
|
||||
let actualParentId = 0;
|
||||
let expectedParentId = 0;
|
||||
|
||||
currentInspector.childNodeInserted = (parentId, lastNodeId, node) => {
|
||||
childNodeInsertedCalled = true;
|
||||
actualParentId = parentId;
|
||||
};
|
||||
|
||||
const stack = new StackLayout();
|
||||
stack.ensureDomNode();
|
||||
expectedParentId = stack._domId;
|
||||
|
||||
const btn1 = new Button();
|
||||
btn1.text = 'button1';
|
||||
stack.addChild(btn1);
|
||||
|
||||
assert(childNodeInsertedCalled, 'global inspector childNodeInserted not called.');
|
||||
assertEqual(actualParentId, expectedParentId);
|
||||
}
|
||||
|
||||
export function test_childNodeInserted_at_index_in_dom_node() {
|
||||
const stack = new StackLayout();
|
||||
stack.ensureDomNode();
|
||||
|
||||
// child index 0
|
||||
const btn1 = new Button();
|
||||
btn1.text = 'button1';
|
||||
stack.addChild(btn1);
|
||||
|
||||
// child index 1
|
||||
const btn2 = new Button();
|
||||
btn2.text = 'button2';
|
||||
stack.addChild(btn2);
|
||||
|
||||
// child index 2
|
||||
const btn3 = new Button();
|
||||
btn3.text = 'button3';
|
||||
stack.addChild(btn3);
|
||||
|
||||
const lbl = new Label();
|
||||
lbl.text = 'label me this';
|
||||
|
||||
let called = false;
|
||||
currentInspector.childNodeInserted = (parentId, lastNodeId, node: any) => {
|
||||
assertEqual(lastNodeId, btn1._domId, "Child inserted at index 1's previous sibling does not match.");
|
||||
assertEqual(node.toObject().nodeId, lbl._domId, "Child id doesn't match");
|
||||
called = true;
|
||||
};
|
||||
|
||||
stack.insertChild(lbl, 1);
|
||||
assert(called, 'childNodeInserted not called');
|
||||
}
|
||||
|
||||
export function test_childNodeRemoved_in_dom_node() {
|
||||
let childNodeRemovedCalled = false;
|
||||
let actualRemovedNodeId = 0;
|
||||
let expectedRemovedNodeId = 0;
|
||||
|
||||
currentInspector.childNodeRemoved = (parentId, nodeId) => {
|
||||
childNodeRemovedCalled = true;
|
||||
actualRemovedNodeId = nodeId;
|
||||
};
|
||||
|
||||
const stack = new StackLayout();
|
||||
stack.ensureDomNode();
|
||||
|
||||
const btn1 = new Button();
|
||||
btn1.text = 'button1';
|
||||
expectedRemovedNodeId = btn1._domId;
|
||||
stack.addChild(btn1);
|
||||
|
||||
const btn2 = new Button();
|
||||
btn2.text = 'button2';
|
||||
stack.addChild(btn2);
|
||||
|
||||
stack.removeChild(btn1);
|
||||
console.log('btn2: ' + btn2);
|
||||
|
||||
assert(childNodeRemovedCalled, 'global inspector childNodeRemoved not called.');
|
||||
assertEqual(actualRemovedNodeId, expectedRemovedNodeId);
|
||||
}
|
||||
|
||||
export function test_falsy_property_is_reported_in_dom_node() {
|
||||
const btn = new Button();
|
||||
btn.text = null;
|
||||
btn.ensureDomNode();
|
||||
const domNode = btn.domNode;
|
||||
assertAttribute(domNode, 'text', 'null');
|
||||
|
||||
btn.text = undefined;
|
||||
domNode.loadAttributes();
|
||||
assertAttribute(domNode, 'text', 'undefined');
|
||||
}
|
||||
|
||||
export function test_property_change_calls_attributeModified() {
|
||||
const btn = new Button();
|
||||
btn.ensureDomNode();
|
||||
const domNode = btn.domNode;
|
||||
|
||||
let callbackCalled = false;
|
||||
currentInspector.attributeModified = (nodeId: number, attrName: string, attrValue: string) => {
|
||||
assertEqual(nodeId, domNode.nodeId, 'nodeId');
|
||||
assertEqual(attrName, 'text', 'attrName');
|
||||
assertEqual(attrValue, 'new value', 'attrValue');
|
||||
callbackCalled = true;
|
||||
};
|
||||
|
||||
btn.text = 'new value';
|
||||
|
||||
assert(callbackCalled, 'attributeModified not called');
|
||||
}
|
||||
|
||||
export function test_property_change_from_native_calls_attributeModified() {
|
||||
const tv = new TextView();
|
||||
tv.ensureDomNode();
|
||||
const domNode = tv.domNode;
|
||||
|
||||
let callbackCalled = false;
|
||||
currentInspector.attributeModified = (nodeId: number, attrName: string, attrValue: string) => {
|
||||
assertEqual(nodeId, domNode.nodeId, 'nodeId');
|
||||
assertEqual(attrName, 'text', 'attrName');
|
||||
assertEqual(attrValue, 'new value', 'attrValue');
|
||||
callbackCalled = true;
|
||||
};
|
||||
|
||||
textProperty.nativeValueChange(tv, 'new value');
|
||||
|
||||
assert(callbackCalled, 'attributeModified not called');
|
||||
}
|
||||
|
||||
export function test_property_reset_calls_attributeRemoved() {
|
||||
const btn = new Button();
|
||||
btn.text = 'some value';
|
||||
btn.ensureDomNode();
|
||||
const domNode = btn.domNode;
|
||||
|
||||
let callbackCalled = false;
|
||||
currentInspector.attributeRemoved = (nodeId: number, attrName: string) => {
|
||||
assertEqual(nodeId, domNode.nodeId, 'nodeId');
|
||||
assertEqual(attrName, 'text', 'attrName');
|
||||
callbackCalled = true;
|
||||
};
|
||||
|
||||
btn.text = unsetValue;
|
||||
|
||||
assert(callbackCalled, 'attributeRemoved not called');
|
||||
}
|
||||
|
||||
export function test_coercible_property_change_calls_attributeModified() {
|
||||
const slider = new Slider();
|
||||
slider.ensureDomNode();
|
||||
const domNode = slider.domNode;
|
||||
|
||||
let callbackCalled = false;
|
||||
currentInspector.attributeModified = (nodeId: number, attrName: string, attrValue: string) => {
|
||||
assertEqual(nodeId, domNode.nodeId, 'nodeId');
|
||||
assertEqual(attrName, 'value', 'attrName');
|
||||
assertEqual(attrValue, '10', 'attrValue');
|
||||
callbackCalled = true;
|
||||
};
|
||||
|
||||
slider.value = 10;
|
||||
|
||||
assert(callbackCalled, 'attributeModified not called');
|
||||
}
|
||||
|
||||
export function test_coercible_property_reset_calls_attributeRemoved() {
|
||||
const slider = new Slider();
|
||||
slider.value = 10;
|
||||
slider.ensureDomNode();
|
||||
const domNode = slider.domNode;
|
||||
|
||||
let callbackCalled = false;
|
||||
currentInspector.attributeRemoved = (nodeId: number, attrName: string) => {
|
||||
assertEqual(nodeId, domNode.nodeId, 'nodeId');
|
||||
assertEqual(attrName, 'value', 'attrName');
|
||||
callbackCalled = true;
|
||||
};
|
||||
|
||||
slider.value = unsetValue;
|
||||
|
||||
assert(callbackCalled, 'attributeRemoved not called');
|
||||
}
|
||||
|
||||
export function test_inspector_ui_setAttributeAsText_set_existing_property() {
|
||||
// Arrange
|
||||
const label = new Label();
|
||||
|
||||
label.text = 'original label';
|
||||
const expectedValue = 'updated label';
|
||||
|
||||
label.ensureDomNode();
|
||||
|
||||
// Act
|
||||
// simulate call from the inspector UI
|
||||
currentInspector.setAttributeAsText(label.domNode.nodeId, "text='" + expectedValue + "'", 'text');
|
||||
|
||||
// Assert
|
||||
assertEqual(label.text, expectedValue);
|
||||
}
|
||||
|
||||
export function test_inspector_ui_setAttributeAsText_remove_existing_property() {
|
||||
// Arrange
|
||||
const label = new Label();
|
||||
label.text = 'original label';
|
||||
|
||||
label.ensureDomNode();
|
||||
|
||||
// Act
|
||||
// simulate call from the inspector UI
|
||||
currentInspector.setAttributeAsText(label.domNode.nodeId, '' /* empty value - removes the attribute */, 'text');
|
||||
|
||||
// Assert
|
||||
assertEqual(label.text, '');
|
||||
}
|
||||
|
||||
export function test_inspector_ui_setAttributeAsText_set_new_property() {
|
||||
// Arrange
|
||||
const label = new Label();
|
||||
const expectedValue = 'custom';
|
||||
|
||||
label.ensureDomNode();
|
||||
|
||||
// Act
|
||||
// simulate call from the inspector UI
|
||||
currentInspector.setAttributeAsText(label.domNode.nodeId, "data-attr='" + expectedValue + "'" /* data-attr="custom" */, ' ' /* empty attr name initially */);
|
||||
|
||||
// Assert
|
||||
assertEqual(label['data-attr'], expectedValue);
|
||||
}
|
||||
|
||||
export function test_inspector_ui_removeNode() {
|
||||
let childNodeRemovedCalled = false;
|
||||
let stack = new StackLayout();
|
||||
let label = new Label();
|
||||
stack.addChild(label);
|
||||
|
||||
stack.ensureDomNode();
|
||||
label.ensureDomNode();
|
||||
|
||||
let expectedParentId = stack.domNode.nodeId;
|
||||
let expectedNodeId = label.domNode.nodeId;
|
||||
|
||||
currentInspector.childNodeRemoved = (parentId, nodeId) => {
|
||||
childNodeRemovedCalled = true;
|
||||
assertEqual(parentId, expectedParentId);
|
||||
assertEqual(nodeId, expectedNodeId);
|
||||
};
|
||||
|
||||
currentInspector.removeNode(label.domNode.nodeId);
|
||||
|
||||
assert(childNodeRemovedCalled, 'childNodeRemoved callback not called.');
|
||||
}
|
||||
204
apps/automated/app/fetch/fetch-tests.ts
Normal file
@@ -0,0 +1,204 @@
|
||||
/* tslint:disable:no-unused-variable */
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import * as types from '@nativescript/core/utils/types';
|
||||
|
||||
export var test_fetch_defined = function () {
|
||||
TKUnit.assert(types.isDefined(fetch), 'Method fetch() should be defined!');
|
||||
};
|
||||
|
||||
export var test_fetch = function (done: (err: Error, res?: string) => void) {
|
||||
// >> fetch-response
|
||||
fetch('https://httpbin.org/get')
|
||||
.then(function (r) {
|
||||
// Argument (r) is Response!
|
||||
// >> (hide)
|
||||
TKUnit.assert(r instanceof Response, 'Result from fetch() should be valid Response object! Actual result is: ' + r);
|
||||
done(null);
|
||||
// << (hide)
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
// << fetch-response
|
||||
};
|
||||
|
||||
export var test_fetch_text = function (done: (err: Error, res?: string) => void) {
|
||||
// >> fetch-string
|
||||
fetch('https://httpbin.org/get')
|
||||
.then((response) => response.text())
|
||||
.then(function (r) {
|
||||
// Argument (r) is string!
|
||||
// >> (hide)
|
||||
TKUnit.assert(types.isString(r), 'Result from text() should be string! Actual result is: ' + r);
|
||||
done(null);
|
||||
// << (hide)
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
// << fetch-string
|
||||
};
|
||||
|
||||
export var test_fetch_json = function (done: (err: Error, res?: string) => void) {
|
||||
// >> fetch-json
|
||||
fetch('https://httpbin.org/get')
|
||||
.then((response) => response.json())
|
||||
.then(function (r) {
|
||||
// Argument (r) is JSON object!
|
||||
// >> (hide)
|
||||
TKUnit.assertNotNull(r, 'Result from json() should be JSON object!');
|
||||
done(null);
|
||||
// << (hide)
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
// << fetch-json
|
||||
};
|
||||
|
||||
export var test_fetch_formData = function (done: (err: Error, res?: string) => void) {
|
||||
// >> fetch-formdata
|
||||
fetch('https://httpbin.org/get')
|
||||
.then((response) => response.formData())
|
||||
.then(function (r) {
|
||||
// Argument (r) is FormData object!
|
||||
// >> (hide)
|
||||
TKUnit.assert(r instanceof FormData, 'Result from formData() should be FormData object! Actual result is: ' + r);
|
||||
done(null);
|
||||
// << (hide)
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
// << fetch-formdata
|
||||
};
|
||||
|
||||
export var test_fetch_blob = function (done: (err: Error, res?: string) => void) {
|
||||
// >> fetch-blob
|
||||
fetch('https://httpbin.org/get')
|
||||
.then((response) => response.blob())
|
||||
.then(function (r) {
|
||||
// Argument (r) is Blob object!
|
||||
// >> (hide)
|
||||
TKUnit.assertNotNull(r, 'Result from blob() should be Blob object!');
|
||||
done(null);
|
||||
// << (hide)
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
// << fetch-blob
|
||||
};
|
||||
|
||||
export var test_fetch_arraybuffer = function (done: (err: Error, res?: string) => void) {
|
||||
// >> fetch-arraybuffer
|
||||
fetch('https://httpbin.org/get')
|
||||
.then((response) => response.arrayBuffer())
|
||||
.then(function (r) {
|
||||
// Argument (r) is ArrayBuffer object!
|
||||
// >> (hide)
|
||||
TKUnit.assertNotNull(r, 'Result from arrayBuffer() should be ArrayBuffer object!');
|
||||
done(null);
|
||||
// << (hide)
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
// << fetch-arraybuffer
|
||||
};
|
||||
|
||||
export var test_fetch_fail_invalid_url = function (done) {
|
||||
var completed: boolean;
|
||||
var isReady = function () {
|
||||
return completed;
|
||||
};
|
||||
|
||||
fetch('hgfttp://httpbin.org/get')
|
||||
.catch(function (e) {
|
||||
completed = true;
|
||||
done(null);
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
};
|
||||
|
||||
// Note: fetch is unable to do url validation
|
||||
// export var test_fetch_invalid_url_fail_message = function (done) {
|
||||
// fetch("hgfttp://httpbin.org/get").catch(function (e: TypeError) {
|
||||
// TKUnit.assert(e.message.match(/Network request failed:.{2,}/), "Failure message should contain details on the failure. Actual message was: " + e.message);
|
||||
// done(null);
|
||||
// }).catch(failOnError(done));
|
||||
// };
|
||||
|
||||
export var test_fetch_response_status = function (done) {
|
||||
// >> fetch-status-response
|
||||
fetch('https://httpbin.org/get')
|
||||
.then(function (response) {
|
||||
// Argument (response) is Response!
|
||||
var statusCode = response.status;
|
||||
// >> (hide)
|
||||
TKUnit.assert(types.isDefined(statusCode), 'response.status should be defined! Actual result is: ' + statusCode);
|
||||
done(null);
|
||||
// << (hide)
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
// << fetch-status-response
|
||||
};
|
||||
|
||||
export var test_fetch_response_headers = function (done) {
|
||||
// >> fetch-headers-response
|
||||
fetch('https://httpbin.org/get')
|
||||
.then(function (response) {
|
||||
// Argument (response) is Response!
|
||||
// var all = response.headers.getAll();
|
||||
// >> (hide)
|
||||
TKUnit.assert(types.isDefined(response.headers), 'response.headers should be defined! Actual result is: ' + response.headers);
|
||||
done(null);
|
||||
// << (hide)
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
// << fetch-headers-response
|
||||
};
|
||||
|
||||
export var test_fetch_headers_sent = function (done) {
|
||||
fetch('https://httpbin.org/get', {
|
||||
method: 'GET',
|
||||
headers: new Headers({ 'Content-Type': 'application/json' }),
|
||||
})
|
||||
.then(function (response) {
|
||||
var result = response.headers;
|
||||
TKUnit.assert(result.get('Content-Type') === 'application/json', 'Headers not sent/received properly! Actual result is: ' + result);
|
||||
done(null);
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
};
|
||||
|
||||
export var test_fetch_post_form_data = function (done) {
|
||||
var data = new FormData();
|
||||
data.append('MyVariableOne', 'ValueOne');
|
||||
data.append('MyVariableTwo', 'ValueTwo');
|
||||
|
||||
fetch('https://httpbin.org/post', {
|
||||
method: 'POST',
|
||||
headers: new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' }),
|
||||
body: data,
|
||||
})
|
||||
.then((r) => {
|
||||
return r.formData();
|
||||
})
|
||||
.then(function (r) {
|
||||
TKUnit.assert(r instanceof FormData, 'Content not sent/received properly! Actual result is: ' + r);
|
||||
done(null);
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
};
|
||||
|
||||
export var test_fetch_post_json = function (done) {
|
||||
// >> fetch-post-json
|
||||
fetch('https://httpbin.org/post', {
|
||||
method: 'POST',
|
||||
headers: new Headers({ 'Content-Type': 'application/json' }),
|
||||
body: JSON.stringify({ MyVariableOne: 'ValueOne', MyVariableTwo: 'ValueTwo' }),
|
||||
})
|
||||
.then((r) => r.json())
|
||||
.then(function (r) {
|
||||
// >> (hide)
|
||||
TKUnit.assert(r.json['MyVariableOne'] === 'ValueOne' && r.json['MyVariableTwo'] === 'ValueTwo', 'Content not sent/received properly! Actual result is: ' + r.json);
|
||||
done(null);
|
||||
// << (hide)
|
||||
// console.log(result);
|
||||
})
|
||||
.catch(failOnError(done));
|
||||
// << fetch-post-json
|
||||
};
|
||||
|
||||
const failOnError = function (done: (err: Error, res?: string) => void) {
|
||||
return (e) => done(e);
|
||||
};
|
||||
@@ -0,0 +1,49 @@
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import { knownFolders, path, File, Folder } from '@nativescript/core';
|
||||
|
||||
export var test_UTF8_BOM_is_not_returned = function () {
|
||||
const folder1 = path.join(knownFolders.documents().path, 'file-system-access-tests');
|
||||
if (!Folder.exists(folder1)) {
|
||||
Folder.fromPath(folder1);
|
||||
}
|
||||
var filePath = path.join(folder1, 'xml.expected');
|
||||
var file = File.fromPath(filePath);
|
||||
|
||||
var onError = function (error) {
|
||||
TKUnit.assert(false, 'Could not read file xml.expected');
|
||||
};
|
||||
|
||||
var text = file.readTextSync(onError);
|
||||
if (text) {
|
||||
var actualCharCode = text.charCodeAt(0);
|
||||
var expectedCharCode = '{'.charCodeAt(0);
|
||||
TKUnit.assert(actualCharCode === expectedCharCode, 'Actual character code: ' + actualCharCode + '; Expected character code: ' + expectedCharCode);
|
||||
}
|
||||
};
|
||||
|
||||
export var test_file_exists_on_folder = function () {
|
||||
const folder1 = path.join(knownFolders.documents().path, 'file-system-access-tests');
|
||||
if (!Folder.exists(folder1)) {
|
||||
Folder.fromPath(folder1);
|
||||
}
|
||||
var filePath = path.join(folder1, 'folder');
|
||||
if (!Folder.exists(filePath)) {
|
||||
Folder.fromPath(filePath);
|
||||
}
|
||||
|
||||
if (!Folder.exists(filePath)) {
|
||||
TKUnit.assert(false, `Could not read path ${filePath}`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
TKUnit.assertTrue(File.exists(filePath), 'File.exists() returned false for folder!');
|
||||
};
|
||||
|
||||
export var test_leading_slash_is_not_returned = function () {
|
||||
var parts = ['app', 'tns_modules', 'fileName'];
|
||||
var expected = parts.join('/');
|
||||
var filePath = path.join(...parts);
|
||||
|
||||
TKUnit.assertEqual(filePath, expected, 'Leading slash should not be part of the path');
|
||||
};
|
||||
700
apps/automated/app/file-system/file-system-tests.ts
Normal file
@@ -0,0 +1,700 @@
|
||||
/* tslint:disable:no-unused-variable */
|
||||
// >> file-system-require
|
||||
import * as fs from '@nativescript/core/file-system';
|
||||
// << file-system-require
|
||||
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import * as appModule from '@nativescript/core/application';
|
||||
import { isIOS, Device, platformNames } from '@nativescript/core';
|
||||
|
||||
export var testPathNormalize = function () {
|
||||
// >> file-system-normalize
|
||||
var documents = fs.knownFolders.documents();
|
||||
var testPath = '///test.txt';
|
||||
// Get a normalized path such as <folder.path>/test.txt from <folder.path>///test.txt
|
||||
var normalizedPath = fs.path.normalize(documents.path + testPath);
|
||||
// >> (hide)
|
||||
var expected = documents.path + '/test.txt';
|
||||
TKUnit.assert(normalizedPath === expected);
|
||||
// << (hide)
|
||||
// << file-system-normalize
|
||||
};
|
||||
|
||||
export var testPathJoin = function () {
|
||||
// >> file-system-multiple-args
|
||||
var documents = fs.knownFolders.documents();
|
||||
// Generate a path like <documents.path>/myFiles/test.txt
|
||||
var path = fs.path.join(documents.path, 'myFiles', 'test.txt');
|
||||
// >> (hide)
|
||||
var expected = documents.path + '/myFiles/test.txt';
|
||||
TKUnit.assert(path === expected);
|
||||
// << (hide)
|
||||
// << file-system-multiple-args
|
||||
};
|
||||
|
||||
export var testPathSeparator = function () {
|
||||
// >> file-system-separator
|
||||
// An OS dependent path separator, "\" or "/".
|
||||
var separator = fs.path.separator;
|
||||
// >> (hide)
|
||||
var expected = '/';
|
||||
TKUnit.assert(separator === expected);
|
||||
// << (hide)
|
||||
// << file-system-separator
|
||||
};
|
||||
|
||||
export var testFileFromPath = function () {
|
||||
// >> file-system-create
|
||||
var documents = fs.knownFolders.documents();
|
||||
var path = fs.path.join(documents.path, 'FileFromPath.txt');
|
||||
var file = fs.File.fromPath(path);
|
||||
|
||||
// Writing text to the file.
|
||||
file.writeText('Something').then(
|
||||
function () {
|
||||
// Succeeded writing to the file.
|
||||
// >> (hide)
|
||||
file.readText().then(
|
||||
function (content) {
|
||||
TKUnit.assert(content === 'Something', 'File read/write not working.');
|
||||
file.remove();
|
||||
},
|
||||
function (error) {
|
||||
TKUnit.assert(false, 'Failed to read/write text');
|
||||
//console.dir(error);
|
||||
}
|
||||
);
|
||||
// << (hide)
|
||||
},
|
||||
function (error) {
|
||||
// Failed to write to the file.
|
||||
// >> (hide)
|
||||
TKUnit.assert(false, 'Failed to read/write text');
|
||||
//console.dir(error);
|
||||
// << (hide)
|
||||
}
|
||||
);
|
||||
// << file-system-create
|
||||
};
|
||||
|
||||
export var testFolderFromPath = function () {
|
||||
// >> file-system-create-folder
|
||||
var path = fs.path.join(fs.knownFolders.documents().path, 'music');
|
||||
var folder = fs.Folder.fromPath(path);
|
||||
// >> (hide)
|
||||
TKUnit.assert(<any>folder, 'Folder.getFolder API not working.');
|
||||
TKUnit.assert(fs.Folder.exists(folder.path), 'Folder.getFolder API not working.');
|
||||
folder.remove();
|
||||
// << (hide)
|
||||
// << file-system-create-folder
|
||||
};
|
||||
|
||||
export var testFileWrite = function () {
|
||||
// >> file-system-write-string
|
||||
var documents = fs.knownFolders.documents();
|
||||
var file = documents.getFile('Test_Write.txt');
|
||||
|
||||
// Writing text to the file.
|
||||
file.writeText('Something').then(
|
||||
function () {
|
||||
// Succeeded writing to the file.
|
||||
// >> (hide)
|
||||
file.readText().then(
|
||||
function (content) {
|
||||
TKUnit.assert(content === 'Something', 'File read/write not working.');
|
||||
file.remove();
|
||||
},
|
||||
function (error) {
|
||||
TKUnit.assert(false, 'Failed to read/write text');
|
||||
//console.dir(error);
|
||||
}
|
||||
);
|
||||
// << (hide)
|
||||
},
|
||||
function (error) {
|
||||
// Failed to write to the file.
|
||||
// >> (hide)
|
||||
TKUnit.assert(false, 'Failed to read/write text');
|
||||
//console.dir(error);
|
||||
// << (hide)
|
||||
}
|
||||
);
|
||||
// << file-system-write-string
|
||||
};
|
||||
|
||||
export var testGetFile = function () {
|
||||
// >> file-system-create-file
|
||||
var documents = fs.knownFolders.documents();
|
||||
var file = documents.getFile('NewFileToCreate.txt');
|
||||
// >> (hide)
|
||||
TKUnit.assert(<any>file, 'File.getFile API not working.');
|
||||
TKUnit.assert(fs.File.exists(file.path), 'File.getFile API not working.');
|
||||
file.remove();
|
||||
// << (hide)
|
||||
// << file-system-create-file
|
||||
};
|
||||
|
||||
export var testGetFolder = function () {
|
||||
// >> file-system-get-folder
|
||||
var documents = fs.knownFolders.documents();
|
||||
var folder = documents.getFolder('NewFolderToCreate');
|
||||
// >> (hide)
|
||||
TKUnit.assert(<any>folder, 'Folder.getFolder API not working.');
|
||||
TKUnit.assert(fs.Folder.exists(folder.path), 'Folder.getFolder API not working.');
|
||||
folder.remove();
|
||||
// << (hide)
|
||||
// << file-system-get-folder
|
||||
};
|
||||
|
||||
export var testFileRead = function () {
|
||||
// >> file-system-example-text
|
||||
var documents = fs.knownFolders.documents();
|
||||
var myFile = documents.getFile('Test_Write.txt');
|
||||
|
||||
var written: boolean;
|
||||
// Writing text to the file.
|
||||
myFile.writeText('Something').then(
|
||||
function () {
|
||||
// Succeeded writing to the file.
|
||||
|
||||
// Getting back the contents of the file.
|
||||
myFile.readText().then(
|
||||
function (content) {
|
||||
// Successfully read the file's content.
|
||||
// >> (hide)
|
||||
written = content === 'Something';
|
||||
TKUnit.assert(written, 'File read/write not working.');
|
||||
myFile.remove();
|
||||
// << (hide)
|
||||
},
|
||||
function (error) {
|
||||
// Failed to read from the file.
|
||||
// >> (hide)
|
||||
TKUnit.assert(false, 'Failed to read/write text');
|
||||
//console.dir(error);
|
||||
// << (hide)
|
||||
}
|
||||
);
|
||||
},
|
||||
function (error) {
|
||||
// Failed to write to the file.
|
||||
// >> (hide)
|
||||
TKUnit.assert(false, 'Failed to read/write text');
|
||||
//console.dir(error);
|
||||
// << (hide)
|
||||
}
|
||||
);
|
||||
// << file-system-example-text
|
||||
};
|
||||
|
||||
export var testFileReadWriteBinary = function () {
|
||||
// >> file-system-read-binary
|
||||
var fileName = 'logo.png';
|
||||
var error;
|
||||
|
||||
var sourceFile = fs.File.fromPath(__dirname + '/assets/' + fileName);
|
||||
var destinationFile = fs.knownFolders.documents().getFile(fileName);
|
||||
|
||||
var source = sourceFile.readSync((e) => {
|
||||
error = e;
|
||||
});
|
||||
|
||||
destinationFile.writeSync(source, (e) => {
|
||||
error = e;
|
||||
});
|
||||
|
||||
// >> (hide)
|
||||
var destination = destinationFile.readSync((e) => {
|
||||
error = e;
|
||||
});
|
||||
TKUnit.assertNull(error);
|
||||
if (Device.os === platformNames.ios) {
|
||||
TKUnit.assertTrue(source.isEqualToData(destination));
|
||||
} else {
|
||||
TKUnit.assertEqual(new java.io.File(sourceFile.path).length(), new java.io.File(destinationFile.path).length());
|
||||
}
|
||||
|
||||
destinationFile.removeSync();
|
||||
// << (hide)
|
||||
// << file-system-read-binary
|
||||
};
|
||||
|
||||
export var testFileReadWriteBinaryAsync = function () {
|
||||
// >> file-system-read-binary-async
|
||||
var fileName = 'logo.png';
|
||||
|
||||
var sourceFile = fs.File.fromPath(__dirname + '/assets/' + fileName);
|
||||
var destinationFile = fs.knownFolders.documents().getFile(fileName);
|
||||
|
||||
// Read the file
|
||||
sourceFile.read().then(
|
||||
function (source) {
|
||||
// Succeeded in reading the file
|
||||
// >> (hide)
|
||||
destinationFile.write(source).then(
|
||||
function () {
|
||||
// Succeded in writing the file
|
||||
destinationFile.read().then(
|
||||
function (destination) {
|
||||
if (Device.os === platformNames.ios) {
|
||||
TKUnit.assertTrue(source.isEqualToData(destination));
|
||||
} else {
|
||||
TKUnit.assertEqual(new java.io.File(sourceFile.path).length(), new java.io.File(destinationFile.path).length());
|
||||
}
|
||||
|
||||
destinationFile.removeSync();
|
||||
},
|
||||
function (error) {
|
||||
TKUnit.assert(false, 'Failed to read destination binary async');
|
||||
}
|
||||
);
|
||||
},
|
||||
function (error) {
|
||||
// Failed to write the file.
|
||||
TKUnit.assert(false, 'Failed to write binary async');
|
||||
}
|
||||
);
|
||||
// << (hide)
|
||||
},
|
||||
function (error) {
|
||||
// Failed to read the file.
|
||||
// >> (hide)
|
||||
TKUnit.assert(false, 'Failed to read binary async');
|
||||
// << (hide)
|
||||
}
|
||||
);
|
||||
// << file-system-read-binary-async
|
||||
};
|
||||
|
||||
export var testGetKnownFolders = function () {
|
||||
// >> file-system-known-folders
|
||||
// Getting the application's 'documents' folder.
|
||||
var documents = fs.knownFolders.documents();
|
||||
// >> (hide)
|
||||
TKUnit.assert(<any>documents, 'Could not retrieve the Documents known folder.');
|
||||
TKUnit.assert(documents.isKnown, 'The Documents folder should have its isKnown property set to true.');
|
||||
// << (hide)
|
||||
// Getting the application's 'temp' folder.
|
||||
var temp = fs.knownFolders.temp();
|
||||
// >> (hide)
|
||||
TKUnit.assert(<any>temp, 'Could not retrieve the Temporary known folder.');
|
||||
TKUnit.assert(temp.isKnown, 'The Temporary folder should have its isKnown property set to true.');
|
||||
// << (hide)
|
||||
// << file-system-known-folders
|
||||
};
|
||||
|
||||
function _testIOSSpecificKnownFolder(knownFolderName: string) {
|
||||
let knownFolder: fs.Folder;
|
||||
let createdFile: fs.File;
|
||||
let testFunc = function testFunc() {
|
||||
knownFolder = fs.knownFolders.ios[knownFolderName]();
|
||||
if (knownFolder) {
|
||||
createdFile = knownFolder.getFile('createdFile');
|
||||
createdFile.writeTextSync('some text');
|
||||
}
|
||||
};
|
||||
if (isIOS) {
|
||||
testFunc();
|
||||
if (knownFolder) {
|
||||
TKUnit.assertTrue(knownFolder.isKnown, `The ${knownFolderName} folder should have its "isKnown" property set to true.`);
|
||||
TKUnit.assertNotNull(createdFile, `Could not create a new file in the ${knownFolderName} known folder.`);
|
||||
TKUnit.assertTrue(fs.File.exists(createdFile.path), `Could not create a new file in the ${knownFolderName} known folder.`);
|
||||
TKUnit.assertEqual(createdFile.readTextSync(), 'some text', `The contents of the new file created in the ${knownFolderName} known folder are not as expected.`);
|
||||
}
|
||||
} else {
|
||||
TKUnit.assertThrows(testFunc, `Trying to retrieve the ${knownFolderName} known folder on a platform different from iOS should throw!`, `The "${knownFolderName}" known folder is available on iOS only!`);
|
||||
}
|
||||
}
|
||||
|
||||
export var testIOSSpecificKnownFolders = function () {
|
||||
_testIOSSpecificKnownFolder('library');
|
||||
_testIOSSpecificKnownFolder('developer');
|
||||
_testIOSSpecificKnownFolder('desktop');
|
||||
_testIOSSpecificKnownFolder('downloads');
|
||||
_testIOSSpecificKnownFolder('movies');
|
||||
_testIOSSpecificKnownFolder('music');
|
||||
_testIOSSpecificKnownFolder('pictures');
|
||||
_testIOSSpecificKnownFolder('sharedPublic');
|
||||
};
|
||||
|
||||
export var testGetEntities = function () {
|
||||
// >> file-system-folders-content
|
||||
var documents = fs.knownFolders.documents();
|
||||
// >> (hide)
|
||||
var file = documents.getFile('Test.txt');
|
||||
var file1 = documents.getFile('Test1.txt');
|
||||
|
||||
var fileFound, file1Found;
|
||||
|
||||
// IMPORTANT: console.log is mocked to make the snippet pretty.
|
||||
var globalConsole = console;
|
||||
var console = {
|
||||
log: function (file) {
|
||||
if (file === 'Test.txt') {
|
||||
fileFound = true;
|
||||
} else if (file === 'Test1.txt') {
|
||||
file1Found = true;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// << (hide)
|
||||
documents.getEntities().then(
|
||||
function (entities) {
|
||||
// entities is array with the document's files and folders.
|
||||
entities.forEach(function (entity) {
|
||||
console.log(entity.name);
|
||||
});
|
||||
// >> (hide)
|
||||
|
||||
TKUnit.assert(fileFound, 'Failed to enumerate Test.txt');
|
||||
TKUnit.assert(file1Found, 'Failed to enumerate Test1.txt');
|
||||
|
||||
file.remove();
|
||||
file1.remove();
|
||||
// << (hide)
|
||||
},
|
||||
function (error) {
|
||||
// Failed to obtain folder's contents.
|
||||
// globalConsole.error(error.message);
|
||||
}
|
||||
);
|
||||
// << file-system-folders-content
|
||||
};
|
||||
|
||||
export var testEnumEntities = function () {
|
||||
// >> file-system-enum-content
|
||||
var documents = fs.knownFolders.documents();
|
||||
// >> (hide)
|
||||
var file = documents.getFile('Test.txt');
|
||||
var file1 = documents.getFile('Test1.txt');
|
||||
var testFolder = documents.getFolder('testFolder');
|
||||
var fileFound = false;
|
||||
var file1Found = false;
|
||||
var testFolderFound = false;
|
||||
var console = {
|
||||
log: function (file) {
|
||||
if (file === 'Test.txt') {
|
||||
fileFound = true;
|
||||
} else if (file === 'Test1.txt') {
|
||||
file1Found = true;
|
||||
} else if (file === 'testFolder') {
|
||||
testFolderFound = true;
|
||||
}
|
||||
},
|
||||
};
|
||||
// << (hide)
|
||||
documents.eachEntity(function (entity) {
|
||||
console.log(entity.name);
|
||||
|
||||
// Return true to continue, or return false to stop the iteration.
|
||||
return true;
|
||||
});
|
||||
// >> (hide)
|
||||
TKUnit.assert(fileFound, 'Failed to enumerate Test.txt');
|
||||
TKUnit.assert(file1Found, 'Failed to enumerate Test1.txt');
|
||||
TKUnit.assert(testFolderFound, 'Failed to enumerate testFolder');
|
||||
|
||||
file.remove();
|
||||
file1.remove();
|
||||
testFolder.remove();
|
||||
// << (hide)
|
||||
// << file-system-enum-content
|
||||
};
|
||||
|
||||
export var testGetParent = function () {
|
||||
// >> file-system-parent
|
||||
var documents = fs.knownFolders.documents();
|
||||
var file = documents.getFile('Test.txt');
|
||||
// >> (hide)
|
||||
TKUnit.assert(<any>file, 'Failed to create file in the Documents folder.');
|
||||
// << (hide)
|
||||
// The parent folder of the file would be the documents folder.
|
||||
var parent = file.parent;
|
||||
// >> (hide)
|
||||
TKUnit.assert(documents === parent, 'The parent folder should be the Documents folder.');
|
||||
file.remove();
|
||||
// << (hide)
|
||||
// << file-system-parent
|
||||
};
|
||||
|
||||
export var testFileNameExtension = function () {
|
||||
// >> file-system-extension
|
||||
var documents = fs.knownFolders.documents();
|
||||
var file = documents.getFile('Test.txt');
|
||||
// Getting the file name "Test.txt".
|
||||
var fileName = file.name;
|
||||
// Getting the file extension ".txt".
|
||||
var fileExtension = file.extension;
|
||||
// >> (hide)
|
||||
TKUnit.assert(fileName === 'Test.txt', 'Wrong file name.');
|
||||
TKUnit.assert(fileExtension === '.txt', 'Wrong extension.');
|
||||
file.remove();
|
||||
// << (hide)
|
||||
// << file-system-extension
|
||||
};
|
||||
|
||||
export var testFileExists = function () {
|
||||
// >> file-system-fileexists
|
||||
var documents = fs.knownFolders.documents();
|
||||
var filePath = fs.path.join(documents.path, 'Test.txt');
|
||||
var exists = fs.File.exists(filePath);
|
||||
// >> (hide)
|
||||
TKUnit.assert(!exists, 'File.exists API not working.');
|
||||
var file = documents.getFile('Test.txt');
|
||||
exists = fs.File.exists(file.path);
|
||||
TKUnit.assert(exists, 'File.exists API not working.');
|
||||
file.remove();
|
||||
// << (hide)
|
||||
// << file-system-fileexists
|
||||
};
|
||||
|
||||
export var testFolderExists = function () {
|
||||
// >> file-system-folderexists
|
||||
var documents = fs.knownFolders.documents();
|
||||
var exists = fs.Folder.exists(documents.path);
|
||||
// >> (hide)
|
||||
TKUnit.assert(exists, 'Folder.exists API not working.');
|
||||
exists = fs.Folder.exists(documents.path + '_');
|
||||
TKUnit.assert(!exists, 'Folder.exists API not working.');
|
||||
// << (hide)
|
||||
// << file-system-folderexists
|
||||
};
|
||||
|
||||
export var testContainsFile = function () {
|
||||
var folder = fs.knownFolders.documents();
|
||||
var file = folder.getFile('Test.txt');
|
||||
|
||||
var contains = folder.contains('Test.txt');
|
||||
TKUnit.assert(contains, 'Folder.contains API not working.');
|
||||
contains = folder.contains('Test_xxx.txt');
|
||||
TKUnit.assert(!contains, 'Folder.contains API not working.');
|
||||
|
||||
file.remove();
|
||||
};
|
||||
|
||||
export var testFileRename = function () {
|
||||
// >> file-system-renaming
|
||||
var documents = fs.knownFolders.documents();
|
||||
var file = documents.getFile('Test.txt');
|
||||
|
||||
file.rename('Test_renamed.txt').then(
|
||||
function (result) {
|
||||
// Successfully Renamed.
|
||||
// >> (hide)
|
||||
TKUnit.assert(file.name === 'Test_renamed.txt', 'File.rename API not working.');
|
||||
file.remove();
|
||||
documents.getFile('Test.txt').remove();
|
||||
// << (hide)
|
||||
},
|
||||
function (error) {
|
||||
// Failed to rename the file.
|
||||
// >> (hide)
|
||||
TKUnit.assert(false, 'Failed to rename file');
|
||||
// << (hide)
|
||||
}
|
||||
);
|
||||
// << file-system-renaming
|
||||
};
|
||||
|
||||
export var testFolderRename = function () {
|
||||
// >> file-system-renaming-folder
|
||||
var folder = fs.knownFolders.documents();
|
||||
var myFolder = folder.getFolder('Test__');
|
||||
|
||||
myFolder.rename('Something').then(
|
||||
function (result) {
|
||||
// Successfully Renamed.
|
||||
// >> (hide)
|
||||
TKUnit.assert(myFolder.name === 'Something', 'Folder.rename API not working.');
|
||||
myFolder.remove();
|
||||
folder.getFolder('Test__').remove();
|
||||
// << (hide)
|
||||
},
|
||||
function (error) {
|
||||
// Failed to rename the folder.
|
||||
// >> (hide)
|
||||
TKUnit.assert(false, 'Folder.rename API not working.');
|
||||
// << (hide)
|
||||
}
|
||||
);
|
||||
// << file-system-renaming-folder
|
||||
};
|
||||
|
||||
export var testFileRemove = function () {
|
||||
// >> file-system-remove-file
|
||||
var documents = fs.knownFolders.documents();
|
||||
var file = documents.getFile('AFileToRemove.txt');
|
||||
file.remove().then(
|
||||
function (result) {
|
||||
// Success removing the file.
|
||||
// >> (hide)
|
||||
TKUnit.assert(!fs.File.exists(file.path));
|
||||
// << (hide)
|
||||
},
|
||||
function (error) {
|
||||
// Failed to remove the file.
|
||||
// >> (hide)
|
||||
TKUnit.assert(false, 'File.remove API not working.');
|
||||
// << (hide)
|
||||
}
|
||||
);
|
||||
// << file-system-remove-file
|
||||
};
|
||||
|
||||
export var testFolderRemove = function () {
|
||||
// >> file-system-remove-folder
|
||||
var documents = fs.knownFolders.documents();
|
||||
var file = documents.getFolder('AFolderToRemove');
|
||||
// Remove a folder and recursively its content.
|
||||
file.remove().then(
|
||||
function (result) {
|
||||
// Success removing the folder.
|
||||
// >> (hide)
|
||||
TKUnit.assert(!fs.File.exists(file.path));
|
||||
// << (hide)
|
||||
},
|
||||
function (error) {
|
||||
// Failed to remove the folder.
|
||||
// >> (hide)
|
||||
TKUnit.assert(false, 'File.remove API not working.');
|
||||
// << (hide)
|
||||
}
|
||||
);
|
||||
// << file-system-remove-folder
|
||||
};
|
||||
|
||||
export var testFolderClear = function () {
|
||||
// >> file-system-clear-folder
|
||||
var documents = fs.knownFolders.documents();
|
||||
var folder = documents.getFolder('testFolderEmpty');
|
||||
// >> (hide)
|
||||
folder.getFile('Test1.txt');
|
||||
folder.getFile('Test2.txt');
|
||||
var subfolder = folder.getFolder('subfolder');
|
||||
var emptied;
|
||||
// << (hide)
|
||||
folder.clear().then(
|
||||
function () {
|
||||
// Successfully cleared the folder.
|
||||
// >> (hide)
|
||||
emptied = true;
|
||||
// << (hide)
|
||||
},
|
||||
function (error) {
|
||||
// Failed to clear the folder.
|
||||
// >> (hide)
|
||||
TKUnit.assert(false, error.message);
|
||||
// << (hide)
|
||||
}
|
||||
);
|
||||
// >> (hide)
|
||||
folder.getEntities().then(function (entities) {
|
||||
TKUnit.assertEqual(entities.length, 0, `${entities.length} entities left after clearing a folder.`);
|
||||
folder.remove();
|
||||
});
|
||||
// << (hide)
|
||||
// << file-system-clear-folder
|
||||
};
|
||||
|
||||
// misc
|
||||
export var testKnownFolderRename = function () {
|
||||
// You can rename known folders in android - so skip this test.
|
||||
if (!appModule.android) {
|
||||
var folder = fs.knownFolders.documents();
|
||||
folder.rename('Something').then(
|
||||
function (result) {
|
||||
TKUnit.assert(false, 'Known folders should not be renamed.');
|
||||
},
|
||||
function (error) {
|
||||
TKUnit.assert(true);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export function testKnownFolderRemove(done) {
|
||||
var result;
|
||||
|
||||
var knownFolder = fs.knownFolders.temp();
|
||||
|
||||
knownFolder.remove().then(
|
||||
function () {
|
||||
done(new Error('Remove known folder should resolve as error.'));
|
||||
},
|
||||
function (error) {
|
||||
done(null);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function test_FSEntity_Properties() {
|
||||
var documents = fs.knownFolders.documents();
|
||||
var file = documents.getFile('Test_File.txt');
|
||||
|
||||
TKUnit.assert(file.extension === '.txt', 'FileEntity.extension not working.');
|
||||
TKUnit.assert(file.isLocked === false, 'FileEntity.isLocked not working.');
|
||||
TKUnit.assert(file.lastModified instanceof Date, 'FileEntity.lastModified not working.');
|
||||
TKUnit.assert(file.size === 0, 'FileEntity.size not working.');
|
||||
TKUnit.assert(file.name === 'Test_File.txt', 'FileEntity.name not working.');
|
||||
TKUnit.assert(file.parent === documents, 'FileEntity.parent not working.');
|
||||
|
||||
file.remove();
|
||||
}
|
||||
|
||||
export function test_FileSize(done) {
|
||||
var file = fs.knownFolders.documents().getFile('Test_File_Size.txt');
|
||||
file
|
||||
.writeText('Hello World!')
|
||||
.then(() => {
|
||||
TKUnit.assert(file.size === 'Hello World!'.length);
|
||||
|
||||
return file.remove();
|
||||
})
|
||||
.then(() => done())
|
||||
.catch(done);
|
||||
}
|
||||
|
||||
export function test_UnlockAfterWrite(done) {
|
||||
var file = fs.knownFolders.documents().getFile('Test_File_Lock.txt');
|
||||
file
|
||||
.writeText('Hello World!')
|
||||
.then(() => {
|
||||
return file.readText();
|
||||
})
|
||||
.then((value) => {
|
||||
TKUnit.assert(value === 'Hello World!');
|
||||
|
||||
return file.remove();
|
||||
})
|
||||
.then(() => done())
|
||||
.catch(done);
|
||||
}
|
||||
|
||||
export function test_CreateParentOnNewFile(done) {
|
||||
var documentsFolderName = fs.knownFolders.documents().path;
|
||||
var tempFileName = fs.path.join(documentsFolderName, 'folder1', 'folder2', 'Test_File_Create_Parent.txt');
|
||||
var file = fs.File.fromPath(tempFileName);
|
||||
file
|
||||
.writeText('Hello World!')
|
||||
.then(() => {
|
||||
return fs.knownFolders.documents().getFolder('folder1').remove();
|
||||
})
|
||||
.then(() => done())
|
||||
.catch(done);
|
||||
}
|
||||
|
||||
export function test_FolderClear_RemovesEmptySubfolders(done) {
|
||||
let documents = fs.knownFolders.documents();
|
||||
let rootFolder = documents.getFolder('rootFolder');
|
||||
let emptySubfolder = rootFolder.getFolder('emptySubfolder');
|
||||
TKUnit.assertTrue(fs.Folder.exists(emptySubfolder.path), 'emptySubfolder should exist before parent folder is cleared.');
|
||||
rootFolder
|
||||
.clear()
|
||||
.then(() => {
|
||||
TKUnit.assertFalse(fs.File.exists(emptySubfolder.path), 'emptySubfolder should not exist after parent folder was cleared.');
|
||||
rootFolder.remove();
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
}
|
||||
15
apps/automated/app/fps-meter/fps-meter-tests.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
// >> fps-meter-require
|
||||
import * as fpsMeter from '@nativescript/core/fps-meter';
|
||||
// << fps-meter-require
|
||||
|
||||
export var test_DummyTestForSnippetOnly0 = function () {
|
||||
// >> fps-meter-logging
|
||||
var callbackId = fpsMeter.addCallback(function (fps: number, minFps: number) {
|
||||
console.info('fps=' + fps + ' minFps=' + minFps);
|
||||
});
|
||||
fpsMeter.start();
|
||||
////...
|
||||
fpsMeter.removeCallback(callbackId);
|
||||
fpsMeter.stop();
|
||||
// << fps-meter-logging
|
||||
};
|
||||
48
apps/automated/app/globals/globals-tests.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import '@nativescript/core/globals';
|
||||
import * as TKUnit from '../tk-unit';
|
||||
|
||||
declare var System: any;
|
||||
export function test_global_system_import() {
|
||||
TKUnit.assert(System, 'System not defined');
|
||||
TKUnit.assert(typeof System.import === 'function', 'System.import not a function');
|
||||
|
||||
TKUnit.assert((<any>global).System, 'global.System not defined');
|
||||
TKUnit.assert(typeof (<any>global).System.import === 'function', 'global.System.import not a function');
|
||||
}
|
||||
|
||||
export function test_global_zonedCallback() {
|
||||
TKUnit.assert(typeof zonedCallback === 'function', 'zonedCallback not defined');
|
||||
TKUnit.assert(typeof global.zonedCallback === 'function', 'global.zonedCallback not a function');
|
||||
}
|
||||
|
||||
export function test_global_moduleMerge() {
|
||||
TKUnit.assert(typeof global.moduleMerge === 'function', 'global.moduleMerge not a function');
|
||||
}
|
||||
|
||||
export function test_global_registerModule() {
|
||||
TKUnit.assert(typeof global.registerModule === 'function', 'global.registerModule not a function');
|
||||
}
|
||||
|
||||
export function test_global_registerWebpackModules() {
|
||||
TKUnit.assert(typeof global.registerWebpackModules === 'function', 'global.registerWebpackModules not a function');
|
||||
}
|
||||
|
||||
export function test_global_loadModule() {
|
||||
TKUnit.assert(typeof global.loadModule === 'function', 'global.loadModule not a function');
|
||||
}
|
||||
|
||||
export function test_global_moduleExists() {
|
||||
TKUnit.assert(typeof global.moduleExists === 'function', 'global.moduleExists not a function');
|
||||
}
|
||||
|
||||
export function test_global_getRegisteredModules() {
|
||||
TKUnit.assert(typeof global.getRegisteredModules === 'function', 'global.getRegisteredModules not a function');
|
||||
}
|
||||
|
||||
export function test_global_Deprecated() {
|
||||
TKUnit.assert(typeof global.Deprecated === 'function', 'global.Deprecated not a function');
|
||||
}
|
||||
|
||||
export function test_global_Experimental() {
|
||||
TKUnit.assert(typeof global.Experimental === 'function', 'global.Experimental not a function');
|
||||
}
|
||||
14
apps/automated/app/http/http-string-worker.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import * as http from '@nativescript/core/http';
|
||||
|
||||
(<any>global).FormData = class FormData {};
|
||||
|
||||
declare var postMessage: any;
|
||||
|
||||
http.getString('https://httpbin.org/get').then(
|
||||
function (r) {
|
||||
postMessage(r);
|
||||
},
|
||||
function (e) {
|
||||
throw e;
|
||||
}
|
||||
);
|
||||
703
apps/automated/app/http/http-tests.ts
Normal file
@@ -0,0 +1,703 @@
|
||||
import { ImageSource } from '@nativescript/core/image-source';
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import * as http from '@nativescript/core/http';
|
||||
import * as fs from '@nativescript/core/file-system';
|
||||
import { addHeader } from '@nativescript/core/http/http-request';
|
||||
|
||||
export var test_getString_isDefined = function () {
|
||||
TKUnit.assert(typeof http.getString !== 'undefined', 'Method http.getString() should be defined!');
|
||||
};
|
||||
|
||||
export var test_getString = function (done: (err: Error, res?: string) => void) {
|
||||
http.getString('https://httpbin.org/get').then(
|
||||
function (r) {
|
||||
//// Argument (r) is string!
|
||||
done(null);
|
||||
},
|
||||
function (e) {
|
||||
//// Argument (e) is Error!
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_getString_fail = function (done) {
|
||||
http.getString({ url: 'hgfttp://httpbin.org/get', method: 'GET', timeout: 2000 }).catch(function (e) {
|
||||
done(null);
|
||||
});
|
||||
};
|
||||
|
||||
// TODO: should this be kept? many decoders will decode the png data into text (even if it's gibberish)
|
||||
// export var test_getString_fail_when_result_is_not_string = function (done) {
|
||||
// var result;
|
||||
|
||||
// http.getString({ url: "https://httpbin.org/image/png", method: "GET" }).then(function (e) {
|
||||
// result = e;
|
||||
// try {
|
||||
// TKUnit.assert(result instanceof Error, "Result from getString().catch() should be Error! Current type is " + typeof result);
|
||||
// done(null);
|
||||
// }
|
||||
// catch (err) {
|
||||
// done(err);
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
|
||||
export var test_getJSON_isDefined = function () {
|
||||
TKUnit.assert(typeof http.getJSON !== 'undefined', 'Method http.getJSON() should be defined!');
|
||||
};
|
||||
|
||||
export var test_getJSON = function (done) {
|
||||
var result;
|
||||
|
||||
http.getJSON('https://httpbin.org/get').then(
|
||||
function (r) {
|
||||
//// Argument (r) is JSON!
|
||||
//completed = true;
|
||||
result = r;
|
||||
try {
|
||||
TKUnit.assert(typeof JSON.stringify(result) === 'string', 'Result from getJSON() should be valid JSON object!');
|
||||
done(null);
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
done(null);
|
||||
},
|
||||
function (e) {
|
||||
//// Argument (e) is Error!
|
||||
//console.log(e);
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_getJSON_fail = function (done) {
|
||||
var result;
|
||||
|
||||
http.getJSON({ url: 'hgfttp://httpbin.org/get', method: 'GET', timeout: 2000 }).catch(function (e) {
|
||||
result = e;
|
||||
try {
|
||||
TKUnit.assert(result instanceof Error, 'Result from getJSON().catch() should be Error! Current type is ' + typeof result);
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export var test_getJSON_fail_when_result_is_not_JSON = function (done) {
|
||||
var result;
|
||||
|
||||
http.getJSON({ url: 'https://httpbin.org/html', method: 'GET' }).catch(function (e) {
|
||||
result = e;
|
||||
try {
|
||||
TKUnit.assert(result instanceof Error, 'Result from getJSON().catch() should be Error! Current type is ' + typeof result);
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export var test_getJSONP = function (done) {
|
||||
var result;
|
||||
|
||||
http.getJSON('https://jsfiddle.net/echo/jsonp/').then(
|
||||
function (r) {
|
||||
result = r;
|
||||
try {
|
||||
TKUnit.assert(typeof JSON.stringify(result) === 'string', 'Result from getJSON() should be valid JSON object!');
|
||||
done(null);
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
done(null);
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_getJSON_fail_when_result_is_not_JSONP = function (done) {
|
||||
var result;
|
||||
|
||||
http.getJSON({ url: 'https://httpbin.org/html', method: 'GET' }).catch(function (e) {
|
||||
result = e;
|
||||
try {
|
||||
TKUnit.assert(result instanceof Error, 'Result from getJSON().catch() should be Error! Current type is ' + typeof result);
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export var test_gzip_request_explicit = function (done) {
|
||||
var result;
|
||||
|
||||
http
|
||||
.request({
|
||||
url: 'https://postman-echo.com/gzip',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept-Encoding': 'gzip',
|
||||
},
|
||||
})
|
||||
.then(
|
||||
function (r) {
|
||||
result = r;
|
||||
try {
|
||||
TKUnit.assert(typeof JSON.stringify(result) === 'string', 'Result from gzipped stream should be valid JSON object!');
|
||||
done(null);
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_gzip_request_implicit = function (done) {
|
||||
var result;
|
||||
|
||||
http
|
||||
.request({
|
||||
url: 'https://postman-echo.com/gzip',
|
||||
method: 'GET',
|
||||
})
|
||||
.then(
|
||||
function (r) {
|
||||
result = r;
|
||||
try {
|
||||
TKUnit.assert(typeof JSON.stringify(result) === 'string', 'Result from gzipped stream should be valid JSON object!');
|
||||
done(null);
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_getImage_isDefined = function () {
|
||||
TKUnit.assert(typeof http.getImage !== 'undefined', 'Method http.getImage() should be defined!');
|
||||
};
|
||||
|
||||
export var test_getImage = function (done) {
|
||||
var result;
|
||||
|
||||
http.getImage('https://httpbin.org/image/png').then(
|
||||
(r) => {
|
||||
// Argument (r) is ImageSource!
|
||||
result = r;
|
||||
try {
|
||||
TKUnit.assert(result instanceof ImageSource, 'Result from getImage() should be valid ImageSource object!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
(err) => {
|
||||
// Argument (e) is Error!
|
||||
done(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_getImage_fail = function (done) {
|
||||
var result;
|
||||
|
||||
http.getImage({ url: 'hgfttp://www.google.com/images/errors/logo_sm_2.png', method: 'GET', timeout: 2000 }).catch(function (e) {
|
||||
result = e;
|
||||
try {
|
||||
TKUnit.assert(result instanceof Error, 'Result from getImage().catch() should be Error! Current type is ' + typeof result);
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export var test_getImage_fail_when_result_is_not_image = function (done) {
|
||||
var result;
|
||||
|
||||
http.getImage({ url: 'https://httpbin.org/html', method: 'GET' }).catch(function (e) {
|
||||
result = e;
|
||||
try {
|
||||
TKUnit.assert(result instanceof Error, 'Result from getImage().catch() should be Error! Current type is ' + typeof result);
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export var test_getFile_isDefined = function () {
|
||||
TKUnit.assert(typeof http.getFile !== 'undefined', 'Method http.getFile() should be defined!');
|
||||
};
|
||||
|
||||
export var test_getFile = function (done) {
|
||||
var result;
|
||||
|
||||
http.getFile('https://raw.githubusercontent.com/NativeScript/NativeScript/master/tests/app/logo.png').then(
|
||||
function (r) {
|
||||
//// Argument (r) is File!
|
||||
result = r;
|
||||
try {
|
||||
TKUnit.assert(result instanceof fs.File, 'Result from getFile() should be valid File object!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
//// Argument (e) is Error!
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_getContentAsFile = function (done) {
|
||||
var result;
|
||||
|
||||
var filePath = fs.path.join(fs.knownFolders.documents().path, 'test.png');
|
||||
http.getFile('https://httpbin.org/image/png?testQuery=query&anotherParam=param', filePath).then(
|
||||
function (r) {
|
||||
//// Argument (r) is File!
|
||||
result = r;
|
||||
try {
|
||||
TKUnit.assert(result instanceof fs.File, 'Result from getFile() should be valid File object!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
//// Argument (e) is Error!
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_getFile_fail = function (done) {
|
||||
var result;
|
||||
|
||||
http.getImage({ url: 'hgfttp://raw.githubusercontent.com/NativeScript/NativeScript/master/tests/app/logo.png', method: 'GET', timeout: 2000 }).catch(function (e) {
|
||||
result = e;
|
||||
try {
|
||||
TKUnit.assert(result instanceof Error, 'Result from getFile().catch() should be Error! Current type is ' + typeof result);
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export var test_request_isDefined = function () {
|
||||
TKUnit.assert(typeof http['request'] !== 'undefined', 'Method http.request() should be defined!');
|
||||
};
|
||||
|
||||
export var test_request_shouldFailIfOptionsUrlIsNotDefined = function (done) {
|
||||
var result;
|
||||
|
||||
http.request({ url: undefined, method: undefined }).catch(function (e) {
|
||||
result = e;
|
||||
try {
|
||||
TKUnit.assert(result instanceof Error, 'Result from request().catch() should be Error! Current type is ' + typeof result);
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export var test_request_requestShouldTimeout = function (done) {
|
||||
var result;
|
||||
http.request({ url: 'https://10.255.255.1', method: 'GET', timeout: 500 }).catch(function (e) {
|
||||
result = e;
|
||||
try {
|
||||
TKUnit.assert(result instanceof Error, 'Result from request().catch() should be Error! Current type is ' + typeof result);
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export var test_request_responseStatusCodeShouldBeDefined = function (done) {
|
||||
var result: http.HttpResponse;
|
||||
|
||||
http.request({ url: 'https://httpbin.org/get', method: 'GET' }).then(
|
||||
function (response) {
|
||||
//// Argument (response) is HttpResponse!
|
||||
var statusCode = response.statusCode;
|
||||
result = response;
|
||||
try {
|
||||
TKUnit.assert(typeof statusCode !== 'undefined', 'response.statusCode should be defined!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
//// Argument (e) is Error!
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_headRequest_responseStatusCodeShouldBeDefined = function (done) {
|
||||
http.request({ url: 'https://httpbin.org/get', method: 'HEAD' }).then(
|
||||
function (response) {
|
||||
try {
|
||||
TKUnit.assert(typeof response.statusCode !== 'undefined', 'response.statusCode should be defined!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_responseHeadersShouldBeDefined = function (done) {
|
||||
var result: http.HttpResponse;
|
||||
|
||||
http.request({ url: 'https://httpbin.org/get', method: 'GET' }).then(
|
||||
function (response) {
|
||||
//// Argument (response) is HttpResponse!
|
||||
//for (var header in response.headers) {
|
||||
// console.log(header + ":" + response.headers[header]);
|
||||
//}
|
||||
result = response;
|
||||
try {
|
||||
TKUnit.assert(typeof result.headers !== 'undefined', 'response.headers should be defined!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
//// Argument (e) is Error!
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_responseContentShouldBeDefined = function (done) {
|
||||
var result: http.HttpResponse;
|
||||
|
||||
http.request({ url: 'https://httpbin.org/get', method: 'GET' }).then(
|
||||
function (response) {
|
||||
//// Argument (response) is HttpResponse!
|
||||
//// Content property of the response is HttpContent!
|
||||
result = response;
|
||||
try {
|
||||
TKUnit.assert(typeof result.content !== 'undefined', 'response.content should be defined!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
//// Argument (e) is Error!
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_responseContentToStringShouldReturnString = function (done) {
|
||||
var result;
|
||||
|
||||
http.request({ url: 'https://httpbin.org/get', method: 'GET' }).then(
|
||||
function (response) {
|
||||
result = response.content.toString();
|
||||
try {
|
||||
TKUnit.assert(typeof result === 'string', 'Result from toString() should be string!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_responseContentToJSONShouldReturnJSON = function (done) {
|
||||
var result;
|
||||
|
||||
http.request({ url: 'https://httpbin.org/get', method: 'GET' }).then(
|
||||
function (response) {
|
||||
result = response.content.toJSON();
|
||||
try {
|
||||
TKUnit.assert(typeof JSON.stringify(result) === 'string', 'Result from toJSON() should be valid JSON object!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_responseContentToImageShouldReturnCorrectImage = function (done) {
|
||||
var result;
|
||||
|
||||
http.request({ url: 'https://httpbin.org/image/png', method: 'GET' }).then(
|
||||
function (response) {
|
||||
response.content.toImage().then((source) => {
|
||||
result = source;
|
||||
try {
|
||||
TKUnit.assert(result instanceof ImageSource, 'Result from toImage() should be valid promise of ImageSource object!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_responseContentToFileFromUrlShouldReturnCorrectFile = function (done) {
|
||||
var result;
|
||||
|
||||
http.request({ url: 'https://raw.githubusercontent.com/NativeScript/NativeScript/master/tests/app/logo.png', method: 'GET' }).then(
|
||||
function (response) {
|
||||
result = response.content.toFile();
|
||||
try {
|
||||
TKUnit.assert(result instanceof fs.File, 'Result from toFile() should be valid File object!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
export var test_request_responseContentToFileFromUrlShouldReturnCorrectFileAndCreateDirPathIfNecesary = function (done) {
|
||||
var result;
|
||||
|
||||
http.request({ url: 'https://raw.githubusercontent.com/NativeScript/NativeScript/master/tests/app/logo.png', method: 'GET' }).then(
|
||||
function (response) {
|
||||
const filePath = fs.path.join(fs.knownFolders.temp().path, 'test', 'some', 'path', 'logo.png');
|
||||
result = response.content.toFile(filePath);
|
||||
try {
|
||||
TKUnit.assert(result instanceof fs.File, 'Result from toFile() should be valid File object!');
|
||||
TKUnit.assert(result.size > 0, 'result from to file should be greater than 0 in size');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_responseContentToFileFromContentShouldReturnCorrectFile = function (done) {
|
||||
var result;
|
||||
|
||||
http.request({ url: 'https://httpbin.org/image/png?queryString=param&another=anotherParam', method: 'GET' }).then(
|
||||
function (response) {
|
||||
result = response.content.toFile();
|
||||
try {
|
||||
TKUnit.assert(result instanceof fs.File, 'Result from toFile() should be valid File object!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_headersSentAndReceivedProperly = function (done) {
|
||||
var result;
|
||||
|
||||
http
|
||||
.request({
|
||||
url: 'https://httpbin.org/get',
|
||||
method: 'GET',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
.then(
|
||||
function (response) {
|
||||
result = response.headers;
|
||||
try {
|
||||
TKUnit.assert(result['Content-Type'] === 'application/json', 'Headers not sent/received properly!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_headersWithSameKeyAddedProperly = function (done) {
|
||||
var keyName = 'key';
|
||||
var value1 = 'value1';
|
||||
var value2 = 'value2';
|
||||
|
||||
var headers: http.Headers = {};
|
||||
|
||||
addHeader(headers, keyName, value1);
|
||||
addHeader(headers, keyName, value2);
|
||||
|
||||
try {
|
||||
TKUnit.assertTrue(Array.isArray(headers[keyName]));
|
||||
TKUnit.assertEqual(headers[keyName][0], value1);
|
||||
TKUnit.assertEqual(headers[keyName][1], value2);
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
};
|
||||
|
||||
export var test_request_contentSentAndReceivedProperly = function (done) {
|
||||
var result;
|
||||
|
||||
http
|
||||
.request({
|
||||
url: 'https://httpbin.org/post',
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
content: 'MyVariableOne=ValueOne&MyVariableTwo=ValueTwo',
|
||||
})
|
||||
.then(
|
||||
function (response) {
|
||||
result = response.content.toJSON();
|
||||
try {
|
||||
TKUnit.assert(result['form']['MyVariableOne'] === 'ValueOne' && result['form']['MyVariableTwo'] === 'ValueTwo', 'Content not sent/received properly!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_FormDataContentSentAndReceivedProperly = function (done) {
|
||||
var result;
|
||||
|
||||
var data = new FormData();
|
||||
data.append('MyVariableOne', 'ValueOne');
|
||||
data.append('MyVariableTwo', 'ValueTwo');
|
||||
|
||||
http
|
||||
.request({
|
||||
url: 'https://httpbin.org/post',
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
content: data,
|
||||
})
|
||||
.then(
|
||||
function (response) {
|
||||
result = response.content.toJSON();
|
||||
try {
|
||||
TKUnit.assert(result['form']['MyVariableOne'] === 'ValueOne' && result['form']['MyVariableTwo'] === 'ValueTwo', 'Content not sent/received properly!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_NonStringHeadersSentAndReceivedProperly = function (done) {
|
||||
var result;
|
||||
|
||||
var postData = 'MyVariableOne=ValueOne&MyVariableTwo=ValueTwo';
|
||||
|
||||
http
|
||||
.request({
|
||||
url: 'https://httpbin.org/post',
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': postData.length },
|
||||
content: postData,
|
||||
})
|
||||
.then(
|
||||
function (response) {
|
||||
result = response.content.toJSON();
|
||||
try {
|
||||
TKUnit.assert(result['form']['MyVariableOne'] === 'ValueOne' && result['form']['MyVariableTwo'] === 'ValueTwo', 'Content not sent/received properly!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_request_jsonAsContentSentAndReceivedProperly = function (done) {
|
||||
var result;
|
||||
|
||||
http
|
||||
.request({
|
||||
url: 'https://httpbin.org/post',
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
content: JSON.stringify({ MyVariableOne: 'ValueOne', MyVariableTwo: 'ValueTwo' }),
|
||||
})
|
||||
.then(
|
||||
function (response) {
|
||||
// result = response.content.toJSON();
|
||||
result = response.content.toJSON();
|
||||
try {
|
||||
TKUnit.assert(result['json']['MyVariableOne'] === 'ValueOne' && result['json']['MyVariableTwo'] === 'ValueTwo', 'Content not sent/received properly!');
|
||||
done(null);
|
||||
} catch (err) {
|
||||
done(err);
|
||||
}
|
||||
// console.log(result);
|
||||
},
|
||||
function (e) {
|
||||
done(e);
|
||||
// console.log("Error occurred " + e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export var test_getString_WorksProperlyInWorker = function (done) {
|
||||
const HttpStringWorker = require('nativescript-worker-loader!./http-string-worker');
|
||||
let worker = new HttpStringWorker();
|
||||
console.log('Worker Created');
|
||||
worker.onmessage = function (msg) {
|
||||
console.log('Message received');
|
||||
done();
|
||||
};
|
||||
worker.onerror = function (e) {
|
||||
console.log('errir received');
|
||||
done(e);
|
||||
};
|
||||
};
|
||||
16
apps/automated/app/image-source/image-source-snippet.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ImageSource } from '@nativescript/core/image-source';
|
||||
import * as fs from '@nativescript/core/file-system';
|
||||
// >> imagesource-from-imageasset-save-to
|
||||
|
||||
export function imageSourceFromAsset(imageAsset) {
|
||||
ImageSource.fromAsset(imageAsset).then((imageSource) => {
|
||||
let folder = fs.knownFolders.documents().path;
|
||||
let fileName = 'test.png';
|
||||
let path = fs.path.join(folder, fileName);
|
||||
let saved = imageSource.saveToFile(path, 'png');
|
||||
if (saved) {
|
||||
console.log('Image saved successfully!');
|
||||
}
|
||||
});
|
||||
}
|
||||
// << imagesource-from-imageasset-save-to
|
||||
315
apps/automated/app/image-source/image-source-tests.ts
Normal file
@@ -0,0 +1,315 @@
|
||||
import { ImageSource } from '@nativescript/core/image-source';
|
||||
import * as imageAssetModule from '@nativescript/core/image-asset';
|
||||
import * as fs from '@nativescript/core/file-system';
|
||||
import * as app from '@nativescript/core/application';
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import { Font } from '@nativescript/core/ui/styling/font';
|
||||
import { Color } from '@nativescript/core/color';
|
||||
|
||||
const imagePath = '~/assets/logo.png';
|
||||
const splashscreenPath = '~/assets/splashscreen.png';
|
||||
const splashscreenWidth = 372;
|
||||
const splashscreenHeight = 218;
|
||||
const smallImagePath = '~/assets/small-image.png';
|
||||
|
||||
export function testFromResource() {
|
||||
// >> imagesource-resname
|
||||
const img = ImageSource.fromResourceSync('icon');
|
||||
// << imagesource-resname
|
||||
|
||||
TKUnit.assert(img.height > 0, 'image.fromResource failed');
|
||||
}
|
||||
|
||||
export function testFromUrl(done) {
|
||||
let result: ImageSource;
|
||||
|
||||
// Deprecated method fromUrl
|
||||
ImageSource.fromUrl('https://www.google.com/images/errors/logo_sm_2.png').then(
|
||||
(res: ImageSource) => {
|
||||
// console.log("Image successfully loaded");
|
||||
// completed = true;
|
||||
result = res;
|
||||
try {
|
||||
TKUnit.assertNotEqual(result, undefined, 'Image not downloaded');
|
||||
TKUnit.assert(result.height > 0, 'Image not downloaded');
|
||||
done(null);
|
||||
} catch (e) {
|
||||
done(e);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
// console.log("Error loading image: " + error);
|
||||
//completed = true;
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testSaveToFile() {
|
||||
// >> imagesource-save-to
|
||||
const img = ImageSource.fromFileSync(imagePath);
|
||||
const folder = fs.knownFolders.documents();
|
||||
const path = fs.path.join(folder.path, 'test.png');
|
||||
const saved = img.saveToFile(path, 'png');
|
||||
// << imagesource-save-to
|
||||
TKUnit.assert(saved, 'Image not saved to file');
|
||||
TKUnit.assert(fs.File.exists(path), 'Image not saved to file');
|
||||
}
|
||||
|
||||
export function testSaveToFile_WithQuality() {
|
||||
const img = ImageSource.fromFileSync(imagePath);
|
||||
const folder = fs.knownFolders.documents();
|
||||
const path = fs.path.join(folder.path, 'test.png');
|
||||
const saved = img.saveToFile(path, 'png', 70);
|
||||
TKUnit.assert(saved, 'Image not saved to file');
|
||||
TKUnit.assert(fs.File.exists(path), 'Image not saved to file');
|
||||
}
|
||||
|
||||
export function testFromFile() {
|
||||
// >> imagesource-load-local
|
||||
const folder = fs.knownFolders.documents();
|
||||
const path = fs.path.join(folder.path, 'test.png');
|
||||
const img = ImageSource.fromFileSync(path);
|
||||
// << imagesource-load-local
|
||||
|
||||
TKUnit.assert(img.height > 0, 'image.fromResource failed');
|
||||
|
||||
// remove the image from the file system
|
||||
const file = folder.getFile('test.png');
|
||||
file.remove();
|
||||
TKUnit.assert(!fs.File.exists(path), 'test.png not removed');
|
||||
}
|
||||
|
||||
export function testFromAssetFileNotFound(done) {
|
||||
let asset = new imageAssetModule.ImageAsset('invalidFile.png');
|
||||
asset.options = {
|
||||
width: 0,
|
||||
height: 0,
|
||||
keepAspectRatio: true,
|
||||
};
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
done('Should not resolve with invalid file name.');
|
||||
},
|
||||
(error) => {
|
||||
TKUnit.assertNotNull(error);
|
||||
done();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testFromAssetSimple(done) {
|
||||
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
|
||||
asset.options = {
|
||||
width: 0,
|
||||
height: 0,
|
||||
keepAspectRatio: true,
|
||||
};
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
TKUnit.assertEqual(source.width, splashscreenWidth);
|
||||
TKUnit.assertEqual(source.height, splashscreenHeight);
|
||||
done();
|
||||
},
|
||||
(error) => {
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testFromAssetWithExactScaling(done) {
|
||||
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
|
||||
let scaleWidth = 10;
|
||||
let scaleHeight = 11;
|
||||
asset.options = {
|
||||
width: scaleWidth,
|
||||
height: scaleHeight,
|
||||
keepAspectRatio: false,
|
||||
autoScaleFactor: false,
|
||||
};
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
TKUnit.assertEqual(source.width, scaleWidth);
|
||||
TKUnit.assertEqual(source.height, scaleHeight);
|
||||
|
||||
const targetFilename = `splashscreenTemp.png`;
|
||||
const tempPath = fs.knownFolders.temp().path;
|
||||
const localFullPath = fs.path.join(tempPath, targetFilename);
|
||||
|
||||
const fullImageSaved = source.saveToFile(localFullPath, 'png');
|
||||
|
||||
if (fullImageSaved) {
|
||||
ImageSource.fromFile(localFullPath).then((sourceImage) => {
|
||||
TKUnit.assertEqual(sourceImage.width, scaleWidth);
|
||||
TKUnit.assertEqual(sourceImage.height, scaleHeight);
|
||||
done();
|
||||
});
|
||||
} else {
|
||||
done(`Error saving photo to local temp folder: ${localFullPath}`);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testFromAssetWithScalingAndAspectRatio(done) {
|
||||
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
|
||||
let scaleWidth = 10;
|
||||
let scaleHeight = 11;
|
||||
asset.options = {
|
||||
width: scaleWidth,
|
||||
height: scaleHeight,
|
||||
keepAspectRatio: true,
|
||||
};
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
TKUnit.assertEqual(source.width, 18);
|
||||
TKUnit.assertEqual(source.height, scaleHeight);
|
||||
done();
|
||||
},
|
||||
(error) => {
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testFromAssetWithScalingAndDefaultAspectRatio(done) {
|
||||
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
|
||||
let scaleWidth = 10;
|
||||
let scaleHeight = 11;
|
||||
asset.options.width = scaleWidth;
|
||||
asset.options.height = scaleHeight;
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
TKUnit.assertEqual(source.width, 18);
|
||||
TKUnit.assertEqual(source.height, scaleHeight);
|
||||
done();
|
||||
},
|
||||
(error) => {
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testFromAssetWithBiggerScaling(done) {
|
||||
let asset = new imageAssetModule.ImageAsset(splashscreenPath);
|
||||
let scaleWidth = 600;
|
||||
let scaleHeight = 600;
|
||||
asset.options = {
|
||||
width: scaleWidth,
|
||||
height: scaleHeight,
|
||||
keepAspectRatio: false,
|
||||
};
|
||||
|
||||
ImageSource.fromAsset(asset).then(
|
||||
(source) => {
|
||||
TKUnit.assertEqual(source.width, scaleWidth);
|
||||
TKUnit.assertEqual(source.height, scaleHeight);
|
||||
done();
|
||||
},
|
||||
(error) => {
|
||||
done(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function testNativeFields() {
|
||||
const img = ImageSource.fromFileSync(imagePath);
|
||||
if (app.android) {
|
||||
TKUnit.assert(img.android != null, 'Image.android not updated.');
|
||||
} else if (app.ios) {
|
||||
TKUnit.assert(img.ios != null, 'Image.ios not updated.');
|
||||
}
|
||||
}
|
||||
const fullAndroidPng = 'iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAA3NCSVQICAjb4U/gAAAAFUlEQVQImWP8z4AAjAz/kTnIPGQAAG86AwGcuMlCAAAAAElFTkSuQmCC';
|
||||
const fullIosPng = 'iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAAXNSR0IArs4c6QAAABxpRE9UAAAAAgAAAAAAAAACAAAAKAAAAAIAAAACAAAARiS4uJEAAAASSURBVBgZYvjPwABHSMz/DAAAAAD//0GWpK0AAAAOSURBVGNgYPiPhBgQAACEvQv1D5y/pAAAAABJRU5ErkJggg==';
|
||||
|
||||
const jpgImageAsBase64String =
|
||||
'/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAEAAQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+Pz/h5j+1Z/z9fBr/AMRt+AH/AM7uiiiv9fV9E36KOn/HMX0f+n/NlvDT/p3/ANUv/V3vrf8AP1nueaf8LOa9P+ZjjP8Ap3/0/wD6u99b/wD/2Q==';
|
||||
const expectedJpegStart = '/9j/4AAQSkZJRgAB';
|
||||
const expectedPngStart = 'iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAA';
|
||||
|
||||
export function testBase64Encode_PNG() {
|
||||
// >> imagesource-to-base-string
|
||||
const img = ImageSource.fromFileSync(smallImagePath);
|
||||
let base64String = img.toBase64String('png');
|
||||
// << imagesource-to-base-string
|
||||
|
||||
base64String = base64String.substr(0, expectedPngStart.length);
|
||||
TKUnit.assertEqual(base64String, expectedPngStart, 'Base 64 encoded PNG');
|
||||
}
|
||||
|
||||
export function testBase64Encode_PNG_WithQuality() {
|
||||
const img = ImageSource.fromFileSync(smallImagePath);
|
||||
let base64String = img.toBase64String('png', 80);
|
||||
base64String = base64String.substr(0, expectedPngStart.length);
|
||||
TKUnit.assertEqual(base64String, expectedPngStart, 'Base 64 encoded PNG');
|
||||
}
|
||||
|
||||
export function testBase64Encode_JPEG() {
|
||||
const img = ImageSource.fromFileSync(smallImagePath);
|
||||
|
||||
let base64String = img.toBase64String('jpeg');
|
||||
base64String = base64String.substr(0, expectedJpegStart.length);
|
||||
|
||||
TKUnit.assertEqual(base64String, expectedJpegStart, 'Base 64 encoded JPEG');
|
||||
}
|
||||
|
||||
export function testBase64Encode_JPEG_With_Quality() {
|
||||
const img = ImageSource.fromFileSync(smallImagePath);
|
||||
|
||||
let base64String = img.toBase64String('jpeg', 80);
|
||||
base64String = base64String.substr(0, expectedJpegStart.length);
|
||||
|
||||
TKUnit.assertEqual(base64String, expectedJpegStart, 'Base 64 encoded JPEG');
|
||||
}
|
||||
|
||||
export function testLoadFromBase64Encode_JPEG() {
|
||||
// >> imagesource-from-base-string
|
||||
let img: ImageSource;
|
||||
img = ImageSource.fromBase64Sync(jpgImageAsBase64String);
|
||||
// << imagesource-from-base-string
|
||||
|
||||
TKUnit.assert(img !== null, 'Actual: ' + img);
|
||||
TKUnit.assertEqual(img.width, 4, 'img.width');
|
||||
TKUnit.assertEqual(img.height, 4, 'img.height');
|
||||
}
|
||||
|
||||
export function testLoadFromBase64Encode_PNG() {
|
||||
let img: ImageSource;
|
||||
if (app.android) {
|
||||
img = ImageSource.fromBase64Sync(fullAndroidPng);
|
||||
} else if (app.ios) {
|
||||
img = ImageSource.fromBase64Sync(fullIosPng);
|
||||
}
|
||||
|
||||
TKUnit.assert(img !== null, 'Actual: ' + img);
|
||||
TKUnit.assertEqual(img.width, 4, 'img.width');
|
||||
TKUnit.assertEqual(img.height, 4, 'img.height');
|
||||
}
|
||||
|
||||
export function testLoadFromFontIconCode() {
|
||||
let img: ImageSource;
|
||||
img = ImageSource.fromFontIconCodeSync('F10B', Font.default.withFontFamily('FontAwesome'), new Color('red'));
|
||||
|
||||
TKUnit.assert(img !== null, 'Actual: ' + img);
|
||||
TKUnit.assert(img.width !== null, 'img.width');
|
||||
TKUnit.assert(img.height !== null, 'img.width');
|
||||
}
|
||||
|
||||
export function testResize() {
|
||||
const img = ImageSource.fromFileSync(imagePath);
|
||||
|
||||
const newSize = Math.floor(Math.max(img.width, img.height) / 2);
|
||||
|
||||
const resized = img.resize(newSize);
|
||||
|
||||
TKUnit.assert(resized.width === newSize || resized.height === newSize, 'Image not resized correctly');
|
||||
}
|
||||
3
apps/automated/app/livesync/livesync-button-page.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export function onLoaded() {
|
||||
console.log('Button page loaded!');
|
||||
}
|
||||
3
apps/automated/app/livesync/livesync-label-page.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export function onLoaded() {
|
||||
console.log('Label page loaded!');
|
||||
}
|
||||
15
apps/automated/app/livesync/livesync-modal-view-page.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { View, ShowModalOptions } from '@nativescript/core';
|
||||
const LIVESYNC_FOLDER = 'livesync/';
|
||||
const buttonPageModuleName = `${LIVESYNC_FOLDER}livesync-button-page`;
|
||||
|
||||
export function onLoaded(args) {
|
||||
const view = args.object as View;
|
||||
|
||||
let options: ShowModalOptions = {
|
||||
context: 'context',
|
||||
closeCallback: () => console.log('modal view closeCallback raised.'),
|
||||
animated: false,
|
||||
};
|
||||
|
||||
view.showModal(buttonPageModuleName, options);
|
||||
}
|
||||
258
apps/automated/app/livesync/livesync-tests.ts
Normal file
@@ -0,0 +1,258 @@
|
||||
import * as helper from '../ui-helper';
|
||||
import * as TKUnit from '../tk-unit';
|
||||
|
||||
import * as app from '@nativescript/core/application';
|
||||
import * as frame from '@nativescript/core/ui/frame';
|
||||
import { Color } from '@nativescript/core/color';
|
||||
import { Builder } from '@nativescript/core/ui/builder';
|
||||
import { Page } from '@nativescript/core/ui/page';
|
||||
import { Frame } from '@nativescript/core/ui/frame';
|
||||
|
||||
const LIVESYNC_FOLDER = 'livesync/';
|
||||
|
||||
const appCssFileName = `${LIVESYNC_FOLDER}application-page.css`;
|
||||
const appNewCssFileName = `${LIVESYNC_FOLDER}app-new-page.css`;
|
||||
// `.scss` module registers in webpack as `.css`
|
||||
// https://github.com/NativeScript/NativeScript/blob/5.4.2/@nativescript/core/globals/globals.ts#L32-L33
|
||||
const appNewScssFileNameAsCss = `${LIVESYNC_FOLDER}app-new-scss-page.css`;
|
||||
const appNewScssFileName = `${LIVESYNC_FOLDER}app-new-scss-page.scss`;
|
||||
|
||||
const buttonCssModuleName = `${LIVESYNC_FOLDER}button-css-page`;
|
||||
const buttonScssModuleName = `${LIVESYNC_FOLDER}button-scss-page`;
|
||||
const buttonCssFileName = `${LIVESYNC_FOLDER}button-css-page.css`;
|
||||
const buttonScssFileName = `${LIVESYNC_FOLDER}button-scss-page.scss`;
|
||||
|
||||
const buttonPageModuleName = `${LIVESYNC_FOLDER}livesync-button-page`;
|
||||
const buttonHtmlPageFileName = `${LIVESYNC_FOLDER}livesync-button-page.html`;
|
||||
const buttonXmlPageFileName = `${LIVESYNC_FOLDER}livesync-button-page.xml`;
|
||||
const buttonJsPageFileName = `${LIVESYNC_FOLDER}livesync-button-page.js`;
|
||||
const buttonTsPageFileName = `${LIVESYNC_FOLDER}livesync-button-page.ts`;
|
||||
const buttonScssPageFileName = `${LIVESYNC_FOLDER}livesync-button-page.scss`;
|
||||
const labelPageModuleName = `${LIVESYNC_FOLDER}livesync-label-page`;
|
||||
|
||||
const modalViewPageModuleName = `${LIVESYNC_FOLDER}livesync-modal-view-page`;
|
||||
const modalViewXmlPageFileName = `${LIVESYNC_FOLDER}livesync-modal-view-page.xml`;
|
||||
const modalViewJsPageFileName = `${LIVESYNC_FOLDER}livesync-modal-view-page.js`;
|
||||
const modalViewTsPageFileName = `${LIVESYNC_FOLDER}livesync-modal-view-page.ts`;
|
||||
const modalViewScssPageFileName = `${LIVESYNC_FOLDER}livesync-modal-view-page.scss`;
|
||||
const modalViewCssFileName = `${LIVESYNC_FOLDER}livesync-modal-view-page.css`;
|
||||
|
||||
const green = new Color('green');
|
||||
|
||||
export function setUp() {
|
||||
const labelPage = <Page>Builder.createViewFromEntry({ moduleName: labelPageModuleName });
|
||||
helper.navigate(() => labelPage);
|
||||
}
|
||||
|
||||
export function tearDown() {
|
||||
app.setCssFileName(appCssFileName);
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_AppStyle_AppNewCss() {
|
||||
_test_onLiveSync_ModuleContext_AppStyle(appNewCssFileName, appNewCssFileName);
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_AppStyle_AppNewScss() {
|
||||
_test_onLiveSync_ModuleContext_AppStyle(appNewScssFileNameAsCss, appNewScssFileName);
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_Undefined() {
|
||||
_test_onLiveSync_ModuleContext({ type: undefined, path: undefined });
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_PathUndefined() {
|
||||
_test_onLiveSync_ModuleContext({ type: 'script', path: undefined });
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_Script_JsFile() {
|
||||
_test_onLiveSync_ModuleReplace({ type: 'script', path: buttonJsPageFileName });
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_Script_TsFile() {
|
||||
_test_onLiveSync_ModuleReplace({ type: 'script', path: buttonTsPageFileName });
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_Style_CssFile() {
|
||||
_test_onLiveSync_ModuleContext_TypeStyle(buttonCssModuleName, buttonCssFileName);
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_Style_ScssFile() {
|
||||
_test_onLiveSync_ModuleContext_TypeStyle(buttonScssModuleName, buttonScssFileName);
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_Markup_HtmlFile() {
|
||||
_test_onLiveSync_ModuleReplace({ type: 'markup', path: buttonHtmlPageFileName });
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_Markup_XmlFile() {
|
||||
_test_onLiveSync_ModuleReplace({ type: 'markup', path: buttonXmlPageFileName });
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_MarkupXml_ScriptTs_Files() {
|
||||
_test_onLiveSync_ModuleReplace_Multiple([
|
||||
{ type: 'script', path: buttonTsPageFileName },
|
||||
{ type: 'markup', path: buttonXmlPageFileName },
|
||||
]);
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_MarkupXml_ScriptTs_StyleScss_Files() {
|
||||
_test_onLiveSync_ModuleReplace_Multiple([
|
||||
{ type: 'script', path: buttonTsPageFileName },
|
||||
{ type: 'markup', path: buttonXmlPageFileName },
|
||||
{ type: 'style', path: buttonScssPageFileName },
|
||||
]);
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_MarkupHtml_ScriptTs_Files() {
|
||||
_test_onLiveSync_ModuleReplace_Multiple([
|
||||
{ type: 'script', path: buttonTsPageFileName },
|
||||
{ type: 'markup', path: buttonHtmlPageFileName },
|
||||
]);
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModuleContext_MarkupHtml_ScriptTs_StyleScss_Files() {
|
||||
_test_onLiveSync_ModuleReplace_Multiple([
|
||||
{ type: 'script', path: buttonTsPageFileName },
|
||||
{ type: 'markup', path: buttonHtmlPageFileName },
|
||||
{ type: 'style', path: buttonScssPageFileName },
|
||||
]);
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModalViewClosed_MarkupXml() {
|
||||
_test_onLiveSync_ModalViewClosed({ type: 'markup', path: modalViewXmlPageFileName });
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModalViewClosed_ScriptTs() {
|
||||
_test_onLiveSync_ModalViewClosed({ type: 'script', path: modalViewTsPageFileName });
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModalViewClosed_ScriptJs() {
|
||||
_test_onLiveSync_ModalViewClosed({ type: 'script', path: modalViewJsPageFileName });
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModalViewClosed_StyleCss() {
|
||||
_test_onLiveSync_ModalViewClosed({ type: 'style', path: modalViewCssFileName });
|
||||
}
|
||||
|
||||
export function test_onLiveSync_ModalViewClosed_StyleScss() {
|
||||
_test_onLiveSync_ModalViewClosed({ type: 'style', path: modalViewScssPageFileName });
|
||||
}
|
||||
|
||||
function _test_onLiveSync_ModuleContext_AppStyle(appStyleFileName: string, livesyncStyleFileName: string) {
|
||||
const pageBeforeNavigation = helper.getCurrentPage();
|
||||
const buttonPage = <Page>Builder.createViewFromEntry({ moduleName: buttonPageModuleName });
|
||||
helper.navigateWithHistory(() => buttonPage);
|
||||
|
||||
app.setCssFileName(appStyleFileName);
|
||||
const pageBeforeLiveSync = helper.getCurrentPage();
|
||||
livesync({ type: 'style', path: livesyncStyleFileName });
|
||||
|
||||
const pageAfterLiveSync = helper.getCurrentPage();
|
||||
TKUnit.waitUntilReady(() => pageAfterLiveSync.getViewById('button').style.color.toString() === green.toString());
|
||||
TKUnit.assertTrue(pageAfterLiveSync.frame.canGoBack(), 'Can NOT go back!');
|
||||
TKUnit.assertEqual(pageAfterLiveSync, pageBeforeLiveSync, 'Pages are different!');
|
||||
TKUnit.assertTrue(pageAfterLiveSync._cssState.isSelectorsLatestVersionApplied(), 'Latest selectors version is NOT applied!');
|
||||
|
||||
helper.goBack();
|
||||
const pageAfterNavigationBack = helper.getCurrentPage();
|
||||
TKUnit.assertEqual(pageAfterNavigationBack.getViewById('label').style.color, green, 'App styles NOT applied on back navigation!');
|
||||
TKUnit.assertEqual(pageBeforeNavigation, pageAfterNavigationBack, 'Pages are different');
|
||||
TKUnit.assertTrue(pageAfterNavigationBack._cssState.isSelectorsLatestVersionApplied(), 'Latest selectors version is NOT applied!');
|
||||
}
|
||||
|
||||
function _test_onLiveSync_ModuleContext(context: ModuleContext) {
|
||||
const buttonPage = <Page>Builder.createViewFromEntry({ moduleName: buttonPageModuleName });
|
||||
helper.navigateWithHistory(() => buttonPage);
|
||||
livesync({ type: context.type, path: context.path });
|
||||
|
||||
TKUnit.waitUntilReady(() => !!Frame.topmost());
|
||||
const topmostFrame = Frame.topmost();
|
||||
TKUnit.waitUntilReady(() => topmostFrame.currentPage && topmostFrame.currentPage.isLoaded && !topmostFrame.canGoBack());
|
||||
TKUnit.assertTrue(topmostFrame.currentPage.getViewById('label').isLoaded);
|
||||
}
|
||||
|
||||
function _test_onLiveSync_ModuleReplace(context: ModuleContext) {
|
||||
const pageBeforeNavigation = helper.getCurrentPage();
|
||||
const buttonPage = <Page>Builder.createViewFromEntry({ moduleName: buttonPageModuleName });
|
||||
helper.navigateWithHistory(() => buttonPage);
|
||||
|
||||
livesync({ type: context.type, path: context.path });
|
||||
const topmostFrame = Frame.topmost();
|
||||
waitUntilLivesyncComplete(topmostFrame);
|
||||
TKUnit.assertTrue(topmostFrame.currentPage.getViewById('button').isLoaded, 'Button page is NOT loaded!');
|
||||
TKUnit.assertEqual(topmostFrame.backStack.length, 1, 'Backstack is clean!');
|
||||
TKUnit.assertTrue(topmostFrame.canGoBack(), 'Can NOT go back!');
|
||||
|
||||
helper.goBack();
|
||||
const pageAfterBackNavigation = helper.getCurrentPage();
|
||||
TKUnit.assertTrue(topmostFrame.currentPage.getViewById('label').isLoaded, 'Label page is NOT loaded!');
|
||||
TKUnit.assertEqual(topmostFrame.backStack.length, 0, 'Backstack is NOT clean!');
|
||||
TKUnit.assertEqual(pageBeforeNavigation, pageAfterBackNavigation, 'Pages are different!');
|
||||
}
|
||||
|
||||
function _test_onLiveSync_ModuleContext_TypeStyle(styleModuleName: string, livesyncStyleFileName: string) {
|
||||
const pageBeforeNavigation = helper.getCurrentPage();
|
||||
const buttonPage = <Page>Builder.createViewFromEntry({ moduleName: buttonPageModuleName });
|
||||
helper.navigateWithHistory(() => buttonPage);
|
||||
|
||||
const pageBeforeLiveSync = helper.getCurrentPage();
|
||||
pageBeforeLiveSync._moduleName = styleModuleName;
|
||||
|
||||
livesync({ type: 'style', path: livesyncStyleFileName });
|
||||
const topmostFrame = Frame.topmost();
|
||||
waitUntilLivesyncComplete(topmostFrame);
|
||||
|
||||
const pageAfterLiveSync = helper.getCurrentPage();
|
||||
TKUnit.waitUntilReady(() => pageAfterLiveSync.getViewById('button').style.color.toString() === green.toString());
|
||||
TKUnit.assertTrue(pageAfterLiveSync.frame.canGoBack(), 'Can NOT go back!');
|
||||
TKUnit.assertEqual(topmostFrame.backStack.length, 1, 'Backstack is clean!');
|
||||
TKUnit.assertTrue(pageAfterLiveSync._cssState.isSelectorsLatestVersionApplied(), 'Latest selectors version is NOT applied!');
|
||||
|
||||
helper.goBack();
|
||||
const pageAfterNavigationBack = helper.getCurrentPage();
|
||||
TKUnit.assertEqual(pageBeforeNavigation, pageAfterNavigationBack, 'Pages are different!');
|
||||
TKUnit.assertTrue(pageAfterNavigationBack._cssState.isSelectorsLatestVersionApplied(), 'Latest selectors version is NOT applied!');
|
||||
}
|
||||
|
||||
function _test_onLiveSync_ModuleReplace_Multiple(context: ModuleContext[]) {
|
||||
const pageBeforeNavigation = helper.getCurrentPage();
|
||||
const buttonPage = <Page>Builder.createViewFromEntry({ moduleName: buttonPageModuleName });
|
||||
helper.navigateWithHistory(() => buttonPage);
|
||||
|
||||
context.forEach((item) => {
|
||||
livesync(item);
|
||||
});
|
||||
|
||||
const topmostFrame = Frame.topmost();
|
||||
waitUntilLivesyncComplete(topmostFrame);
|
||||
TKUnit.assertTrue(topmostFrame.currentPage.getViewById('button').isLoaded, 'Button page is NOT loaded!');
|
||||
TKUnit.assertEqual(topmostFrame.backStack.length, 1, 'Backstack is clean!');
|
||||
TKUnit.assertTrue(topmostFrame.canGoBack(), 'Can NOT go back!');
|
||||
|
||||
helper.goBack();
|
||||
const pageAfterBackNavigation = helper.getCurrentPage();
|
||||
TKUnit.assertTrue(topmostFrame.currentPage.getViewById('label').isLoaded, 'Label page is NOT loaded!');
|
||||
TKUnit.assertEqual(topmostFrame.backStack.length, 0, 'Backstack is NOT clean!');
|
||||
TKUnit.assertEqual(pageBeforeNavigation, pageAfterBackNavigation, 'Pages are different!');
|
||||
}
|
||||
|
||||
function _test_onLiveSync_ModalViewClosed(context: ModuleContext) {
|
||||
const modalViewPage = <Page>Builder.createViewFromEntry({ moduleName: modalViewPageModuleName });
|
||||
helper.navigateWithHistory(() => modalViewPage);
|
||||
livesync({ type: context.type, path: context.path });
|
||||
|
||||
TKUnit.waitUntilReady(() => !!Frame.topmost());
|
||||
const topmostFrame = Frame.topmost();
|
||||
TKUnit.waitUntilReady(() => topmostFrame.currentPage && topmostFrame.currentPage.isLoaded && topmostFrame.canGoBack());
|
||||
|
||||
TKUnit.assertTrue(topmostFrame._getRootModalViews().length === 0);
|
||||
}
|
||||
|
||||
function livesync(context: ModuleContext) {
|
||||
const ls = (<any>global).__coreModulesLiveSync || global.__onLiveSync;
|
||||
ls(context);
|
||||
}
|
||||
|
||||
function waitUntilLivesyncComplete(frame: Frame) {
|
||||
TKUnit.waitUntilReady(() => frame.navigationQueueIsEmpty());
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
import { Trace, Page } from "@nativescript/core";
|
||||
import { Trace, Page } from '@nativescript/core';
|
||||
|
||||
import * as tests from "./test-runner";
|
||||
import * as tests from './test-runner';
|
||||
|
||||
let executeTests = true;
|
||||
|
||||
Trace.enable();
|
||||
Trace.addCategories(Trace.categories.Test + "," + Trace.categories.Error);
|
||||
Trace.addCategories(Trace.categories.Test + ',' + Trace.categories.Error);
|
||||
|
||||
// When debugging
|
||||
// Trace.setCategories(Trace.categories.concat(
|
||||
@@ -18,13 +18,13 @@ Trace.addCategories(Trace.categories.Test + "," + Trace.categories.Error);
|
||||
// ));
|
||||
|
||||
function runTests() {
|
||||
setTimeout(() => tests.runAll(""), 10);
|
||||
setTimeout(() => tests.runAll(''), 10);
|
||||
}
|
||||
|
||||
export function onNavigatedTo(args) {
|
||||
args.object.off(Page.loadedEvent, onNavigatedTo);
|
||||
if (executeTests) {
|
||||
executeTests = false;
|
||||
runTests();
|
||||
}
|
||||
args.object.off(Page.loadedEvent, onNavigatedTo);
|
||||
if (executeTests) {
|
||||
executeTests = false;
|
||||
runTests();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import { ModuleNameResolver, ModuleListProvider } from '@nativescript/core';
|
||||
|
||||
import { androidPhonePortraitContext, androidPhoneLandscapeContext, androidTabletPortraitContext, iPhoneLandscapeContext, iPhonePortraitContext } from './qualifier-matcher-tests';
|
||||
|
||||
const testModule = 'name-resolvers-tests/files/test';
|
||||
const moduleProvider: ModuleListProvider = () => {
|
||||
return ['name-resolvers-tests/files/other.xml', 'name-resolvers-tests/files/test.land.xml', 'name-resolvers-tests/files/test.minWH600.xml', 'name-resolvers-tests/files/test.xml'];
|
||||
};
|
||||
|
||||
export function test_module_name_resolver_with_android_phone_portrait() {
|
||||
const moduleResolver = new ModuleNameResolver(androidPhonePortraitContext, moduleProvider);
|
||||
const result = moduleResolver.resolveModuleName(testModule, 'xml');
|
||||
TKUnit.assertEqual(result, testModule + '.xml');
|
||||
}
|
||||
|
||||
export function test_module_name_resolver_with_android_phone_landscape() {
|
||||
const moduleResolver = new ModuleNameResolver(androidPhoneLandscapeContext, moduleProvider);
|
||||
const result = moduleResolver.resolveModuleName(testModule, 'xml');
|
||||
TKUnit.assertEqual(result, testModule + '.land.xml');
|
||||
}
|
||||
|
||||
export function test_module_name_resolver_with_android_tablet_portrait() {
|
||||
const moduleResolver = new ModuleNameResolver(androidTabletPortraitContext, moduleProvider);
|
||||
const result = moduleResolver.resolveModuleName(testModule, 'xml');
|
||||
TKUnit.assertEqual(result, testModule + '.minWH600.xml');
|
||||
}
|
||||
|
||||
export function test_module_name_resolver_with_ios_phone_landscape() {
|
||||
const moduleResolver = new ModuleNameResolver(iPhoneLandscapeContext, moduleProvider);
|
||||
const result = moduleResolver.resolveModuleName(testModule, 'xml');
|
||||
TKUnit.assertEqual(result, testModule + '.land.xml');
|
||||
}
|
||||
|
||||
export function test_module_name_resolver_with_ios_phone_portrait() {
|
||||
const moduleResolver = new ModuleNameResolver(iPhonePortraitContext, moduleProvider);
|
||||
const result = moduleResolver.resolveModuleName(testModule, 'xml');
|
||||
TKUnit.assertEqual(result, testModule + '.xml');
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import * as enums from '@nativescript/core/ui/enums';
|
||||
import { findMatch, PlatformContext } from '@nativescript/core/module-name-resolver/qualifier-matcher';
|
||||
|
||||
export const androidPhonePortraitContext: PlatformContext = {
|
||||
width: 360,
|
||||
height: 640,
|
||||
deviceType: enums.DeviceType.Phone,
|
||||
os: 'android',
|
||||
};
|
||||
|
||||
export const androidPhoneLandscapeContext: PlatformContext = {
|
||||
width: 640,
|
||||
height: 360,
|
||||
deviceType: enums.DeviceType.Phone,
|
||||
os: 'android',
|
||||
};
|
||||
|
||||
export const androidTabletPortraitContext: PlatformContext = {
|
||||
width: 600,
|
||||
height: 960,
|
||||
deviceType: enums.DeviceType.Tablet,
|
||||
os: 'android',
|
||||
};
|
||||
|
||||
export const iPhonePortraitContext: PlatformContext = {
|
||||
width: 320,
|
||||
height: 480,
|
||||
deviceType: enums.DeviceType.Phone,
|
||||
os: 'ios',
|
||||
};
|
||||
|
||||
export const iPhoneLandscapeContext: PlatformContext = {
|
||||
width: 480,
|
||||
height: 320,
|
||||
deviceType: enums.DeviceType.Phone,
|
||||
os: 'ios',
|
||||
};
|
||||
|
||||
export function test_findFileMatch_fileName() {
|
||||
var candidates: Array<string> = ['test.xml', 'test2.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidPhonePortraitContext, 'test.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_os_android() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.ios.xml', 'test.android.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidPhonePortraitContext, 'test.android.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_os_ios() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.ios.xml', 'test.android.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, iPhonePortraitContext, 'test.ios.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_os_fallback() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.ios.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidPhonePortraitContext, 'test.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_minWH_fallback() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.minWH600.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidPhonePortraitContext, 'test.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_minWH_best_value() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.minWH400.xml', 'test.minWH500.xml', 'test.minWH600.xml', 'test.minWH700.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidTabletPortraitContext, 'test.minWH600.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_minW_fallback() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.minW600.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidPhonePortraitContext, 'test.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_minW_best_value() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.minW400.xml', 'test.minW500.xml', 'test.minW600.xml', 'test.minW700.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidTabletPortraitContext, 'test.minW600.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_minH_fallback() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.minH600.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidPhoneLandscapeContext, 'test.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_minH_best_value() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.minH400.xml', 'test.minH500.xml', 'test.minH600.xml', 'test.minH700.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidPhonePortraitContext, 'test.minH600.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_orientation_fallback() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.land.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidTabletPortraitContext, 'test.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_orientation_portrait() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.land.xml', 'test.port.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidTabletPortraitContext, 'test.port.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_orientation_landscape() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.land.xml', 'test.port.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidPhoneLandscapeContext, 'test.land.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_choose_most_specific_file() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.android.xml', 'test.android.port.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidPhonePortraitContext, 'test.android.port.xml');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_with_multiple_matches_loads_by_priority() {
|
||||
var candidates: Array<string> = ['test.xml', 'test.android.xml', 'test.tablet.xml', 'test.land.xml', 'test.minH600.xml', 'test.minW600.xml', 'test.minWH600.xml', 'other.xml'];
|
||||
|
||||
findMatchTemplate(candidates, androidTabletPortraitContext, 'test.minWH600.xml');
|
||||
}
|
||||
|
||||
function findMatchTemplate(candidates: Array<string>, context: PlatformContext, expected: string) {
|
||||
var result = findMatch('test', '.xml', candidates, context);
|
||||
TKUnit.assertEqual(result, expected, 'module name');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_with_empty_extension() {
|
||||
var candidates: Array<string> = ['test', 'other'];
|
||||
|
||||
var result = findMatch('test', '', candidates, androidTabletPortraitContext);
|
||||
TKUnit.assertEqual(result, 'test', 'module name');
|
||||
}
|
||||
|
||||
export function test_findFileMatch_with_null_extension() {
|
||||
var candidates: Array<string> = ['test', 'other'];
|
||||
|
||||
var result = findMatch('test', null, candidates, androidTabletPortraitContext);
|
||||
TKUnit.assertEqual(result, 'test', 'module name');
|
||||
}
|
||||
36
apps/automated/app/navigation/custom-transition.android.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import * as transition from '@nativescript/core/ui/transition';
|
||||
|
||||
export class CustomTransition extends transition.Transition {
|
||||
constructor(duration: number, curve: any) {
|
||||
super(duration, curve);
|
||||
}
|
||||
|
||||
public createAndroidAnimator(transitionType: string): android.animation.Animator {
|
||||
var scaleValues = Array.create('float', 2);
|
||||
switch (transitionType) {
|
||||
case transition.AndroidTransitionType.enter:
|
||||
case transition.AndroidTransitionType.popEnter:
|
||||
scaleValues[0] = 0;
|
||||
scaleValues[1] = 1;
|
||||
break;
|
||||
case transition.AndroidTransitionType.exit:
|
||||
case transition.AndroidTransitionType.popExit:
|
||||
scaleValues[0] = 1;
|
||||
scaleValues[1] = 0;
|
||||
break;
|
||||
}
|
||||
var objectAnimators = Array.create(android.animation.Animator, 2);
|
||||
objectAnimators[0] = android.animation.ObjectAnimator.ofFloat(null, 'scaleX', scaleValues);
|
||||
objectAnimators[1] = android.animation.ObjectAnimator.ofFloat(null, 'scaleY', scaleValues);
|
||||
var animatorSet = new android.animation.AnimatorSet();
|
||||
animatorSet.playTogether(objectAnimators);
|
||||
|
||||
var duration = this.getDuration();
|
||||
if (duration !== undefined) {
|
||||
animatorSet.setDuration(duration);
|
||||
}
|
||||
animatorSet.setInterpolator(this.getCurve());
|
||||
|
||||
return animatorSet;
|
||||
}
|
||||
}
|
||||
6
apps/automated/app/navigation/custom-transition.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Transition } from '@nativescript/core/ui/transition';
|
||||
|
||||
export class CustomTransition extends Transition {
|
||||
constructor();
|
||||
constructor(duration: number, curve: any);
|
||||
}
|
||||
33
apps/automated/app/navigation/custom-transition.ios.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import * as transition from '@nativescript/core/ui/transition';
|
||||
|
||||
export class CustomTransition extends transition.Transition {
|
||||
constructor(duration: number, curve: any) {
|
||||
super(duration, curve);
|
||||
}
|
||||
|
||||
public animateIOSTransition(containerView: UIView, fromView: UIView, toView: UIView, operation: UINavigationControllerOperation, completion: (finished: boolean) => void): void {
|
||||
toView.transform = CGAffineTransformMakeScale(0, 0);
|
||||
fromView.transform = CGAffineTransformIdentity;
|
||||
|
||||
switch (operation) {
|
||||
case UINavigationControllerOperation.Push:
|
||||
containerView.insertSubviewAboveSubview(toView, fromView);
|
||||
break;
|
||||
case UINavigationControllerOperation.Pop:
|
||||
containerView.insertSubviewBelowSubview(toView, fromView);
|
||||
break;
|
||||
}
|
||||
|
||||
var duration = this.getDuration();
|
||||
var curve = this.getCurve();
|
||||
UIView.animateWithDurationAnimationsCompletion(
|
||||
duration,
|
||||
() => {
|
||||
UIView.setAnimationCurve(curve);
|
||||
toView.transform = CGAffineTransformIdentity;
|
||||
fromView.transform = CGAffineTransformMakeScale(0, 0);
|
||||
},
|
||||
completion
|
||||
);
|
||||
}
|
||||
}
|
||||
467
apps/automated/app/navigation/navigation-tests.ts
Normal file
@@ -0,0 +1,467 @@
|
||||
import * as TKUnit from '../tk-unit';
|
||||
import { EventData, Page, NavigatedData } from '@nativescript/core';
|
||||
import { Frame, NavigationTransition } from '@nativescript/core/ui/frame';
|
||||
import { StackLayout } from '@nativescript/core/ui/layouts/stack-layout';
|
||||
import { Color } from '@nativescript/core/color';
|
||||
import * as helper from '../ui-helper';
|
||||
import * as frame from '@nativescript/core/ui/frame';
|
||||
// Creates a random colorful page full of meaningless stuff.
|
||||
let id = 0;
|
||||
let pageFactory = function (): Page {
|
||||
const page = new Page();
|
||||
page.actionBarHidden = true;
|
||||
page.id = `NavTestPage${id++}`;
|
||||
page.style.backgroundColor = new Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
|
||||
return page;
|
||||
};
|
||||
|
||||
function attachEventListeners(page: Page, events: Array<string>) {
|
||||
let argsToString = (args: NavigatedData) => {
|
||||
return `${(<Page>args.object).id} ${args.eventName} ${args.isBackNavigation ? 'back' : 'forward'}`;
|
||||
};
|
||||
|
||||
page.on(Page.navigatingFromEvent, (args: NavigatedData) => {
|
||||
events.push(argsToString(args));
|
||||
});
|
||||
page.on(Page.navigatedFromEvent, (args: NavigatedData) => {
|
||||
events.push(argsToString(args));
|
||||
});
|
||||
page.on(Page.navigatingToEvent, (args: NavigatedData) => {
|
||||
events.push(argsToString(args));
|
||||
});
|
||||
page.on(Page.navigatedToEvent, (args: NavigatedData) => {
|
||||
events.push(argsToString(args));
|
||||
});
|
||||
}
|
||||
|
||||
function _test_backstackVisible(transition?: NavigationTransition) {
|
||||
let topmost = Frame.topmost();
|
||||
let mainTestPage = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, transition: transition, animated: !!transition });
|
||||
TKUnit.waitUntilReady(() => topmost.navigationQueueIsEmpty());
|
||||
// page1 should not be added to the backstack
|
||||
let page0 = topmost.currentPage;
|
||||
topmost.navigate({ create: pageFactory, backstackVisible: false, transition: transition, animated: !!transition });
|
||||
topmost.navigate({ create: pageFactory, transition: transition, animated: !!transition });
|
||||
topmost.goBack();
|
||||
TKUnit.waitUntilReady(() => topmost.navigationQueueIsEmpty());
|
||||
// From page2 we have to go directly to page0, skipping page1.
|
||||
TKUnit.assertEqual(topmost.currentPage, page0, 'Page 1 should be skipped when going back.');
|
||||
|
||||
helper.goBack();
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
}
|
||||
|
||||
export function test_backstackVisible() {
|
||||
_test_backstackVisible();
|
||||
}
|
||||
|
||||
export function test_backstackVisible_WithTransition() {
|
||||
_test_backstackVisible({ name: 'fade', duration: 10 });
|
||||
}
|
||||
|
||||
export function test_backAndForwardParentPage_nestedFrames() {
|
||||
const topmost = Frame.topmost();
|
||||
const mainTestPage = topmost.currentPage;
|
||||
let innerFrame;
|
||||
|
||||
const page = (title) => {
|
||||
const p = new Page();
|
||||
p['tag'] = title;
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
const parentPage = (title, innerPage) => {
|
||||
const parentPage = new Page();
|
||||
parentPage['tag'] = title;
|
||||
|
||||
const stack = new StackLayout();
|
||||
innerFrame = new frame.Frame();
|
||||
innerFrame.navigate({ create: () => innerPage });
|
||||
stack.addChild(innerFrame);
|
||||
parentPage.content = stack;
|
||||
|
||||
return parentPage;
|
||||
};
|
||||
|
||||
const back = (pages) => Frame.topmost().goBack(Frame.topmost().backStack[Frame.topmost().backStack.length - pages]);
|
||||
const currentPageMustBe = (tag) => TKUnit.assertEqual(Frame.topmost().currentPage['tag'], tag, 'Expected current page to be ' + tag + ' it was ' + Frame.topmost().currentPage['tag'] + ' instead.');
|
||||
|
||||
let parentPage1, parentPage2, innerPage1, innerPage2;
|
||||
innerPage1 = page('InnerPage1');
|
||||
innerPage2 = page('InnerPage2');
|
||||
parentPage1 = page('ParentPage1');
|
||||
parentPage2 = parentPage('ParentPage2', innerPage1);
|
||||
|
||||
helper.waitUntilNavigatedTo(parentPage1, () => topmost.navigate({ create: () => parentPage1 }));
|
||||
currentPageMustBe('ParentPage1');
|
||||
|
||||
helper.waitUntilNavigatedTo(parentPage2, () => topmost.navigate({ create: () => parentPage2 }));
|
||||
currentPageMustBe('ParentPage2');
|
||||
|
||||
helper.waitUntilNavigatedTo(innerPage2, () => innerFrame.navigate({ create: () => innerPage2 }));
|
||||
currentPageMustBe('InnerPage2');
|
||||
|
||||
helper.waitUntilNavigatedTo(innerPage1, () => Frame.goBack());
|
||||
currentPageMustBe('InnerPage1');
|
||||
|
||||
helper.waitUntilNavigatedTo(parentPage1, () => Frame.goBack());
|
||||
currentPageMustBe('ParentPage1');
|
||||
|
||||
const innerPage3 = page('InnerPage3');
|
||||
const parentPage3 = parentPage('ParentPage3', innerPage3);
|
||||
|
||||
helper.waitUntilNavigatedTo(parentPage3, () => topmost.navigate({ create: () => parentPage3 }));
|
||||
currentPageMustBe('ParentPage3');
|
||||
|
||||
back(2);
|
||||
TKUnit.waitUntilReady(() => Frame.topmost().navigationQueueIsEmpty());
|
||||
|
||||
const frameStack = Frame._stack();
|
||||
TKUnit.assertEqual(frameStack.length, 1, 'There should be only one frame left in the stack');
|
||||
TKUnit.assertEqual(Frame.topmost().currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
}
|
||||
|
||||
function _test_backToEntry(transition?: NavigationTransition) {
|
||||
const topmost = Frame.topmost();
|
||||
const page = (tag) => () => {
|
||||
const p = new Page();
|
||||
p.actionBarHidden = true;
|
||||
p.id = `NavTestPage${id++}`;
|
||||
p['tag'] = tag;
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
const mainTestPage = topmost.currentPage;
|
||||
|
||||
const navigate = (tag) => topmost.navigate({ create: page(tag), transition: transition, animated: !!transition });
|
||||
const back = (pages) => topmost.goBack(topmost.backStack[topmost.backStack.length - pages]);
|
||||
const currentPageMustBe = (tag) => TKUnit.assertEqual(topmost.currentPage['tag'], tag, 'Expected current page to be ' + tag + ' it was ' + topmost.currentPage['tag'] + ' instead.');
|
||||
|
||||
navigate('page1');
|
||||
navigate('page2');
|
||||
navigate('page3');
|
||||
navigate('page4');
|
||||
TKUnit.waitUntilReady(() => topmost.navigationQueueIsEmpty());
|
||||
|
||||
currentPageMustBe('page4');
|
||||
|
||||
back(2);
|
||||
TKUnit.waitUntilReady(() => topmost.navigationQueueIsEmpty());
|
||||
|
||||
currentPageMustBe('page2');
|
||||
|
||||
back(1);
|
||||
TKUnit.waitUntilReady(() => topmost.navigationQueueIsEmpty());
|
||||
|
||||
currentPageMustBe('page1');
|
||||
|
||||
navigate('page1.1');
|
||||
navigate('page1.2');
|
||||
TKUnit.waitUntilReady(() => topmost.navigationQueueIsEmpty());
|
||||
|
||||
currentPageMustBe('page1.2');
|
||||
|
||||
back(1);
|
||||
TKUnit.waitUntilReady(() => topmost.navigationQueueIsEmpty());
|
||||
|
||||
currentPageMustBe('page1.1');
|
||||
|
||||
back(1);
|
||||
TKUnit.waitUntilReady(() => topmost.navigationQueueIsEmpty());
|
||||
|
||||
currentPageMustBe('page1');
|
||||
|
||||
back(1);
|
||||
TKUnit.waitUntilReady(() => topmost.navigationQueueIsEmpty());
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
}
|
||||
|
||||
export function test_backToEntry() {
|
||||
_test_backToEntry();
|
||||
}
|
||||
|
||||
export function test_backToEntry_WithTransition() {
|
||||
_test_backToEntry({ name: 'fade', duration: 10 });
|
||||
}
|
||||
|
||||
function _test_ClearHistory(transition?: NavigationTransition) {
|
||||
let topmost = Frame.topmost();
|
||||
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, '1.topmost.backStack.length');
|
||||
TKUnit.assertEqual(topmost.canGoBack(), false, '1.topmost.canGoBack().');
|
||||
|
||||
helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
|
||||
TKUnit.assertEqual(topmost.backStack.length, 1, '2.topmost.backStack.length');
|
||||
TKUnit.assertEqual(topmost.canGoBack(), true, '2.topmost.canGoBack().');
|
||||
|
||||
helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
|
||||
TKUnit.assertEqual(topmost.backStack.length, 2, '3.topmost.backStack.length');
|
||||
TKUnit.assertEqual(topmost.canGoBack(), true, '3.topmost.canGoBack().');
|
||||
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: transition, animated: !!transition });
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, '4.topmost.backStack.length');
|
||||
TKUnit.assertEqual(topmost.canGoBack(), false, '4.topmost.canGoBack().');
|
||||
}
|
||||
|
||||
export function test_ClearHistory() {
|
||||
_test_ClearHistory();
|
||||
}
|
||||
|
||||
export function test_ClearHistory_WithTransition() {
|
||||
_test_ClearHistory({ name: 'fade', duration: 10 });
|
||||
}
|
||||
|
||||
// Test case for https://github.com/NativeScript/NativeScript/issues/1948
|
||||
export function test_ClearHistoryWithTransitionDoesNotBreakNavigation() {
|
||||
let topmost = Frame.topmost();
|
||||
let mainTestPage = new Page();
|
||||
let mainPageFactory = function (): Page {
|
||||
return mainTestPage;
|
||||
};
|
||||
|
||||
// Go to details-page
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
|
||||
|
||||
// Go back to main-page with clearHistory
|
||||
topmost.transition = { name: 'fade', duration: 10 };
|
||||
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
|
||||
|
||||
// Go to details-page AGAIN
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, animated: true });
|
||||
|
||||
// Go back to main-page with clearHistory
|
||||
topmost.transition = { name: 'fade', duration: 10 };
|
||||
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: true });
|
||||
|
||||
// Clean up
|
||||
topmost.transition = undefined;
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
|
||||
}
|
||||
|
||||
export function test_ClearHistoryWithTransitionDoesNotBreakNavigation_WithLocalTransition() {
|
||||
const topmost = Frame.topmost();
|
||||
|
||||
let mainTestPage = topmost.currentPage;
|
||||
let mainPageFactory = function (): Page {
|
||||
return mainTestPage;
|
||||
};
|
||||
|
||||
// Go to 1st page
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
|
||||
// Go to 2nd page
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: false, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
|
||||
// Go to 3rd page with clearHistory
|
||||
helper.navigateWithEntry({ create: pageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
|
||||
// Go back to main
|
||||
helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, transition: { name: 'fade', duration: 10 }, animated: true });
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
TKUnit.assertEqual(topmost.backStack.length, 0, 'Back stack should be empty at the end of the test.');
|
||||
}
|
||||
|
||||
function _test_NavigationEvents(transition?: NavigationTransition) {
|
||||
const topmost = Frame.topmost();
|
||||
const mainTestPage = topmost.currentPage;
|
||||
const originalMainPageId = mainTestPage.id;
|
||||
|
||||
mainTestPage.id = 'main-page';
|
||||
let actualMainPageEvents = new Array<string>();
|
||||
attachEventListeners(mainTestPage, actualMainPageEvents);
|
||||
|
||||
let actualSecondPageEvents = new Array<string>();
|
||||
let secondPageFactory = function (): Page {
|
||||
const secondPage = new Page();
|
||||
secondPage.actionBarHidden = true;
|
||||
secondPage.id = 'second-page';
|
||||
attachEventListeners(secondPage, actualSecondPageEvents);
|
||||
secondPage.style.backgroundColor = new Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
|
||||
return secondPage;
|
||||
};
|
||||
|
||||
// Go to other page
|
||||
helper.navigateWithEntry({ create: secondPageFactory, transition: transition, animated: !!transition });
|
||||
|
||||
// Go back to main
|
||||
helper.goBack();
|
||||
|
||||
mainTestPage.id = originalMainPageId;
|
||||
|
||||
let expectedMainPageEvents = ['main-page navigatingFrom forward', 'main-page navigatedFrom forward', 'main-page navigatingTo back', 'main-page navigatedTo back'];
|
||||
TKUnit.arrayAssert(actualMainPageEvents, expectedMainPageEvents, 'Actual main-page events are different from expected.');
|
||||
|
||||
let expectedSecondPageEvents = ['second-page navigatingTo forward', 'second-page navigatedTo forward', 'second-page navigatingFrom back', 'second-page navigatedFrom back'];
|
||||
TKUnit.arrayAssert(actualSecondPageEvents, expectedSecondPageEvents, 'Actual second-page events are different from expected.');
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
}
|
||||
|
||||
export function test_NavigationEvents() {
|
||||
_test_NavigationEvents();
|
||||
}
|
||||
|
||||
export function test_NavigationEvents_WithTransition() {
|
||||
_test_NavigationEvents({ name: 'fade', duration: 10 });
|
||||
}
|
||||
|
||||
function _test_NavigationEvents_WithBackstackVisibile_False_Forward_Back(transition?: NavigationTransition) {
|
||||
const topmost = Frame.topmost();
|
||||
const mainTestPage = topmost.currentPage;
|
||||
|
||||
let actualSecondPageEvents = new Array<string>();
|
||||
let secondPageFactory = function (): Page {
|
||||
const secondPage = new Page();
|
||||
secondPage.actionBarHidden = true;
|
||||
secondPage.id = 'second-page';
|
||||
attachEventListeners(secondPage, actualSecondPageEvents);
|
||||
secondPage.style.backgroundColor = new Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
|
||||
return secondPage;
|
||||
};
|
||||
|
||||
// Go to other page
|
||||
helper.navigateWithEntry({ create: secondPageFactory, transition: transition, animated: !!transition, backstackVisible: false });
|
||||
|
||||
// Go back to main
|
||||
helper.goBack();
|
||||
|
||||
let expectedSecondPageEvents = ['second-page navigatingTo forward', 'second-page navigatedTo forward', 'second-page navigatingFrom back', 'second-page navigatedFrom back'];
|
||||
TKUnit.arrayAssert(actualSecondPageEvents, expectedSecondPageEvents, 'Actual second-page events are different from expected.');
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
}
|
||||
|
||||
export function test_NavigationEvents_WithBackstackVisibile_False_Forward_Back() {
|
||||
_test_NavigationEvents_WithBackstackVisibile_False_Forward_Back();
|
||||
}
|
||||
|
||||
export function test_NavigationEvents_WithBackstackVisibile_False_Forward_Back_WithTransition() {
|
||||
_test_NavigationEvents_WithBackstackVisibile_False_Forward_Back({ name: 'fade', duration: 10 });
|
||||
}
|
||||
|
||||
function _test_NavigationEvents_WithBackstackVisibile_False_Forward_Forward(transition?: NavigationTransition) {
|
||||
const topmost = Frame.topmost();
|
||||
const mainTestPage = topmost.currentPage;
|
||||
|
||||
let actualSecondPageEvents = new Array<string>();
|
||||
let secondPageFactory = function (): Page {
|
||||
const secondPage = new Page();
|
||||
secondPage.actionBarHidden = true;
|
||||
secondPage.id = 'second-page';
|
||||
attachEventListeners(secondPage, actualSecondPageEvents);
|
||||
secondPage.style.backgroundColor = new Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
|
||||
return secondPage;
|
||||
};
|
||||
|
||||
// Go to other page
|
||||
helper.navigateWithEntry({ create: secondPageFactory, transition: transition, animated: !!transition, backstackVisible: false });
|
||||
|
||||
// Go forward to third page
|
||||
helper.navigateWithEntry({ create: pageFactory, transition: transition, animated: !!transition });
|
||||
|
||||
// Go back to main
|
||||
helper.goBack();
|
||||
|
||||
let expectedSecondPageEvents = ['second-page navigatingTo forward', 'second-page navigatedTo forward', 'second-page navigatingFrom forward', 'second-page navigatedFrom forward'];
|
||||
TKUnit.arrayAssert(actualSecondPageEvents, expectedSecondPageEvents, 'Actual second-page events are different from expected.');
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, mainTestPage, 'We should be on the main test page at the end of the test.');
|
||||
}
|
||||
|
||||
export function test_NavigationEvents_WithBackstackVisibile_False_Forward_Forward() {
|
||||
_test_NavigationEvents_WithBackstackVisibile_False_Forward_Forward();
|
||||
}
|
||||
|
||||
export function test_NavigationEvents_WithBackstackVisibile_False_Forward_Forward_WithTransition() {
|
||||
_test_NavigationEvents_WithBackstackVisibile_False_Forward_Forward({ name: 'fade', duration: 10 });
|
||||
}
|
||||
|
||||
function _test_NavigationEvents_WithClearHistory(transition?: NavigationTransition) {
|
||||
const topmost = Frame.topmost();
|
||||
const mainTestPage = topmost.currentPage;
|
||||
|
||||
mainTestPage.id = 'main-page';
|
||||
const actualMainPageEvents = new Array<string>();
|
||||
attachEventListeners(mainTestPage, actualMainPageEvents);
|
||||
|
||||
const actualSecondPageEvents = new Array<string>();
|
||||
const secondPage = new Page();
|
||||
const secondPageFactory = function (): Page {
|
||||
secondPage.actionBarHidden = true;
|
||||
secondPage.id = 'second-page';
|
||||
attachEventListeners(secondPage, actualSecondPageEvents);
|
||||
secondPage.style.backgroundColor = new Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
|
||||
return secondPage;
|
||||
};
|
||||
|
||||
// Go to second page
|
||||
helper.navigateWithEntry({ create: secondPageFactory, transition: transition, animated: !!transition, clearHistory: true });
|
||||
|
||||
const expectedMainPageEvents = ['main-page navigatingFrom forward', 'main-page navigatedFrom forward'];
|
||||
TKUnit.arrayAssert(actualMainPageEvents, expectedMainPageEvents, 'Actual main-page events are different from expected.');
|
||||
|
||||
const expectedSecondPageEvents = ['second-page navigatingTo forward', 'second-page navigatedTo forward'];
|
||||
TKUnit.arrayAssert(actualSecondPageEvents, expectedSecondPageEvents, 'Actual main-page events are different from expected.');
|
||||
|
||||
TKUnit.assertEqual(topmost.currentPage, secondPage, 'We should be on the second page at the end of the test.');
|
||||
}
|
||||
|
||||
export function test_NavigationEvents_WithClearHistory() {
|
||||
_test_NavigationEvents_WithClearHistory();
|
||||
}
|
||||
|
||||
export function test_NavigationEvents_WithClearHistory_WithTransition() {
|
||||
_test_NavigationEvents_WithClearHistory({ name: 'fade', duration: 10 });
|
||||
}
|
||||
|
||||
export function test_Navigate_From_Page_Loaded_Handler() {
|
||||
_test_Navigate_From_Page_Event_Handler(Page.loadedEvent);
|
||||
}
|
||||
|
||||
export function test_Navigate_From_Page_NavigatedTo_Handler() {
|
||||
_test_Navigate_From_Page_Event_Handler(Page.navigatedToEvent);
|
||||
}
|
||||
|
||||
function _test_Navigate_From_Page_Event_Handler(eventName: string) {
|
||||
let secondPageNavigatedTo = false;
|
||||
|
||||
const firstPageFactory = function (): Page {
|
||||
const firstPage = new Page();
|
||||
firstPage.id = 'first-page';
|
||||
firstPage.on(eventName, (args: EventData) => {
|
||||
const page = <Page>args.object;
|
||||
const frame = page.frame;
|
||||
|
||||
const secondPageFactory = function (): Page {
|
||||
const secondPage = new Page();
|
||||
secondPage.id = 'second-page';
|
||||
secondPage.on(Page.navigatedToEvent, () => {
|
||||
secondPageNavigatedTo = true;
|
||||
});
|
||||
|
||||
return secondPage;
|
||||
};
|
||||
|
||||
frame.navigate(secondPageFactory);
|
||||
});
|
||||
|
||||
return firstPage;
|
||||
};
|
||||
|
||||
helper.navigateWithEntry({ create: firstPageFactory });
|
||||
|
||||
TKUnit.waitUntilReady(() => secondPageNavigatedTo);
|
||||
}
|
||||
58
apps/automated/app/navigation/transition-tests.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import * as helper from '../ui-helper';
|
||||
import * as platform from '@nativescript/core/platform';
|
||||
import { Trace } from '@nativescript/core';
|
||||
import { Color } from '@nativescript/core/color';
|
||||
import { NavigationEntry, NavigationTransition } from '@nativescript/core/ui/frame';
|
||||
import { Page } from '@nativescript/core/ui/page';
|
||||
import { AnimationCurve } from '@nativescript/core/ui/enums';
|
||||
import { CustomTransition } from './custom-transition';
|
||||
|
||||
function _testTransition(navigationTransition: NavigationTransition) {
|
||||
var testId = `Transition[${JSON.stringify(navigationTransition)}]`;
|
||||
if (Trace.isEnabled()) {
|
||||
Trace.write(`Testing ${testId}`, Trace.categories.Test);
|
||||
}
|
||||
var navigationEntry: NavigationEntry = {
|
||||
create: function (): Page {
|
||||
let page = new Page();
|
||||
page.id = testId;
|
||||
page.style.backgroundColor = new Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
|
||||
return page;
|
||||
},
|
||||
animated: true,
|
||||
transition: navigationTransition,
|
||||
};
|
||||
|
||||
helper.navigateWithEntry(navigationEntry);
|
||||
}
|
||||
|
||||
export function test_Transitions() {
|
||||
helper.navigate(() => {
|
||||
const page = new Page();
|
||||
page.id = 'TransitionsTestPage_MAIN';
|
||||
page.style.backgroundColor = new Color(255, Math.round(Math.random() * 255), Math.round(Math.random() * 255), Math.round(Math.random() * 255));
|
||||
|
||||
return page;
|
||||
});
|
||||
|
||||
var transitions;
|
||||
if (platform.Device.os === platform.platformNames.ios) {
|
||||
transitions = ['curl'];
|
||||
} else {
|
||||
const _sdkVersion = parseInt(platform.Device.sdkVersion);
|
||||
transitions = _sdkVersion >= 21 ? ['explode'] : [];
|
||||
}
|
||||
|
||||
transitions = transitions.concat(['fade', 'slide']);
|
||||
|
||||
// Custom transition
|
||||
_testTransition({ instance: new CustomTransition(), duration: 10 });
|
||||
|
||||
// Built-in transitions
|
||||
transitions.forEach((name) => {
|
||||
_testTransition({ name, duration: 20, curve: AnimationCurve.easeIn });
|
||||
});
|
||||
|
||||
// helper.navigateWithEntry({ create: mainPageFactory, clearHistory: true, animated: false });
|
||||
}
|
||||
13
apps/automated/app/pages/background-test.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import * as view from '@nativescript/core/ui/core/view';
|
||||
import * as pages from '@nativescript/core/ui/page';
|
||||
|
||||
export function applyTap(args) {
|
||||
var page = <pages.Page>(<view.View>args.object).page;
|
||||
var css = '#test-element { ' + args.object.tag + ' }';
|
||||
page.css = css;
|
||||
}
|
||||
|
||||
export function resetTap(args) {
|
||||
var page = <pages.Page>(<view.View>args.object).page;
|
||||
page.css = '';
|
||||
}
|
||||
28
apps/automated/app/pages/file-load-test.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Page, Label, knownFolders, path, ModuleNameResolver } from '@nativescript/core';
|
||||
|
||||
export function createPage() {
|
||||
var page = new Page();
|
||||
var lbl = new Label();
|
||||
|
||||
var moduleName = 'tests/pages/files/test';
|
||||
|
||||
ModuleNameResolver;
|
||||
var resolver = new ModuleNameResolver({
|
||||
width: 400,
|
||||
height: 600,
|
||||
os: 'android',
|
||||
deviceType: 'phone',
|
||||
});
|
||||
|
||||
// Current app full path.
|
||||
var currentAppPath = knownFolders.currentApp().path;
|
||||
var moduleNamePath = path.join(currentAppPath, moduleName);
|
||||
|
||||
var fileName = resolver.resolveModuleName(moduleNamePath, 'xml');
|
||||
lbl.text = fileName;
|
||||
lbl.textWrap = true;
|
||||
|
||||
page.content = lbl;
|
||||
|
||||
return page;
|
||||
}
|
||||
17
apps/automated/app/pages/fonts-test.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import * as stack from '@nativescript/core/ui/layouts/stack-layout';
|
||||
import { unsetValue } from '@nativescript/core';
|
||||
|
||||
export function buttonTap(args) {
|
||||
var stackLayout = <stack.StackLayout>args.object.parent;
|
||||
|
||||
for (var i = 0; i < stackLayout.getChildrenCount(); i++) {
|
||||
var v = stackLayout.getChildAt(i);
|
||||
v.style.fontFamily = unsetValue;
|
||||
v.style.fontSize = unsetValue;
|
||||
v.style.fontStyle = unsetValue;
|
||||
v.style.fontWeight = unsetValue;
|
||||
|
||||
v.style.color = unsetValue;
|
||||
v.style.textAlignment = unsetValue;
|
||||
}
|
||||
}
|
||||
47
apps/automated/app/pages/page10.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { Page } from '@nativescript/core/ui/page';
|
||||
import { ImageSource } from '@nativescript/core/image-source';
|
||||
import { GridLayout, ItemSpec } from '@nativescript/core/ui/layouts/grid-layout';
|
||||
import { StackLayout } from '@nativescript/core/ui/layouts/stack-layout';
|
||||
import { Label } from '@nativescript/core/ui/label';
|
||||
import { Image } from '@nativescript/core/ui/image';
|
||||
|
||||
export function createPage() {
|
||||
var stack = new StackLayout();
|
||||
var grid = new GridLayout();
|
||||
stack.addChild(grid);
|
||||
|
||||
grid.addColumn(new ItemSpec(80, 'pixel'));
|
||||
grid.addColumn(new ItemSpec(1, 'star'));
|
||||
grid.addRow(new ItemSpec(1, 'auto'));
|
||||
grid.addRow(new ItemSpec(1, 'auto'));
|
||||
|
||||
var defaultImageSource = ImageSource.fromFileSync(__dirname + '/test.png');
|
||||
|
||||
var img = new Image();
|
||||
img.src = defaultImageSource;
|
||||
|
||||
img.width = 80;
|
||||
img.height = 80;
|
||||
img.verticalAlignment = 'bottom';
|
||||
GridLayout.setRowSpan(img, 2);
|
||||
grid.addChild(img);
|
||||
|
||||
var titleLabel = new Label();
|
||||
titleLabel.textWrap = true;
|
||||
titleLabel.text = 'some text goes here';
|
||||
GridLayout.setColumn(titleLabel, 1);
|
||||
grid.addChild(titleLabel);
|
||||
|
||||
var commentsLabel = new Label();
|
||||
commentsLabel.text = 'comments';
|
||||
commentsLabel.verticalAlignment = 'bottom';
|
||||
GridLayout.setRow(commentsLabel, 1);
|
||||
GridLayout.setColumn(commentsLabel, 1);
|
||||
grid.addChild(commentsLabel);
|
||||
|
||||
var page = new Page();
|
||||
page.content = stack;
|
||||
page.css = 'GridLayout { background-color: yellow } image { background-color: green } label { background-color: red } stackpnael { background-color: pink }';
|
||||
|
||||
return page;
|
||||
}
|
||||
74
apps/automated/app/pages/page11.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import * as gridModule from '@nativescript/core/ui/layouts/grid-layout';
|
||||
import * as sp from '@nativescript/core/ui/layouts/stack-layout';
|
||||
import * as button from '@nativescript/core/ui/button';
|
||||
import { Page } from '@nativescript/core/ui/page';
|
||||
|
||||
export function createPage() {
|
||||
var StackLayout = new sp.StackLayout();
|
||||
var grid = new gridModule.GridLayout();
|
||||
grid.horizontalAlignment = 'left';
|
||||
|
||||
StackLayout.addChild(grid);
|
||||
|
||||
var btn1 = new button.Button();
|
||||
btn1.text = 'btn1';
|
||||
var btn2 = new button.Button();
|
||||
btn2.text = 'btn2';
|
||||
var btn3 = new button.Button();
|
||||
btn3.text = 'btn3';
|
||||
var btn4 = new button.Button();
|
||||
btn4.text = 'btn4';
|
||||
|
||||
grid.addChild(btn2);
|
||||
grid.addChild(btn3);
|
||||
grid.addChild(btn4);
|
||||
|
||||
var sp1 = new sp.StackLayout();
|
||||
sp1.orientation = 'horizontal';
|
||||
sp1.height = 200;
|
||||
|
||||
var b1 = new button.Button();
|
||||
b1.text = 'nested Btn1';
|
||||
sp1.addChild(b1);
|
||||
|
||||
var b2 = new button.Button();
|
||||
b2.text = 'nested Btn2';
|
||||
sp1.addChild(b2);
|
||||
|
||||
grid.addChild(sp1);
|
||||
|
||||
gridModule.GridLayout.setColumn(btn4, 1);
|
||||
gridModule.GridLayout.setColumn(btn3, 1);
|
||||
gridModule.GridLayout.setRow(btn2, 1);
|
||||
gridModule.GridLayout.setRow(btn4, 1);
|
||||
|
||||
grid.addRow(new gridModule.ItemSpec());
|
||||
grid.addRow(new gridModule.ItemSpec());
|
||||
grid.addColumn(new gridModule.ItemSpec());
|
||||
grid.addColumn(new gridModule.ItemSpec());
|
||||
|
||||
var page = new Page();
|
||||
//page.content = GridLayout;
|
||||
page.content = StackLayout;
|
||||
var x = 1;
|
||||
btn1.on(button.Button.tapEvent, function () {
|
||||
x++;
|
||||
var gravity;
|
||||
//btn1.android.setLayoutParams(new android.view.ViewGroup.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT, android.view.ViewGroup.LayoutParams.FILL_PARENT));
|
||||
if (x === 1) {
|
||||
gravity = android.view.Gravity.CENTER;
|
||||
} else if (x === 2) {
|
||||
gravity = android.view.Gravity.RIGHT | android.view.Gravity.BOTTOM;
|
||||
} else {
|
||||
gravity = android.view.Gravity.LEFT | android.view.Gravity.TOP;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
for (var i = 0; i < grid.getChildrenCount(); i++) {
|
||||
grid.getChildAt(i).android.setGravity(gravity);
|
||||
}
|
||||
});
|
||||
|
||||
return page;
|
||||
}
|
||||
//export var Page = page;
|
||||
54
apps/automated/app/pages/page12.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import * as pages from '@nativescript/core/ui/page';
|
||||
import * as btns from '@nativescript/core/ui/button';
|
||||
import * as tb from '@nativescript/core/ui/text-field';
|
||||
import * as gridLayoutModule from '@nativescript/core/ui/layouts/grid-layout';
|
||||
|
||||
export function createPage() {
|
||||
var page = new pages.Page();
|
||||
var gridLayout = new gridLayoutModule.GridLayout();
|
||||
|
||||
var lengths = [new gridLayoutModule.ItemSpec(140, 'pixel'), new gridLayoutModule.ItemSpec(1, 'star'), new gridLayoutModule.ItemSpec(140, 'pixel')];
|
||||
|
||||
var rows = 2;
|
||||
var cols = 3;
|
||||
var row;
|
||||
var col;
|
||||
|
||||
for (row = 0; row < rows; row++) {
|
||||
var rowDef = new gridLayoutModule.ItemSpec(1, 'auto');
|
||||
gridLayout.addRow(rowDef);
|
||||
}
|
||||
|
||||
for (col = 0; col < cols; col++) {
|
||||
gridLayout.addColumn(lengths[col]);
|
||||
}
|
||||
|
||||
var btn = new btns.Button();
|
||||
btn.text = 'Col: 0';
|
||||
gridLayoutModule.GridLayout.setColumn(btn, 0);
|
||||
gridLayoutModule.GridLayout.setRow(btn, 0);
|
||||
gridLayout.addChild(btn);
|
||||
|
||||
var btn2 = new btns.Button();
|
||||
btn2.text = 'Col: 2';
|
||||
gridLayoutModule.GridLayout.setColumn(btn2, 2);
|
||||
gridLayoutModule.GridLayout.setRow(btn2, 0);
|
||||
gridLayout.addChild(btn2);
|
||||
|
||||
var txt = new tb.TextField();
|
||||
txt.text = 'Col: 1';
|
||||
txt.width = 140;
|
||||
gridLayoutModule.GridLayout.setColumn(txt, 1);
|
||||
gridLayoutModule.GridLayout.setRow(txt, 0);
|
||||
gridLayout.addChild(txt);
|
||||
|
||||
var txt2 = new tb.TextField();
|
||||
txt2.text = 'Col: All';
|
||||
gridLayoutModule.GridLayout.setColumnSpan(txt2, 3);
|
||||
gridLayoutModule.GridLayout.setRow(txt2, 1);
|
||||
gridLayout.addChild(txt2);
|
||||
|
||||
page.content = gridLayout;
|
||||
|
||||
return page;
|
||||
}
|
||||
35
apps/automated/app/pages/page13.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import * as pages from '@nativescript/core/ui/page';
|
||||
import * as btns from '@nativescript/core/ui/button';
|
||||
import * as layout from '@nativescript/core/ui/layouts/stack-layout';
|
||||
|
||||
export function createPage() {
|
||||
var page = new pages.Page();
|
||||
var linearLayout = new layout.StackLayout();
|
||||
|
||||
var btn = addButton(linearLayout, 'left');
|
||||
btn.marginLeft = 100;
|
||||
btn = addButton(linearLayout, 'center');
|
||||
btn.marginTop = 100;
|
||||
btn = addButton(linearLayout, 'right');
|
||||
btn.marginRight = 100;
|
||||
|
||||
btn = addButton(linearLayout, 'stretch');
|
||||
btn.marginLeft = 100;
|
||||
btn.marginRight = 100;
|
||||
btn.marginTop = 100;
|
||||
btn.marginBottom = 100;
|
||||
|
||||
page.content = linearLayout;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
function addButton(layout: layout.StackLayout, text: 'left' | 'center' | 'right' | 'stretch') {
|
||||
var btn = new btns.Button();
|
||||
btn.text = text;
|
||||
btn.horizontalAlignment = text;
|
||||
layout.addChild(btn);
|
||||
layout.style.paddingLeft = 5;
|
||||
|
||||
return btn;
|
||||
}
|
||||
40
apps/automated/app/pages/page15.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import * as pageModule from '@nativescript/core/ui/page';
|
||||
import * as buttonModule from '@nativescript/core/ui/button';
|
||||
import * as stackModule from '@nativescript/core/ui/layouts/stack-layout';
|
||||
|
||||
export function createPage() {
|
||||
var page = new pageModule.Page();
|
||||
var stackLayout = new stackModule.StackLayout();
|
||||
var btn1 = new buttonModule.Button();
|
||||
btn1.horizontalAlignment = 'left';
|
||||
btn1.verticalAlignment = 'top';
|
||||
btn1.marginTop = 10;
|
||||
btn1.marginRight = 0;
|
||||
btn1.marginBottom = 10;
|
||||
btn1.marginLeft = 20;
|
||||
btn1.text = 'top, left';
|
||||
|
||||
var btn2 = new buttonModule.Button();
|
||||
btn2.horizontalAlignment = 'center';
|
||||
btn2.verticalAlignment = 'middle';
|
||||
btn2.text = 'center, center';
|
||||
|
||||
var btn3 = new buttonModule.Button();
|
||||
btn3.horizontalAlignment = 'right';
|
||||
btn3.verticalAlignment = 'bottom';
|
||||
btn3.text = 'bottom, right';
|
||||
|
||||
var btn4 = new buttonModule.Button();
|
||||
btn4.horizontalAlignment = 'stretch';
|
||||
btn4.verticalAlignment = 'stretch';
|
||||
btn4.text = 'stretch, stretch';
|
||||
|
||||
stackLayout.addChild(btn1);
|
||||
stackLayout.addChild(btn2);
|
||||
stackLayout.addChild(btn3);
|
||||
stackLayout.addChild(btn4);
|
||||
|
||||
page.content = stackLayout;
|
||||
|
||||
return page;
|
||||
}
|
||||
56
apps/automated/app/pages/page16.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import * as pageModule from '@nativescript/core/ui/page';
|
||||
import * as buttonModule from '@nativescript/core/ui/button';
|
||||
import * as stackModule from '@nativescript/core/ui/layouts/stack-layout';
|
||||
import { Frame } from '@nativescript/core/ui/frame';
|
||||
|
||||
export function createPage() {
|
||||
var page = new pageModule.Page();
|
||||
|
||||
//var iconItem = new pageModule.MenuItem();
|
||||
//iconItem.text = "TEST";
|
||||
|
||||
//iconItem.icon = "~/app" + "/tests" + "/test-icon.png"; // use + to stop regex replace during build
|
||||
//iconItem.on("tap", () => {
|
||||
// console.log("Icon item tapped");
|
||||
//});
|
||||
//page.optionsMenu.addItem(iconItem);
|
||||
|
||||
//var textItem = new pageModule.MenuItem();
|
||||
//textItem.text = "SAVE";
|
||||
//textItem.on("tap", () => {
|
||||
// console.log("Save item tapped");
|
||||
//});
|
||||
//page.optionsMenu.addItem(textItem);
|
||||
|
||||
var stackLayout = new stackModule.StackLayout();
|
||||
//var count = 0;
|
||||
var btn1 = new buttonModule.Button();
|
||||
btn1.text = 'add item';
|
||||
//btn1.on("tap", () => {
|
||||
// console.log("adding menu item");
|
||||
|
||||
// var newItem = new pageModule.MenuItem();
|
||||
// var text = "item " + count;
|
||||
// newItem.text = text
|
||||
// newItem.on("tap", () => {
|
||||
// console.log("ITEM [" + text + "] tapped");
|
||||
// });
|
||||
// page.optionsMenu.addItem(newItem);
|
||||
// count++;
|
||||
//});
|
||||
|
||||
stackLayout.addChild(btn1);
|
||||
|
||||
var btn2 = new buttonModule.Button();
|
||||
btn2.text = 'navigate';
|
||||
btn2.on('tap', () => {
|
||||
var nextPage = 'app/tests/pages/page16';
|
||||
Frame.topmost().navigate(nextPage);
|
||||
});
|
||||
|
||||
stackLayout.addChild(btn2);
|
||||
|
||||
page.content = stackLayout;
|
||||
|
||||
return page;
|
||||
}
|
||||
36
apps/automated/app/pages/page17.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import * as observable from '@nativescript/core/data/observable';
|
||||
import * as action from '@nativescript/core/ui/action-bar';
|
||||
|
||||
import * as pages from '@nativescript/core/ui/page';
|
||||
|
||||
var currentPage: pages.Page;
|
||||
// Event handler for Page "loaded" event attached in main-page.xml
|
||||
export function pageLoaded(args: observable.EventData) {
|
||||
// Get the event sender
|
||||
var page = <pages.Page>args.object;
|
||||
currentPage = page;
|
||||
var textItem = new action.ActionItem();
|
||||
textItem.text = 'from loaded';
|
||||
textItem.on('tap', () => {
|
||||
console.log('item added in page.loaded tapped!!!');
|
||||
});
|
||||
page.actionBar.actionItems.addItem(textItem);
|
||||
}
|
||||
|
||||
export function optionTap(args) {
|
||||
console.log('item added form XML tapped!!!');
|
||||
}
|
||||
var i = 0;
|
||||
export function buttonTap(args: observable.EventData) {
|
||||
currentPage.actionBar.title = 'hi ' + i++;
|
||||
|
||||
if (currentPage.actionBar.android) {
|
||||
if (i % 3 === 0) {
|
||||
currentPage.actionBar.android.icon = 'res://ic_test';
|
||||
} else if (i % 3 === 1) {
|
||||
currentPage.actionBar.android.icon = '~/assets/test-icon.png';
|
||||
} else if (i % 3 === 2) {
|
||||
currentPage.actionBar.android.icon = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
22
apps/automated/app/pages/page18.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { Frame } from '@nativescript/core/ui/frame';
|
||||
import * as observable from '@nativescript/core/data/observable';
|
||||
|
||||
import { Trace } from '@nativescript/core';
|
||||
Trace.setCategories('gestures');
|
||||
Trace.enable();
|
||||
|
||||
export function itemTap(args) {
|
||||
console.log('----- Item tapped: ' + args.view.tag);
|
||||
|
||||
Frame.topmost().navigate({
|
||||
moduleName: './pages/page5',
|
||||
});
|
||||
}
|
||||
|
||||
export function itemLoaded(args: observable.EventData) {
|
||||
console.log('----- Item loaded: ' + (<any>args.object).tag);
|
||||
}
|
||||
|
||||
export function itemUnloaded(args: observable.EventData) {
|
||||
console.log('----- Item unloaded: ' + (<any>args.object).tag);
|
||||
}
|
||||
8
apps/automated/app/pages/page19.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import * as observable from '@nativescript/core/data/observable';
|
||||
import { Trace } from '@nativescript/core';
|
||||
Trace.addCategories(Trace.categories.Layout);
|
||||
Trace.enable();
|
||||
|
||||
export function onLoaded(args: observable.EventData) {
|
||||
(<any>args.object).bindingContext = [0, 1];
|
||||
}
|
||||