-[NativeScript](http://www.nativescript.org) empowers you to access native APIs from JavaScript directly. Currently iOS and Android runtimes are provided for rich mobile development across a variety of diverse use cases.
+[NativeScript](http://www.nativescript.org) empowers you to access native APIs from JavaScript directly. Currently iOS, Android, and visionOS runtimes are provided for rich mobile development across a variety of diverse use cases.
+
+
+[](https://app.fossa.com/projects/git%2Bgithub.com%2FNativeScript%2FNativeScript?ref=badge_large)
+
+## Quick Start
+
+To get started with NativeScript, follow these steps:
+
+1. **Install the NativeScript CLI globally:**
+ ```bash
+ npm install -g nativescript
+ ```
+
+2. **Create a new project:**
+ ```bash
+ ns create my-app
+ ```
+
+3. **Navigate into your project directory:**
+ ```bash
+ cd my-app
+ ```
+
+4. **Run your app on an emulator or device:**
+ ```bash
+ ns run android
+ ```
+ or
+ ```bash
+ ns run ios
+ ```
## Contribute
-1. [Setup your local development environment](https://docs.nativescript.org/environment-setup.html)
+1. [Setup your local development environment](https://docs.nativescript.org/setup/)
2. Clone to contribute:
@@ -36,32 +68,34 @@ We love you and your pull requests 🤗. Please follow our [contributing guide](
## @nativescript/*
-* [@nativescript/core](https://github.com/NativeScript/NativeScript/tree/main/packages/core)
- * Core iOS/Android for NativeScript.
-* [@nativescript/types](https://www.npmjs.com/package/@nativescript/types)
- * Types for both iOS/Android below wrapped up as a convenience. *Most commonly used.*
-* [@nativescript/types-ios](https://github.com/NativeScript/NativeScript/tree/main/packages/types-ios)
- * Types for iOS.
-* [@nativescript/types-android](https://github.com/NativeScript/NativeScript/tree/main/packages/types-android)
- * Types for Android.
-* [@nativescript/types-minimal](https://github.com/NativeScript/NativeScript/tree/main/packages/types-minimal)
- * A very minimal set of types for only the latest Android and iOS sdks. Most commonly used to optimize Web-based IDE's which auto load all type declarations from node_modules.
-* [@nativescript/ui-mobile-base](https://github.com/NativeScript/NativeScript/tree/main/packages/ui-mobile-base)
- * UI mobile base native classes used by core.
-* [@nativescript/webpack](https://github.com/NativeScript/NativeScript/tree/main/packages/webpack5)
- * Webpack build utilities and configs used by NativeScript apps.
+- [@nativescript/core](https://github.com/NativeScript/NativeScript/tree/main/packages/core)
+ Singular primitives offering an easy-to-use API surface for diverse iOS/visionOS/Android APIs implemented with NativeScript.
+- [@nativescript/types](https://github.com/NativeScript/NativeScript/tree/main/packages/types)
+ Types for both iOS/Android below wrapped up as a convenience. *Most commonly used.*
+- [@nativescript/types-ios](https://github.com/NativeScript/NativeScript/tree/main/packages/types-ios)
+ Types for iOS.
+- [@nativescript/types-android](https://github.com/NativeScript/NativeScript/tree/main/packages/types-android)
+ Types for Android.
+- [@nativescript/types-minimal](https://github.com/NativeScript/NativeScript/tree/main/packages/types-minimal)
+ A very minimal set of types for only the latest Android and iOS sdks. Most commonly used to optimize Web-based IDE's which auto load all type declarations from node_modules.
+- [@nativescript/ui-mobile-base](https://github.com/NativeScript/NativeScript/tree/main/packages/ui-mobile-base)
+ UI mobile base native classes used by core.
+- [@nativescript/webpack](https://github.com/NativeScript/NativeScript/tree/main/packages/webpack5)
+ Webpack build utilities and configs used by NativeScript apps.
## Quick Links
- [NativeScript Home](https://nativescript.org)
-- [NativeScript Tutorials](https://docs.nativescript.org/tutorial/)
+- [NativeScript Tutorials](https://docs.nativescript.org/tutorials/)
- [NativeScript documentation](https://docs.nativescript.org/)
- JavaScript starter: https://nativescript.new/javascript
- TypeScript starter: https://nativescript.new/typescript
- Angular starter: https://nativescript.new/angular
-- Vue starter: https://nativescript.new/vue
-- Svelte starter: https://nativescript.new/svelte
- React starter: https://nativescript.new/react
+- Solid starter: https://nativescript.new/solid
+- Svelte starter: https://nativescript.new/svelte
+- Vue starter: https://nativescript.new/vue
+- Vue 3 starter: https://nativescript.new/vue3
- [NativeScript on Twitter](http://twitter.com/NativeScript)
- [NativeScript on Discord](https://nativescript.org/discord)
- [NativeScript on Stack Overflow](http://stackoverflow.com/questions/tagged/nativescript)
@@ -70,23 +104,29 @@ We love you and your pull requests 🤗. Please follow our [contributing guide](
Outside the source centralized in this repo, NativeScript consists of a few other source repos. Here are the major ones:
-- **[iOS Runtime](https://github.com/NativeScript/ns-v8ios-runtime)**
- - This repo contains the NativeScript iOS Runtime — the code that hosts NativeScript iOS apps, and allows JavaScript code to be executed on iOS devices. The iOS runtime is written in a mix of C++, Objective-C, and more.
-- **[Android Runtime](https://github.com/NativeScript/android-runtime)**
- - This repo contains the NativeScript Android Runtime — the code that hosts NativeScript Android apps, and allows JavaScript code to be executed on Android devices. The Android runtime is written in a mix of C++ and Java.
-- **[CLI](//github.com/NativeScript/nativescript-cli)**
- - This repo contains the NativeScript command-line interface, which lets you create, build, and run apps using NativeScript. The CLI is written in TypeScript.
-- **[Docs](//github.com/NativeScript/docs-new)**
- - This repo contains NativeScript documentation, which is available at . The docs are written in Markdown.
-- **[Plugins](https://github.com/NativeScript/plugins)**
- - This repo contains a [plugin workspace](https://docs.nativescript.org/plugins/plugin-workspace-guide.html) with several often useful plugins.
-- **[Firebase](https://github.com/NativeScript/firebase)**
- - Modular Firebase 🔥 implementation for iOS & Android.
-- **[ML Kit](https://github.com/NativeScript/mlkit)**
- - Google's [ML Kit SDKs for iOS and Android](https://developers.google.com/ml-kit).
-- **[Payments](https://github.com/NativeScript/payments)**
- - In-App Purchase, Subscriptions, Google Pay and Apple Pay.
-- **[Artwork](https://github.com/NativeScript/artwork)**
- - Want to use our logo or colors? This repo contains ready to use media material.
+- [iOS and visionOS Runtime](https://github.com/NativeScript/ios)
+ Empowers JavaScript code to be executed on iOS and visionOS devices written in a mix of C++, Objective-C, and Swift.
+- [Android Runtime](https://github.com/NativeScript/android)
+ Empowers JavaScript code to be executed on Android devices written in a mix of C++, Java and Kotlin.
+- [CLI](https://github.com/NativeScript/nativescript-cli)
+ Command-line interface empowering you to create, build, and run apps using NativeScript.
+- [Docs](https://github.com/NativeScript/docs)
+ Documentation available at written in Markdown.
+- [Plugins](https://github.com/NativeScript/plugins)
+ Various TSC managed plugins. Also a good reference is the [plugin marketplace](https://market.nativescript.org/) with several additional plugins.
+- [Firebase](https://github.com/NativeScript/firebase)
+ Modular Firebase 🔥 implementation for supported platforms.
+- [ML Kit](https://github.com/NativeScript/mlkit)
+ Google's [ML Kit SDKs for supported platforms](https://developers.google.com/ml-kit).
+- [Payments](https://github.com/NativeScript/payments)
+ In-App Purchase, Subscriptions, Google Pay and Apple Pay.
+- [Artwork](https://github.com/NativeScript/artwork)
+ Want to use our logo or colors? Feel free to use any of our ready-to-use media material.
+
+## Copyright notice
+
+Copyright [OpenJS Foundation](https://openjsf.org) and `NativeScript` contributors. All rights reserved. The [OpenJS Foundation](https://openjsf.org) has registered trademarks and uses trademarks. For a list of trademarks of the [OpenJS Foundation](https://openjsf.org), please see our [Trademark Policy](https://trademark-policy.openjsf.org/) and [Trademark List](https://trademark-list.openjsf.org/). Trademarks and logos not indicated on the [list of OpenJS Foundation trademarks](https://trademark-list.openjsf.org) are trademarks™ or registered® trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.
+
+[The OpenJS Foundation](https://openjsf.org/) | [Terms of Use](https://terms-of-use.openjsf.org/) | [Privacy Policy](https://privacy-policy.openjsf.org/) | [OpenJS Foundation Bylaws](https://bylaws.openjsf.org/) | [Trademark Policy](https://trademark-policy.openjsf.org/) | [Trademark List](https://trademark-list.openjsf.org/) | [Cookie Policy](https://www.linuxfoundation.org/cookies/)
Made with ❤️
diff --git a/apps/automated/.gitignore b/apps/automated/.gitignore
index 512c68e15a..e9dc6c6f24 100644
--- a/apps/automated/.gitignore
+++ b/apps/automated/.gitignore
@@ -1 +1,2 @@
!webpack.config.js
+hooks
\ No newline at end of file
diff --git a/apps/automated/.npmrc b/apps/automated/.npmrc
deleted file mode 100644
index 3b59692060..0000000000
--- a/apps/automated/.npmrc
+++ /dev/null
@@ -1,6 +0,0 @@
-legacy-peer-deps=true
-
-# npm 9+ this defaults to `true` meaning `file:` dependencies are packed and then installed
-# but since we want to link the source files in this case, we disable this behavior and
-# opt to link the dependency as-is instead. (eg. @nativescript/core)
-install-links=false
diff --git a/apps/automated/nativescript.config.ts b/apps/automated/nativescript.config.ts
index 043f59c668..7dfd261e33 100644
--- a/apps/automated/nativescript.config.ts
+++ b/apps/automated/nativescript.config.ts
@@ -9,5 +9,8 @@ export default {
},
cli: {
packageManager: 'npm',
+ additionalPathsToClean: ['.ns-vite-build'],
},
+ // bundler: 'vite',
+ // bundlerConfigPath: 'vite.config.ts',
} as NativeScriptConfig;
diff --git a/apps/automated/package.json b/apps/automated/package.json
index 9ed1314a99..56964cd456 100644
--- a/apps/automated/package.json
+++ b/apps/automated/package.json
@@ -11,11 +11,13 @@
"nativescript-theme-core": "file:../../node_modules/nativescript-theme-core"
},
"devDependencies": {
- "@nativescript/android": "~8.5.0",
- "@nativescript/ios": "~8.5.0",
- "@nativescript/webpack": "file:../../dist/packages/nativescript-webpack.tgz",
+ "@nativescript/android": "~9.0.0",
+ "@nativescript/ios": "~9.0.0",
+ "@nativescript/visionos": "~9.0.0",
+ "@nativescript/vite": "file:../../dist/packages/vite",
+ "@nativescript/webpack": "file:../../dist/packages/webpack5",
"circular-dependency-plugin": "^5.2.2",
- "typescript": "~4.9.5"
+ "typescript": "~5.8.0"
},
"gitHead": "c06800e52ee1a184ea2dffd12a6702aaa43be4e3",
"readme": "NativeScript Application"
diff --git a/apps/automated/project.json b/apps/automated/project.json
index d61bc888b7..6aae5b2a9a 100644
--- a/apps/automated/project.json
+++ b/apps/automated/project.json
@@ -11,43 +11,67 @@
"targets": {
"build": {
"executor": "@nativescript/nx:build",
+ "inputs": ["default", "^production"],
"options": {
"noHmr": true,
"production": true,
"uglify": true,
"release": true,
"forDevice": true
- }
+ },
+ "configurations": {},
+ "dependsOn": ["^build"]
},
- "ios": {
- "executor": "@nativescript/nx:build",
+ "debug": {
+ "executor": "@nativescript/nx:debug",
"inputs": ["default", "^production"],
- "outputs": [],
"options": {
"noHmr": true,
- "platform": "ios"
- }
+ "debug": false,
+ "uglify": false,
+ "release": false,
+ "forDevice": false,
+ "prepare": false
+ },
+ "dependsOn": ["^build"]
},
- "android": {
- "executor": "@nativescript/nx:build",
+ "prepare": {
+ "executor": "@nativescript/nx:prepare",
"inputs": ["default", "^production"],
- "outputs": [],
"options": {
"noHmr": true,
- "platform": "android"
- }
+ "production": true,
+ "uglify": true,
+ "release": true,
+ "forDevice": true,
+ "prepare": true
+ },
+ "configurations": {},
+ "dependsOn": ["^build"]
+ },
+ "test": {
+ "executor": "nx:run-commands",
+ "defaultConfiguration": "ios",
+ "configurations": {
+ "ios": {
+ "commands": ["node tools/scripts/run-automated.js ios"]
+ },
+ "android": {
+ "commands": ["node tools/scripts/run-automated.js android"]
+ }
+ },
+ "dependsOn": ["^build"]
},
"clean": {
- "executor": "@nativescript/nx:build",
- "options": {
- "clean": true
- }
+ "executor": "@nativescript/nx:clean",
+ "options": {}
},
"lint": {
- "executor": "@nrwl/linter:eslint",
+ "executor": "@nx/eslint:lint",
"options": {
"lintFilePatterns": ["apps/automated/**/*.ts", "apps/automated/src/**/*.html"]
}
}
- }
+ },
+ "implicitDependencies": ["webpack5", "vite"]
}
diff --git a/apps/automated/src/app-root.ts b/apps/automated/src/app-root.ts
new file mode 100644
index 0000000000..2c052a575f
--- /dev/null
+++ b/apps/automated/src/app-root.ts
@@ -0,0 +1,31 @@
+import { Application, Frame, Page } from '@nativescript/core';
+
+export function onLoaded(args) {
+ try {
+ console.log('[automated] app-root onLoaded');
+ const rootPage = args.object as Page;
+ // Create a Frame and navigate to main-page to ensure code-behind is bound
+ const frame = new Frame();
+ try {
+ frame.navigate('main-page');
+ } catch (e) {
+ try {
+ console.error('[automated] app-root onLoaded: navigate to main-page failed', e);
+ } catch {}
+ }
+ // Replace the temporary Page root with the Frame containing the page
+ try {
+ if ((Application as any).resetRootView) {
+ (Application as any).resetRootView({ create: () => frame });
+ }
+ } catch (e) {
+ try {
+ console.error('[automated] app-root onLoaded: resetRootView failed', e);
+ } catch {}
+ }
+ } catch (e) {
+ try {
+ console.error('[automated] app-root onLoaded failed', e);
+ } catch {}
+ }
+}
diff --git a/apps/automated/src/app-root.xml b/apps/automated/src/app-root.xml
index 54e70d9760..3d2c920bc8 100644
--- a/apps/automated/src/app-root.xml
+++ b/apps/automated/src/app-root.xml
@@ -1,2 +1,3 @@
-
-
+
+
+
diff --git a/apps/automated/src/application/application-tests-common.ts b/apps/automated/src/application/application-tests-common.ts
index 440ecb35e0..b1802a2d5d 100644
--- a/apps/automated/src/application/application-tests-common.ts
+++ b/apps/automated/src/application/application-tests-common.ts
@@ -11,12 +11,15 @@ if (isAndroid) {
export function testInitialized() {
if (Device.os === platformNames.android) {
TKUnit.assert(Application.android, 'Application module not properly intialized');
- } else if (Device.os === platformNames.ios) {
+ } else if (__APPLE__) {
TKUnit.assert(Application.ios, 'Application module not properly intialized');
}
}
export function testDisplayedEvent() {
+ if (__VISIONOS__) {
+ return;
+ }
// global.isDisplayedEventFired flag is set in app.ts application.displayedEvent handler
TKUnit.assert(global.isDisplayedEventFired, 'application.displayedEvent not fired');
}
diff --git a/apps/automated/src/application/application-tests.android.ts b/apps/automated/src/application/application-tests.android.ts
index d927fb1cc4..3371a7cd0b 100644
--- a/apps/automated/src/application/application-tests.android.ts
+++ b/apps/automated/src/application/application-tests.android.ts
@@ -1,5 +1,5 @@
/* tslint:disable:no-unused-variable */
-import { Application } from '@nativescript/core';
+import { Application, Utils } from '@nativescript/core';
import * as TKUnit from '../tk-unit';
export * from './application-tests-common';
@@ -43,15 +43,16 @@ export function testAndroidApplicationInitialized() {
TKUnit.assert(
// @ts-expect-error
Application.android.foregroundActivity.isNativeScriptActivity,
- 'Android foregroundActivity.isNativeScriptActivity is false.'
+ '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.');
+ TKUnit.assert(Application.android.orientation(), 'Android orientation not initialized.');
+ TKUnit.assert(Utils.android.getPackageName(), 'Android packageName not initialized.');
+ TKUnit.assert(Application.android.systemAppearance(), 'Android system appearance not initialized.');
+ TKUnit.assert(Application.android.layoutDirection(), 'Android layout direction not initialized.');
}
export function testSystemAppearance() {
- TKUnit.assert(Application.android.systemAppearance, 'System appearance not initialized.');
+ TKUnit.assert(Application.android.systemAppearance(), 'System appearance not initialized.');
}
diff --git a/apps/automated/src/application/application-tests.ios.ts b/apps/automated/src/application/application-tests.ios.ts
index add87fc103..b60c32f234 100644
--- a/apps/automated/src/application/application-tests.ios.ts
+++ b/apps/automated/src/application/application-tests.ios.ts
@@ -44,22 +44,23 @@ 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.');
+ 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.');
+ if (!__VISIONOS__ && Utils.SDK_VERSION <= 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.systemAppearance(), 'iOS system appearance not initialized.');
}
+ TKUnit.assert(Application.ios.layoutDirection(), 'iOS layout direction 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.');
+ if (!__VISIONOS__ && Utils.SDK_VERSION <= 11) {
+ TKUnit.assertNull(Application.ios.systemAppearance(), 'System appearance should be `null` on iOS <= 11.');
} else {
- TKUnit.assert(Application.ios.systemAppearance, 'System appearance not initialized.');
+ TKUnit.assert(Application.ios.systemAppearance(), 'System appearance not initialized.');
}
}
diff --git a/apps/automated/src/xml-parser-tests/xml-with-namespaces.xml b/apps/automated/src/assets/xml-with-namespaces.xml
similarity index 100%
rename from apps/automated/src/xml-parser-tests/xml-with-namespaces.xml
rename to apps/automated/src/assets/xml-with-namespaces.xml
diff --git a/apps/automated/src/xml-parser-tests/xml.expected b/apps/automated/src/assets/xml.expected
similarity index 96%
rename from apps/automated/src/xml-parser-tests/xml.expected
rename to apps/automated/src/assets/xml.expected
index 5cdb47fc44..45a1441970 100644
--- a/apps/automated/src/xml-parser-tests/xml.expected
+++ b/apps/automated/src/assets/xml.expected
@@ -1 +1 @@
-{"eventType":"StartElement","position":{"line":2,"column":1},"elementName":"DocumentElement","attributes":{"param":"value"}}{"eventType":"StartElement","position":{"line":3,"column":3},"elementName":"First.Element","attributes":{"some.attr":"some.value"}}{"eventType":"Text","position":{"line":3,"column":41},"data":"\n ¶ Some Text ®\n "}{"eventType":"EndElement","position":{"line":5,"column":3},"elementName":"First.Element"}{"eventType":"StartElement","position":{"line":7,"column":3},"elementName":"SecondElement","attributes":{"param2":"something"}}{"eventType":"Text","position":{"line":7,"column":37},"data":"\n Pre-Text "}{"eventType":"StartElement","position":{"line":8,"column":14},"elementName":"Inline"}{"eventType":"Text","position":{"line":8,"column":22},"data":"Inlined text"}{"eventType":"EndElement","position":{"line":8,"column":34},"elementName":"Inline"}{"eventType":"Text","position":{"line":8,"column":43},"data":" Post-text.\n "}{"eventType":"EndElement","position":{"line":9,"column":3},"elementName":"SecondElement"}{"eventType":"StartElement","position":{"line":10,"column":3},"elementName":"entities"}{"eventType":"Text","position":{"line":10,"column":13},"data":"Xml tags begin with \"<\" and end with \">\" Ampersand is & and apostrophe is '"}{"eventType":"EndElement","position":{"line":10,"column":123},"elementName":"entities"}{"eventType":"StartElement","position":{"line":11,"column":3},"elementName":"script"}{"eventType":"CDATA","position":{"line":12,"column":5},"data":"\nfunction sum(a,b)\n{\n return a+b;\n}\n"}{"eventType":"EndElement","position":{"line":18,"column":3},"elementName":"script"}{"eventType":"Comment","position":{"line":19,"column":3},"data":"\n Hello,\n I am a multi-line XML comment.\n"}{"eventType":"EndElement","position":{"line":23,"column":1},"elementName":"DocumentElement"}
+{"eventType":"StartElement","position":{"line":2,"column":1},"elementName":"DocumentElement","attributes":{"param":"value"}}{"eventType":"StartElement","position":{"line":3,"column":3},"elementName":"First.Element","attributes":{"some.attr":"some.value"}}{"eventType":"Text","position":{"line":3,"column":41},"data":"\n ¶ Some Text ®\n "}{"eventType":"EndElement","position":{"line":5,"column":3},"elementName":"First.Element"}{"eventType":"StartElement","position":{"line":7,"column":3},"elementName":"SecondElement","attributes":{"param2":"something"}}{"eventType":"Text","position":{"line":7,"column":37},"data":"\n Pre-Text "}{"eventType":"StartElement","position":{"line":8,"column":14},"elementName":"Inline"}{"eventType":"Text","position":{"line":8,"column":22},"data":"Inlined text"}{"eventType":"EndElement","position":{"line":8,"column":34},"elementName":"Inline"}{"eventType":"Text","position":{"line":8,"column":43},"data":" Post-text.\n "}{"eventType":"EndElement","position":{"line":9,"column":3},"elementName":"SecondElement"}{"eventType":"StartElement","position":{"line":10,"column":3},"elementName":"entities"}{"eventType":"Text","position":{"line":10,"column":13},"data":"Xml tags begin with \"<\" and end with \">\" Ampersand is & and apostrophe is '"}{"eventType":"EndElement","position":{"line":10,"column":123},"elementName":"entities"}{"eventType":"StartElement","position":{"line":11,"column":3},"elementName":"script"}{"eventType":"CDATA","position":{"line":12,"column":5},"data":"\nfunction sum(a,b)\n{\n return a+b;\n}\n"}{"eventType":"EndElement","position":{"line":18,"column":3},"elementName":"script"}{"eventType":"Comment","position":{"line":19,"column":3},"data":"\n Hello,\n I am a multi-line XML comment.\n"}{"eventType":"EndElement","position":{"line":23,"column":1},"elementName":"DocumentElement"}
\ No newline at end of file
diff --git a/apps/automated/src/xml-parser-tests/xml.xml b/apps/automated/src/assets/xml.xml
similarity index 96%
rename from apps/automated/src/xml-parser-tests/xml.xml
rename to apps/automated/src/assets/xml.xml
index 93a55b0186..3b9a16b9a5 100644
--- a/apps/automated/src/xml-parser-tests/xml.xml
+++ b/apps/automated/src/assets/xml.xml
@@ -20,4 +20,4 @@ function sum(a,b)
Hello,
I am a multi-line XML comment.
-->
-
+
\ No newline at end of file
diff --git a/apps/automated/src/color/color-tests-common.ts b/apps/automated/src/color/color-tests-common.ts
index 18d94bac96..13182f417f 100644
--- a/apps/automated/src/color/color-tests-common.ts
+++ b/apps/automated/src/color/color-tests-common.ts
@@ -17,6 +17,19 @@ export var test_Hex_Color = function () {
TKUnit.assertEqual(color.argb, 0xffff0000, 'Color.argb not properly parsed');
};
+export var test_Hex_rgba_Color = function () {
+ // >> color-hex-rgba
+ // Creates the red color
+ var color = new Color('#FF0000FF');
+ // << color-hex-rgba
+ 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
@@ -30,6 +43,19 @@ export var test_ShortHex_Color = function () {
TKUnit.assertEqual(color.argb, 0xffff8800, 'Color.argb not properly parsed');
};
+export var test_ShortHex_rgba_Color = function () {
+ // >> color-hex-short-rgba
+ // Creates the color #FF8800
+ var color = new Color('#F80F');
+ // << color-hex-short-rgba
+ 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
@@ -112,7 +138,10 @@ export var test_Color_isValid = function () {
var color = new Color('#FF0000');
TKUnit.assertEqual(Color.isValid(color), true, 'Failed to validate color instance');
- TKUnit.assertEqual(Color.isValid('#FF0000'), true, 'Failed to validate hex color');
+ TKUnit.assertEqual(Color.isValid('#FFF'), true, 'Failed to validate 3-digit hex color');
+ TKUnit.assertEqual(Color.isValid('#FFF0'), true, 'Failed to validate 4-digit hex color');
+ TKUnit.assertEqual(Color.isValid('#FF0000'), true, 'Failed to validate 6-digit hex color');
+ TKUnit.assertEqual(Color.isValid('#FF000000'), true, 'Failed to validate 8-digit hex color');
TKUnit.assertEqual(Color.isValid('rgb(255, 100, 100)'), true, 'Failed to validate rgb color');
TKUnit.assertEqual(Color.isValid('hsl(50, 50%, 50%)'), true, 'Failed to validate hsl color');
TKUnit.assertEqual(Color.isValid(null) || Color.isValid(undefined), false, 'Failed to invalidate nullish value');
diff --git a/apps/automated/src/color/color-tests.ios.ts b/apps/automated/src/color/color-tests.ios.ts
index 228776da32..0acf4f767d 100644
--- a/apps/automated/src/color/color-tests.ios.ts
+++ b/apps/automated/src/color/color-tests.ios.ts
@@ -6,7 +6,7 @@ import * as TKUnit from '../tk-unit';
export * from './color-tests-common';
-export function testFromIosColorWhite () {
+export function testFromIosColorWhite() {
// >> color-ios-white
// Creates the white color
const color = Color.fromIosColor(UIColor.whiteColor);
@@ -17,4 +17,4 @@ export function testFromIosColorWhite () {
TKUnit.assertEqual(color.b, 255, 'Color.b not properly parsed');
TKUnit.assertEqual(color.hex, '#FFFFFF', 'Color.hex not properly parsed');
TKUnit.assertEqual(color.argb, 0xffffffff, 'Color.argb not properly parsed');
-};
+}
diff --git a/apps/automated/src/data/observable-tests.ts b/apps/automated/src/data/observable-tests.ts
index 5bfa1cefb7..32efd1f956 100644
--- a/apps/automated/src/data/observable-tests.ts
+++ b/apps/automated/src/data/observable-tests.ts
@@ -163,7 +163,7 @@ export var test_Observable_addEventListener_MultipleEvents = function () {
obj.addEventListener(events, callback);
obj.set('testName', 1);
obj.test();
- TKUnit.assert(receivedCount === 2, 'Callbacks not raised properly.');
+ TKUnit.assert(receivedCount === 0, "Expected no event handlers to fire upon the 'propertyChange' event when listening for event name 'propertyChange,tested', as we have dropped support for listening to plural event names.");
};
export var test_Observable_addEventListener_MultipleEvents_ShouldTrim = function () {
@@ -176,13 +176,14 @@ export var test_Observable_addEventListener_MultipleEvents_ShouldTrim = function
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.');
+ TKUnit.assert(obj.hasListeners(events), "Expected a listener to be present for event name 'propertyChange , tested', as we have dropped support for splitting plural event names.");
+ TKUnit.assert(!obj.hasListeners(Observable.propertyChangeEvent), "Expected no listeners to be present for event name 'propertyChange', as we have dropped support for splitting plural event names.");
+ TKUnit.assert(!obj.hasListeners(TESTED_NAME), "Expected no listeners to be present for event name 'tested', as we have dropped support for splitting plural event names.");
obj.set('testName', 1);
obj.test();
- TKUnit.assert(receivedCount === 2, 'Callbacks not raised properly.');
+ TKUnit.assert(receivedCount === 0, "Expected no event handlers to fire upon the 'propertyChange' event when listening for event name 'propertyChange , tested', as we have dropped support for listening to plural event names (and trimming whitespace in event names).");
};
export var test_Observable_addEventListener_MultipleCallbacks = function () {
@@ -223,7 +224,7 @@ export var test_Observable_addEventListener_MultipleCallbacks_MultipleEvents = f
obj.set('testName', 1);
obj.test();
- TKUnit.assert(receivedCount === 4, 'The propertyChanged notification should be raised twice.');
+ TKUnit.assert(receivedCount === 0, "Expected no event handlers to fire upon the 'propertyChange' event when listening for event name 'propertyChange , tested' with two different callbacks, as we have dropped support for listening to plural event names (and trimming whitespace in event names).");
};
export var test_Observable_removeEventListener_SingleEvent_SingleCallback = function () {
@@ -273,7 +274,65 @@ export var test_Observable_removeEventListener_SingleEvent_MultipleCallbacks = f
TKUnit.assert(receivedCount === 3, 'Observable.removeEventListener not working properly with multiple listeners.');
};
-export var test_Observable_removeEventListener_MutlipleEvents_SingleCallback = function () {
+export var test_Observable_identity = function () {
+ const obj = new Observable();
+
+ let receivedCount = 0;
+ const callback = () => receivedCount++;
+ const eventName = Observable.propertyChangeEvent;
+
+ // The identity of an event listener is determined by the tuple of
+ // [eventType, callback, thisArg], and influences addition and removal.
+
+ // If you try to add the same callback for a given event name twice, without
+ // distinguishing by its thisArg, the second addition will no-op.
+ obj.addEventListener(eventName, callback);
+ obj.addEventListener(eventName, callback);
+ obj.set('testName', 1);
+ TKUnit.assert(receivedCount === 1, 'Expected Observable to fire exactly once upon a property change, having passed the same callback into addEventListener() twice');
+ obj.removeEventListener(eventName, callback);
+ TKUnit.assert(!obj.hasListeners(eventName), 'Expected removeEventListener(eventName, callback) to remove all matching callbacks regardless of thisArg');
+ receivedCount = 0;
+
+ // All truthy thisArgs are distinct, so we have three distinct identities here
+ // and they should all get added.
+ obj.addEventListener(eventName, callback);
+ obj.addEventListener(eventName, callback, 1);
+ obj.addEventListener(eventName, callback, 2);
+ obj.set('testName', 2);
+ TKUnit.assert(receivedCount === 3, 'Expected Observable to fire exactly three times upon a property change, having passed the same callback into addEventListener() three times, with the latter two distinguished by each having a different truthy thisArg');
+ obj.removeEventListener(eventName, callback);
+ TKUnit.assert(!obj.hasListeners(eventName), 'Expected removeEventListener(eventName, callback) to remove all matching callbacks regardless of thisArg');
+ receivedCount = 0;
+
+ // If you specify thisArg when removing an event listener, it should remove
+ // just the event listener with the corresponding thisArg.
+ obj.addEventListener(eventName, callback, 1);
+ obj.addEventListener(eventName, callback, 2);
+ obj.set('testName', 3);
+ TKUnit.assert(receivedCount === 2, 'Expected Observable to fire exactly three times upon a property change, having passed the same callback into addEventListener() three times, with the latter two distinguished by each having a different truthy thisArg');
+ obj.removeEventListener(eventName, callback, 2);
+ TKUnit.assert(obj.hasListeners(eventName), 'Expected removeEventListener(eventName, callback, thisArg) to remove just the event listener that matched the callback and thisArg');
+ obj.removeEventListener(eventName, callback, 1);
+ TKUnit.assert(!obj.hasListeners(eventName), 'Expected removeEventListener(eventName, callback, thisArg) to remove the remaining event listener that matched the callback and thisArg');
+ receivedCount = 0;
+
+ // All falsy thisArgs are treated alike, so these all have the same identity
+ // and only the first should get added.
+ obj.addEventListener(eventName, callback);
+ obj.addEventListener(eventName, callback, 0);
+ obj.addEventListener(eventName, callback, false);
+ obj.addEventListener(eventName, callback, null);
+ obj.addEventListener(eventName, callback, undefined);
+ obj.addEventListener(eventName, callback, '');
+ obj.set('testName', 4);
+ TKUnit.assert(receivedCount === 1, 'Expected Observable to fire exactly once upon a property change, having passed the same callback into addEventListener() multiple times, each time with a different falsy (and therefore indistinct) thisArg');
+ obj.removeEventListener(eventName, callback);
+ TKUnit.assert(!obj.hasListeners(eventName), 'Expected removeEventListener(eventName, callback) to remove all matching callbacks regardless of thisArg');
+ receivedCount = 0;
+};
+
+export var test_Observable_removeEventListener_MultipleEvents_SingleCallback = function () {
var obj = new TestObservable();
var receivedCount = 0;
@@ -283,19 +342,22 @@ export var test_Observable_removeEventListener_MutlipleEvents_SingleCallback = f
var events = Observable.propertyChangeEvent + ' , ' + TESTED_NAME;
obj.addEventListener(events, callback);
+ TKUnit.assert(obj.hasListeners(events), "Expected a listener to be present for event name 'propertyChange , tested', as we have dropped support for splitting plural event names.");
+ TKUnit.assert(!obj.hasListeners(Observable.propertyChangeEvent), "Expected no listeners to be present for event name 'propertyChange', as we have dropped support for splitting plural event names.");
+ TKUnit.assert(!obj.hasListeners(TESTED_NAME), "Expected no listeners to be present for event name 'tested', as we have dropped support for splitting plural event names.");
+ TKUnit.assert(receivedCount === 0, "Expected no event handlers to fire upon the 'propertyChange' event when listening for event name 'propertyChange , tested', as we have dropped support for listening to plural event names (and trimming whitespace in event names).");
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.');
+ TKUnit.assert(!obj.hasListeners(events), "Expected the listener for event name 'propertyChange , tested' to have been removed, as we have dropped support for splitting plural event names.");
obj.set('testName', 2);
obj.test();
- TKUnit.assert(receivedCount === 2, 'Expected receive count is 2');
+ TKUnit.assert(receivedCount === 0, "Expected no event handlers to fire upon the 'propertyChange' event when listening for event name 'propertyChange , tested', as we have dropped support for listening to plural event names (and trimming whitespace in event names).");
};
export var test_Observable_removeEventListener_SingleEvent_NoCallbackSpecified = function () {
diff --git a/apps/automated/src/debugger/dom-node-tests.ts b/apps/automated/src/debugger/dom-node-tests.ts
index 52b8b8ad88..80d76e21c4 100644
--- a/apps/automated/src/debugger/dom-node-tests.ts
+++ b/apps/automated/src/debugger/dom-node-tests.ts
@@ -1,15 +1,9 @@
import { assert, assertEqual } from '../tk-unit';
-import { DOMNode } from '@nativescript/core/debugger/dom-node';
+import { DOMNode } from '@nativescript/core/debugger/dom-types';
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 { unsetValue, Button, Slider, Label, TextView, StackLayout, isAndroid } from '@nativescript/core';
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;
diff --git a/apps/automated/src/file-system/file-system-tests.ts b/apps/automated/src/file-system/file-system-tests.ts
index 3a2ba03c84..b78254ae01 100644
--- a/apps/automated/src/file-system/file-system-tests.ts
+++ b/apps/automated/src/file-system/file-system-tests.ts
@@ -61,7 +61,7 @@ export var testFileFromPath = function () {
function (error) {
TKUnit.assert(false, 'Failed to read/write text');
//console.dir(error);
- }
+ },
);
// << (hide)
},
@@ -71,7 +71,7 @@ export var testFileFromPath = function () {
TKUnit.assert(false, 'Failed to read/write text');
//console.dir(error);
// << (hide)
- }
+ },
);
// << file-system-create
};
@@ -106,7 +106,7 @@ export var testFileWrite = function () {
function (error) {
TKUnit.assert(false, 'Failed to read/write text');
//console.dir(error);
- }
+ },
);
// << (hide)
},
@@ -116,7 +116,7 @@ export var testFileWrite = function () {
TKUnit.assert(false, 'Failed to read/write text');
//console.dir(error);
// << (hide)
- }
+ },
);
// << file-system-write-string
};
@@ -172,7 +172,7 @@ export var testFileRead = function () {
TKUnit.assert(false, 'Failed to read/write text');
//console.dir(error);
// << (hide)
- }
+ },
);
},
function (error) {
@@ -181,20 +181,20 @@ export var testFileRead = function () {
TKUnit.assert(false, 'Failed to read/write text');
//console.dir(error);
// << (hide)
- }
+ },
);
// << file-system-example-text
};
-export var testFileReadWriteBinary = function () {
+export function testFileReadWriteBinary() {
// >> file-system-read-binary
- var fileName = 'logo.png';
- var error;
+ const fileName = 'logo.png';
+ let error;
+ const appFolder = fs.knownFolders.currentApp().path;
+ const sourceFile = fs.File.fromPath(appFolder + '/assets/' + fileName);
+ const destinationFile = fs.knownFolders.documents().getFile(fileName);
- var sourceFile = fs.File.fromPath(__dirname + '/assets/' + fileName);
- var destinationFile = fs.knownFolders.documents().getFile(fileName);
-
- var source = sourceFile.readSync((e) => {
+ const source = sourceFile.readSync((e) => {
error = e;
});
@@ -203,11 +203,11 @@ export var testFileReadWriteBinary = function () {
});
// >> (hide)
- var destination = destinationFile.readSync((e) => {
+ const destination = destinationFile.readSync((e) => {
error = e;
});
TKUnit.assertNull(error);
- if (Device.os === platformNames.ios) {
+ if (__APPLE__) {
TKUnit.assertTrue(source.isEqualToData(destination));
} else {
TKUnit.assertEqual(new java.io.File(sourceFile.path).length(), new java.io.File(destinationFile.path).length());
@@ -216,14 +216,14 @@ export var testFileReadWriteBinary = function () {
destinationFile.removeSync();
// << (hide)
// << file-system-read-binary
-};
+}
-export var testFileReadWriteBinaryAsync = function () {
+export function testFileReadWriteBinaryAsync() {
// >> file-system-read-binary-async
- var fileName = 'logo.png';
-
- var sourceFile = fs.File.fromPath(__dirname + '/assets/' + fileName);
- var destinationFile = fs.knownFolders.documents().getFile(fileName);
+ const fileName = 'logo.png';
+ const appFolder = fs.knownFolders.currentApp().path;
+ const sourceFile = fs.File.fromPath(appFolder + '/assets/' + fileName);
+ const destinationFile = fs.knownFolders.documents().getFile(fileName);
// Read the file
sourceFile.read().then(
@@ -235,7 +235,7 @@ export var testFileReadWriteBinaryAsync = function () {
// Succeded in writing the file
destinationFile.read().then(
function (destination) {
- if (Device.os === platformNames.ios) {
+ if (__APPLE__) {
TKUnit.assertTrue(source.isEqualToData(destination));
} else {
TKUnit.assertEqual(new java.io.File(sourceFile.path).length(), new java.io.File(destinationFile.path).length());
@@ -245,13 +245,13 @@ export var testFileReadWriteBinaryAsync = function () {
},
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)
},
@@ -260,10 +260,10 @@ export var testFileReadWriteBinaryAsync = function () {
// >> (hide)
TKUnit.assert(false, 'Failed to read binary async');
// << (hide)
- }
+ },
);
// << file-system-read-binary-async
-};
+}
export var testGetKnownFolders = function () {
// >> file-system-known-folders
@@ -306,14 +306,16 @@ function _testIOSSpecificKnownFolder(knownFolderName: string) {
}
export var testIOSSpecificKnownFolders = function () {
- _testIOSSpecificKnownFolder('library');
- _testIOSSpecificKnownFolder('developer');
- _testIOSSpecificKnownFolder('desktop');
- _testIOSSpecificKnownFolder('downloads');
- _testIOSSpecificKnownFolder('movies');
- _testIOSSpecificKnownFolder('music');
- _testIOSSpecificKnownFolder('pictures');
- _testIOSSpecificKnownFolder('sharedPublic');
+ if (__IOS__) {
+ _testIOSSpecificKnownFolder('library');
+ _testIOSSpecificKnownFolder('developer');
+ _testIOSSpecificKnownFolder('desktop');
+ _testIOSSpecificKnownFolder('downloads');
+ _testIOSSpecificKnownFolder('movies');
+ _testIOSSpecificKnownFolder('music');
+ _testIOSSpecificKnownFolder('pictures');
+ _testIOSSpecificKnownFolder('sharedPublic');
+ }
};
export var testGetEntities = function () {
@@ -356,7 +358,7 @@ export var testGetEntities = function () {
function (error) {
// Failed to obtain folder's contents.
// globalConsole.error(error.message);
- }
+ },
);
// << file-system-folders-content
};
@@ -423,11 +425,11 @@ export var testFileNameExtension = function () {
var file = documents.getFile('Test.txt');
// Getting the file name "Test.txt".
var fileName = file.name;
- // Getting the file extension ".txt".
+ // Getting the file extension "txt".
var fileExtension = file.extension;
// >> (hide)
TKUnit.assert(fileName === 'Test.txt', 'Wrong file name.');
- TKUnit.assert(fileExtension === '.txt', 'Wrong extension.');
+ TKUnit.assert(fileExtension === 'txt', 'Wrong extension.');
file.remove();
// << (hide)
// << file-system-extension
@@ -491,7 +493,7 @@ export var testFileRename = function () {
// >> (hide)
TKUnit.assert(false, 'Failed to rename file');
// << (hide)
- }
+ },
);
// << file-system-renaming
};
@@ -515,7 +517,7 @@ export var testFolderRename = function () {
// >> (hide)
TKUnit.assert(false, 'Folder.rename API not working.');
// << (hide)
- }
+ },
);
// << file-system-renaming-folder
};
@@ -536,7 +538,7 @@ export var testFileRemove = function () {
// >> (hide)
TKUnit.assert(false, 'File.remove API not working.');
// << (hide)
- }
+ },
);
// << file-system-remove-file
};
@@ -558,7 +560,7 @@ export var testFolderRemove = function () {
// >> (hide)
TKUnit.assert(false, 'File.remove API not working.');
// << (hide)
- }
+ },
);
// << file-system-remove-folder
};
@@ -585,7 +587,7 @@ export var testFolderClear = function () {
// >> (hide)
TKUnit.assert(false, error.message);
// << (hide)
- }
+ },
);
// >> (hide)
folder.getEntities().then(function (entities) {
@@ -607,7 +609,7 @@ export var testKnownFolderRename = function () {
},
function (error) {
TKUnit.assert(true);
- }
+ },
);
}
};
@@ -623,7 +625,7 @@ export function testKnownFolderRemove(done) {
},
function (error) {
done(null);
- }
+ },
);
}
@@ -631,7 +633,7 @@ 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.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.');
@@ -744,7 +746,7 @@ export function testAndroidCreate() {
export function test_FileAppend(done) {
const content = 'Hello World';
- const hello_world = global.isIOS ? NSString.stringWithString(content).dataUsingEncoding(NSUTF8StringEncoding) : new java.lang.String(content).getBytes('UTF-8');
+ const hello_world = __APPLE__ ? NSString.stringWithString(content).dataUsingEncoding(NSUTF8StringEncoding) : new java.lang.String(content).getBytes('UTF-8');
const file = fs.File.fromPath(fs.path.join(fs.knownFolders.temp().path, `${Date.now()}-app.txt`));
file
.appendText('Hello')
diff --git a/apps/automated/src/globals/globals-tests.ts b/apps/automated/src/globals/globals-tests.ts
index 65c10e14d4..9bd0244651 100644
--- a/apps/automated/src/globals/globals-tests.ts
+++ b/apps/automated/src/globals/globals-tests.ts
@@ -23,8 +23,8 @@ 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_registerBundlerModules() {
+ TKUnit.assert(typeof global.registerBundlerModules === 'function', 'global.registerBundlerModules not a function');
}
export function test_global_loadModule() {
diff --git a/apps/automated/src/http/http-tests.ts b/apps/automated/src/http/http-tests.ts
index 5901bdb880..5272f8759a 100644
--- a/apps/automated/src/http/http-tests.ts
+++ b/apps/automated/src/http/http-tests.ts
@@ -2,7 +2,7 @@ import { ImageSource } from '@nativescript/core';
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';
+import { requestInternal, addHeader, BaseHttpContent } from '@nativescript/core/http/http-request-internal';
export var test_getString_isDefined = function () {
TKUnit.assert(typeof http.getString !== 'undefined', 'Method http.getString() should be defined!');
@@ -17,7 +17,7 @@ export var test_getString = function (done: (err: Error, res?: string) => void)
function (e) {
//// Argument (e) is Error!
done(e);
- }
+ },
);
};
@@ -67,7 +67,7 @@ export var test_getJSON = function (done) {
//// Argument (e) is Error!
//console.log(e);
done(e);
- }
+ },
);
};
@@ -115,7 +115,7 @@ export var test_getJSONP = function (done) {
},
function (e) {
done(e);
- }
+ },
);
};
@@ -156,7 +156,7 @@ export var test_gzip_request_explicit = function (done) {
},
function (e) {
done(e);
- }
+ },
);
};
@@ -180,7 +180,7 @@ export var test_gzip_request_implicit = function (done) {
},
function (e) {
done(e);
- }
+ },
);
};
@@ -205,7 +205,7 @@ export var test_getImage = function (done) {
(err) => {
// Argument (e) is Error!
done(err);
- }
+ },
);
};
@@ -258,7 +258,7 @@ export var test_getFile = function (done) {
function (e) {
//// Argument (e) is Error!
done(e);
- }
+ },
);
};
@@ -280,7 +280,7 @@ export var test_getContentAsFile = function (done) {
function (e) {
//// Argument (e) is Error!
done(e);
- }
+ },
);
};
@@ -329,6 +329,89 @@ export var test_request_requestShouldTimeout = function (done) {
});
};
+export var test_requestInternal_responseStatusCodeShouldBeDefined = function (done) {
+ requestInternal({ url: 'https://http-echo.nativescript.org/get', method: 'GET' }).then(
+ function (response) {
+ //// Argument (response) is HttpResponse!
+ var statusCode = response.statusCode;
+ 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_requestInternal_responseContentShouldExposeNativeContentFunctions = function (done) {
+ requestInternal({ url: 'https://http-echo.nativescript.org/get', method: 'GET' }).then(
+ function (response) {
+ try {
+ TKUnit.assert(typeof response.content.toNativeImage === 'function' && typeof response.content.toNativeString === 'function', `response.content should expose native content functions!`);
+ done(null);
+ } catch (err) {
+ done(err);
+ }
+ },
+ function (e) {
+ //// Argument (e) is Error!
+ done(e);
+ },
+ );
+};
+
+export var test_requestInternal_responseContentShouldExposeHandlerFunctions = function (done) {
+ const responseHandler = {
+ toDummy1: () => 'dummy1',
+ toDummy2: () => 'dummy2',
+ };
+
+ requestInternal({ url: 'https://http-echo.nativescript.org/get', method: 'GET' }, responseHandler).then(
+ function (response) {
+ try {
+ TKUnit.assert(typeof response.content.toDummy1 === 'function' && typeof response.content.toDummy2 === 'function', `response.content should expose content handler functions!`);
+ done(null);
+ } catch (err) {
+ done(err);
+ }
+ },
+ function (e) {
+ //// Argument (e) is Error!
+ done(e);
+ },
+ );
+};
+
+export var test_requestInternal_responseHandlerShouldBeAvailable = function (done) {
+ const suffix = '-nsformatted';
+ const responseHandler = {
+ toFormattedString: function (this: BaseHttpContent) {
+ return this.toNativeString() + suffix;
+ },
+ };
+
+ requestInternal({ url: 'https://http-echo.nativescript.org/get', method: 'GET' }, responseHandler).then(
+ function (response) {
+ const value = response.content.toFormattedString();
+ try {
+ TKUnit.assert(typeof value === 'string' && value.endsWith(suffix), `response.content.toFormattedString should return the response string appended with ${suffix} at the end!`);
+ done(null);
+ } catch (err) {
+ done(err);
+ }
+ },
+ function (e) {
+ //// Argument (e) is Error!
+ done(e);
+ },
+ );
+};
+
export var test_request_responseStatusCodeShouldBeDefined = function (done) {
var result: http.HttpResponse;
@@ -347,7 +430,7 @@ export var test_request_responseStatusCodeShouldBeDefined = function (done) {
function (e) {
//// Argument (e) is Error!
done(e);
- }
+ },
);
};
@@ -363,7 +446,7 @@ export var test_headRequest_responseStatusCodeShouldBeDefined = function (done)
},
function (e) {
done(e);
- }
+ },
);
};
@@ -387,7 +470,7 @@ export var test_request_responseHeadersShouldBeDefined = function (done) {
function (e) {
//// Argument (e) is Error!
done(e);
- }
+ },
);
};
@@ -409,7 +492,7 @@ export var test_request_responseContentShouldBeDefined = function (done) {
function (e) {
//// Argument (e) is Error!
done(e);
- }
+ },
);
};
@@ -428,7 +511,7 @@ export var test_request_responseContentToStringShouldReturnString = function (do
},
function (e) {
done(e);
- }
+ },
);
};
@@ -447,7 +530,7 @@ export var test_request_responseContentToJSONShouldReturnJSON = function (done)
},
function (e) {
done(e);
- }
+ },
);
};
@@ -468,7 +551,7 @@ export var test_request_responseContentToImageShouldReturnCorrectImage = functio
},
function (e) {
done(e);
- }
+ },
);
};
@@ -487,7 +570,7 @@ export var test_request_responseContentToFileFromUrlShouldReturnCorrectFile = fu
},
function (e) {
done(e);
- }
+ },
);
};
export var test_request_responseContentToFileFromUrlShouldReturnCorrectFileAndCreateDirPathIfNecesary = function (done) {
@@ -507,7 +590,7 @@ export var test_request_responseContentToFileFromUrlShouldReturnCorrectFileAndCr
},
function (e) {
done(e);
- }
+ },
);
};
@@ -526,7 +609,7 @@ export var test_request_responseContentToFileFromContentShouldReturnCorrectFile
},
function (e) {
done(e);
- }
+ },
);
};
@@ -551,7 +634,7 @@ export var test_request_headersSentAndReceivedProperly = function (done) {
},
function (e) {
done(e);
- }
+ },
);
};
@@ -597,7 +680,7 @@ export var test_request_contentSentAndReceivedProperly = function (done) {
},
function (e) {
done(e);
- }
+ },
);
};
@@ -627,7 +710,7 @@ export var test_request_FormDataContentSentAndReceivedProperly = function (done)
},
function (e) {
done(e);
- }
+ },
);
};
@@ -655,7 +738,7 @@ export var test_request_NonStringHeadersSentAndReceivedProperly = function (done
},
function (e) {
done(e);
- }
+ },
);
};
@@ -684,12 +767,12 @@ export var test_request_jsonAsContentSentAndReceivedProperly = function (done) {
function (e) {
done(e);
// console.log("Error occurred " + e);
- }
+ },
);
};
export var test_getString_WorksProperlyInWorker = function (done) {
- const worker = new Worker('./http-string-worker');
+ const worker = new Worker(new URL('./http-string-worker', import.meta.url));
console.log('Worker Created');
worker.onmessage = function (msg) {
console.log('Message received');
diff --git a/apps/automated/src/main-page.ts b/apps/automated/src/main-page.ts
index 5a62b4412d..4b15c8855f 100644
--- a/apps/automated/src/main-page.ts
+++ b/apps/automated/src/main-page.ts
@@ -1,7 +1,5 @@
import { Trace, Page } from '@nativescript/core';
-import * as tests from './test-runner';
-
let executeTests = true;
Trace.enable();
@@ -18,10 +16,18 @@ Trace.addCategories(Trace.categories.Test + ',' + Trace.categories.Error);
// ));
function runTests() {
- setTimeout(() => tests.runAll(''), 10);
+ setTimeout(async () => {
+ try {
+ const tests = await import('./test-runner');
+ tests.runAll('');
+ } catch (e) {
+ console.error('[automated] failed to load test-runner', e);
+ }
+ }, 10);
}
export function onNavigatedTo(args) {
+ console.log('onNavigatedTo');
args.object.off(Page.loadedEvent, onNavigatedTo);
if (executeTests) {
executeTests = false;
diff --git a/apps/automated/src/main.ts b/apps/automated/src/main.ts
index 05cbb7bf85..5271a64c9e 100644
--- a/apps/automated/src/main.ts
+++ b/apps/automated/src/main.ts
@@ -12,6 +12,13 @@ if (Application.ios) {
Application.ios.addNotificationObserver(UIApplicationDidFinishLaunchingNotification, (notification: NSNotification) => {
console.log('UIApplicationDidFinishLaunchingNotification:', notification);
});
+
+ // Make sure we can add multiple handlers for the same event.
+ for (let i = 0; i < 10; i++) {
+ Application.ios.addDelegateHandler('applicationDidBecomeActive', (application: UIApplication) => {
+ console.log('applicationDidBecomeActive', i, application);
+ });
+ }
}
// Common events for both Android and iOS.
@@ -80,14 +87,14 @@ Application.on(Application.lowMemoryEvent, function (args: ApplicationEventData)
// Error events.
Application.on(Application.uncaughtErrorEvent, function (args: UnhandledErrorEventData) {
console.log('NativeScriptError:', args.error);
- console.log((args.error).nativeException ?? (args.error).nativeError);
- console.log((args.error).stackTrace ?? (args.error).stack);
+ console.log(args.error.nativeException ?? (args.error as any).nativeError);
+ console.log(args.error.stackTrace ?? args.error.stack);
});
Application.on(Application.discardedErrorEvent, function (args: DiscardedErrorEventData) {
console.log('[Discarded] NativeScriptError:', args.error);
- console.log((args.error).nativeException ?? (args.error).nativeError);
- console.log((args.error).stackTrace ?? (args.error).stack);
+ console.log(args.error.nativeException ?? (args.error as any).nativeError);
+ console.log(args.error.stackTrace ?? args.error.stack);
});
// Android activity events.
@@ -142,5 +149,4 @@ if (typeof NSDate !== 'undefined') {
}
console.log(`TIME TO LOAD APP: ${time} ms`);
-
Application.run({ moduleName: 'app-root' });
diff --git a/apps/automated/src/navigation/custom-transition.ios.ts b/apps/automated/src/navigation/custom-transition.ios.ts
index 16a0138899..644b9c4743 100644
--- a/apps/automated/src/navigation/custom-transition.ios.ts
+++ b/apps/automated/src/navigation/custom-transition.ios.ts
@@ -1,5 +1,4 @@
import { PageTransition, SharedTransition, SharedTransitionAnimationType, SharedTransitionHelper, Transition, Utils } from '@nativescript/core';
-import { CORE_ANIMATION_DEFAULTS } from '@nativescript/core/utils';
export class CustomTransition extends Transition {
constructor(duration: number, curve: any) {
@@ -32,7 +31,7 @@ export class CustomTransition extends Transition {
},
(finished) => {
transitionContext.completeTransition(finished);
- }
+ },
);
}
}
@@ -90,7 +89,7 @@ class PageTransitionController extends NSObject implements UIViewControllerAnima
}
}
}
- return CORE_ANIMATION_DEFAULTS.duration;
+ return Utils.CORE_ANIMATION_DEFAULTS.duration;
}
animateTransition(transitionContext: UIViewControllerContextTransitioning): void {
diff --git a/apps/automated/src/navigation/transition-tests.ts b/apps/automated/src/navigation/transition-tests.ts
index e25d482475..9101a57e13 100644
--- a/apps/automated/src/navigation/transition-tests.ts
+++ b/apps/automated/src/navigation/transition-tests.ts
@@ -32,7 +32,7 @@ export function test_Transitions() {
});
var transitions;
- if (Device.os === platformNames.ios) {
+ if (__APPLE__) {
transitions = ['curl'];
} else {
const _sdkVersion = parseInt(Device.sdkVersion);
diff --git a/apps/automated/src/pages/package.json b/apps/automated/src/pages/package.json
index 7117029859..b95dd49cd5 100644
--- a/apps/automated/src/pages/package.json
+++ b/apps/automated/src/pages/package.json
@@ -1,4 +1,4 @@
{
- "name": "testsapp",
- "main": "app.js"
+ "name": "testsapp",
+ "main": "app.js"
}
diff --git a/apps/automated/src/pages/page5.ts b/apps/automated/src/pages/page5.ts
index 349e272a9a..347a1ae1fd 100644
--- a/apps/automated/src/pages/page5.ts
+++ b/apps/automated/src/pages/page5.ts
@@ -7,9 +7,7 @@ function printDeviceInfoAndroid() {
console.log('android.os.Build.VERSION.SDK_INT = ' + android.os.Build.VERSION.SDK_INT); //android.os.Build.VERSION.SDK_INT = 19
console.log('android.os.Build.VERSION.CODENAME = ' + android.os.Build.VERSION.CODENAME); //android.os.Build.VERSION.CODENAME = REL
console.log('android.os.Build.VERSION.RELEASE = ' + android.os.Build.VERSION.RELEASE); //android.os.Build.VERSION.RELEASE = 4.4.4
- var metrics: android.util.DisplayMetrics = Application.android.context
- .getResources()
- .getDisplayMetrics();
+ var metrics: android.util.DisplayMetrics = Application.android.context.getResources().getDisplayMetrics();
console.log('metrics.density = ' + metrics.density); //metrics.density = 3
console.log('metrics.scaledDensity = ' + metrics.scaledDensity); //metrics.scaledDensity = 3
console.log('metrics.densityDpi = ' + metrics.densityDpi); //metrics.densityDpi = 480
@@ -22,12 +20,7 @@ function printDeviceInfoAndroid() {
console.log('config.screenWidthDp = ' + config.screenWidthDp);
console.log('config.screenHeightDp = ' + config.screenHeightDp);
console.log('config.smallestScreenWidthDp = ' + config.smallestScreenWidthDp);
- console.log(
- 'config.orientation = ' +
- (config.orientation === android.content.res.Configuration.ORIENTATION_PORTRAIT
- ? 'portrait'
- : 'ladscape')
- );
+ console.log('config.orientation = ' + (config.orientation === android.content.res.Configuration.ORIENTATION_PORTRAIT ? 'portrait' : 'ladscape'));
}
function printDeviceInfoIOS() {
@@ -41,12 +34,7 @@ function printDeviceInfoIOS() {
console.log('device.batteryLevel = ' + device.batteryLevel); //device.batteryLevel = -1
var screen = UIScreen.mainScreen;
console.log('screen = ' + screen);
- console.log(
- 'screen.nativeBounds = ' +
- screen.nativeBounds.size.width +
- ', ' +
- screen.nativeBounds.size.height
- ); //screen.nativeBounds = 640, 1136
+ console.log('screen.nativeBounds = ' + screen.nativeBounds.size.width + ', ' + screen.nativeBounds.size.height); //screen.nativeBounds = 640, 1136
console.log('screen.scale = ' + screen.scale); //screen.scale = 2
console.log('screen.nativeScale = ' + screen.nativeScale); //screen.nativeScale = 2
}
@@ -58,19 +46,11 @@ function printTNSInfo() {
console.log('platform.Device.sdkVersion = ' + platform.Device.sdkVersion);
console.log('platform.Device.deviceType = ' + platform.Device.deviceType);
- console.log(
- 'platform.Screen.mainScreen.widthDIPs = ' + platform.Screen.mainScreen.widthDIPs
- );
- console.log(
- 'platform.Screen.mainScreen.heightDIPs = ' + platform.Screen.mainScreen.heightDIPs
- );
+ console.log('platform.Screen.mainScreen.widthDIPs = ' + platform.Screen.mainScreen.widthDIPs);
+ console.log('platform.Screen.mainScreen.heightDIPs = ' + platform.Screen.mainScreen.heightDIPs);
console.log('platform.Screen.mainScreen.scale = ' + platform.Screen.mainScreen.scale);
- console.log(
- 'platform.Screen.mainScreen.widthPixels = ' + platform.Screen.mainScreen.widthPixels
- );
- console.log(
- 'platform.Screen.mainScreen.heightPixels = ' + platform.Screen.mainScreen.heightPixels
- );
+ console.log('platform.Screen.mainScreen.widthPixels = ' + platform.Screen.mainScreen.widthPixels);
+ console.log('platform.Screen.mainScreen.heightPixels = ' + platform.Screen.mainScreen.heightPixels);
}
function print() {
diff --git a/apps/automated/src/pages/property-bindings.ts b/apps/automated/src/pages/property-bindings.ts
index 12a9ec9fcd..cb7c3f8bca 100644
--- a/apps/automated/src/pages/property-bindings.ts
+++ b/apps/automated/src/pages/property-bindings.ts
@@ -8,7 +8,7 @@ import { Trace } from '@nativescript/core';
import * as gridModule from '@nativescript/core/ui/layouts/grid-layout';
import * as sliders from '@nativescript/core/ui/slider';
import * as switches from '@nativescript/core/ui/switch';
-import * as bindable from '@nativescript/core/ui/core/bindable';
+import type { BindingOptions } from '@nativescript/core/ui/core/bindable/bindable-types';
Trace.enable();
//Trace.setCategories(Trace.categories.Style + " ," + Trace.categories.Binding);
@@ -64,7 +64,7 @@ export function createPage() {
slider.value = desc.value;
stack.addChild(slider);
- var options: bindable.BindingOptions = {
+ var options: BindingOptions = {
sourceProperty: 'value',
targetProperty: desc.name,
};
@@ -82,7 +82,7 @@ export function createPage() {
sw.horizontalAlignment = 'left';
stack.addChild(sw);
- var options: bindable.BindingOptions = {
+ var options: BindingOptions = {
sourceProperty: 'checked',
targetProperty: desc.name,
};
@@ -99,7 +99,7 @@ export function createPage() {
txt.text = desc.value;
stack.addChild(txt);
- var options: bindable.BindingOptions = {
+ var options: BindingOptions = {
sourceProperty: 'text',
targetProperty: desc.name,
};
diff --git a/apps/automated/src/platform/platform-tests.ts b/apps/automated/src/platform/platform-tests.ts
index e308ccb928..8a2aa4c0bd 100644
--- a/apps/automated/src/platform/platform-tests.ts
+++ b/apps/automated/src/platform/platform-tests.ts
@@ -5,6 +5,8 @@ export function test_platform() {
let expectedPlatform;
if (isAndroid) {
expectedPlatform = 'Android';
+ } else if (__VISIONOS__) {
+ expectedPlatform = 'visionOS';
} else {
expectedPlatform = 'iOS';
}
diff --git a/apps/automated/src/test-runner.ts b/apps/automated/src/test-runner.ts
index 3e97b56735..fd4ffbca88 100644
--- a/apps/automated/src/test-runner.ts
+++ b/apps/automated/src/test-runner.ts
@@ -2,7 +2,7 @@
import * as TKUnit from './tk-unit';
import './ui-test';
-import { isIOS, isAndroid, Application, Device, platformNames, Trace, Button, Frame, StackLayout, Page, TextView, Utils } from '@nativescript/core';
+import { isAndroid, Device, platformNames, Trace, Button, Frame, StackLayout, Page, TextView, Utils, Color } from '@nativescript/core';
Frame.defaultAnimatedNavigation = false;
export function isRunningOnEmulator(): boolean {
@@ -16,7 +16,7 @@ export function isRunningOnEmulator(): boolean {
android.os.Build.PRODUCT.toLocaleLowerCase().indexOf('sdk') > -1 ||
android.os.Build.PRODUCT.toLocaleLowerCase().indexOf('emulator') > -1
); // VS Emulator
- } else if (Device.os === platformNames.ios) {
+ } else if (__APPLE__) {
return __dirname.search('Simulator') > -1;
}
}
@@ -147,7 +147,7 @@ import * as scrollViewSafeAreaTests from './ui/scroll-view/scroll-view-safe-area
import * as repeaterSafeAreaTests from './ui/repeater/repeater-safe-area-tests';
import * as webViewSafeAreaTests from './ui/web-view/web-view-safe-area-tests';
-if (isIOS && Utils.ios.MajorVersion > 10) {
+if (__APPLE__ && Utils.SDK_VERSION > 10) {
allTests['SAFEAREALAYOUT'] = safeAreaLayoutTests;
allTests['SAFEAREA-LISTVIEW'] = safeAreaListViewtTests;
allTests['SAFEAREA-SCROLL-VIEW'] = scrollViewSafeAreaTests;
@@ -176,6 +176,9 @@ allTests['STYLE'] = styleTests;
import * as visualStateTests from './ui/styling/visual-state-tests';
allTests['VISUAL-STATE'] = visualStateTests;
+import * as cssKeywordsTests from './ui/styling/css-keywords-tests';
+allTests['CSS-KEYWORDS'] = cssKeywordsTests;
+
import * as valueSourceTests from './ui/styling/value-source-tests';
allTests['VALUE-SOURCE'] = valueSourceTests;
@@ -218,8 +221,8 @@ allTests['PROGRESS'] = progressTests;
import * as placeholderTests from './ui/placeholder/placeholder-tests';
allTests['PLACEHOLDER'] = placeholderTests;
-// import * as pageTests from './ui/page/page-tests';
-// allTests['PAGE'] = pageTests;
+import * as pageTests from './ui/page/page-tests';
+allTests['PAGE'] = pageTests;
import * as listViewTests from './ui/list-view/list-view-tests';
allTests['LISTVIEW'] = listViewTests;
@@ -245,6 +248,7 @@ allTests['DATE-PICKER'] = datePickerTests;
import * as timePickerTests from './ui/time-picker/time-picker-tests';
allTests['TIME-PICKER'] = timePickerTests;
+// TODO: followup on 3 assertions here -
// import * as webViewTests from './ui/web-view/web-view-tests';
// allTests['WEB-VIEW'] = webViewTests;
@@ -347,6 +351,8 @@ function printRunTestStats() {
let finalMessage = `\n` + `=== ALL TESTS COMPLETE ===\n` + `${allTests.length - failedTestCount} OK, ${failedTestCount} failed\n` + `DURATION: ${totalTime} ms\n` + `=== END OF TESTS ===\n`;
+ Trace.setCategories(Trace.categories.Test);
+ Trace.enable();
TKUnit.write(finalMessage, Trace.messageType.info);
failedTestInfo.forEach((message, i, arr) => {
@@ -397,12 +403,23 @@ function showReportPage(finalMessage: string) {
messageContainer.text = finalMessage;
stack.addChild(messageContainer);
+ if (__VISIONOS__) {
+ // just helps make the results screen more clear on Vision Pro
+ btn.style.fontSize = 22;
+ stack.style.padding = 20;
+ stack.style.marginTop = 20;
+ messageContainer.style.fontSize = 22;
+ messageContainer.style.color = new Color('#fff');
+ }
+
Frame.topmost().navigate({
create: () => {
const page = new Page();
page.content = stack;
messageContainer.focus();
- page.style.fontSize = 11;
+ if (!__VISIONOS__) {
+ page.style.fontSize = 11;
+ }
if (isAndroid) {
page.on('navigatedTo', () => {
messageContainer.focus();
@@ -473,7 +490,7 @@ export function runAll(testSelector?: string) {
new TestInfo(() => {
running = true;
startTime = TKUnit.time();
- })
+ }),
);
for (const name in allTests) {
if (singleModuleName && singleModuleName !== name.toLowerCase()) {
@@ -482,7 +499,11 @@ export function runAll(testSelector?: string) {
const testModule = allTests[name];
- const test = testModule.createTestCase ? testModule.createTestCase() : testModule;
+ // In ESM environments (like Vite), module namespace objects are not extensible.
+ // Some tests expect to set arbitrary properties like `name` on the test instance.
+ // If a module doesn't provide `createTestCase()`, wrap its exports in a plain
+ // mutable object to safely attach metadata without mutating the namespace object.
+ const test = testModule.createTestCase ? testModule.createTestCase() : ({ ...testModule } as any);
test.name = name;
testsQueue.push(new TestInfo(startLog, test));
@@ -519,7 +540,7 @@ export function runAll(testSelector?: string) {
new TestInfo(function () {
testsQueue = [];
running = false;
- })
+ }),
);
TKUnit.runTests(testsQueue, 0);
diff --git a/apps/automated/src/tk-unit.ts b/apps/automated/src/tk-unit.ts
index c875f60f4c..3c79c6dffc 100644
--- a/apps/automated/src/tk-unit.ts
+++ b/apps/automated/src/tk-unit.ts
@@ -11,8 +11,7 @@
*/
-import { isIOS, Trace, Device } from '@nativescript/core';
-import * as types from '@nativescript/core/utils/types';
+import { Trace, Device, Utils } from '@nativescript/core';
const sdkVersion = parseInt(Device.sdkVersion);
@@ -172,10 +171,10 @@ export function assertFalse(test: boolean, message?: string) {
export function assertNotEqual(actual: any, expected: any, message?: string) {
let equals = false;
- if (types.isUndefined(actual) && types.isUndefined(expected)) {
+ if (Utils.isUndefined(actual) && Utils.isUndefined(expected)) {
equals = true;
- } else if (!types.isNullOrUndefined(actual) && !types.isNullOrUndefined(expected)) {
- if (types.isFunction(actual.equals)) {
+ } else if (!Utils.isNullOrUndefined(actual) && !Utils.isNullOrUndefined(expected)) {
+ if (Utils.isFunction(actual.equals)) {
// Use the equals method
if (actual.equals(expected)) {
equals = true;
@@ -191,7 +190,7 @@ export function assertNotEqual(actual: any, expected: any, message?: string) {
}
export function assertEqual(actual: T, expected: T, message: string = '') {
- if (!types.isNullOrUndefined(actual) && !types.isNullOrUndefined(expected) && types.getClass(actual) === types.getClass(expected) && types.isFunction((actual).equals)) {
+ if (!Utils.isNullOrUndefined(actual) && !Utils.isNullOrUndefined(expected) && Utils.getClass(actual) === Utils.getClass(expected) && Utils.isFunction((actual).equals)) {
// Use the equals method
if (!(actual).equals(expected)) {
throw new Error(`${message} Actual: <${actual}>(${typeof actual}). Expected: <${expected}>(${typeof expected})`);
@@ -352,7 +351,7 @@ export function waitUntilReady(isReady: () => boolean, timeoutSec: number = 5, s
return;
}
- if (isIOS) {
+ if (__APPLE__) {
const timeoutMs = timeoutSec * 1000;
let totalWaitTime = 0;
while (true) {
diff --git a/apps/automated/src/ui-helper.ts b/apps/automated/src/ui-helper.ts
index 487ba37cf0..3e1879dbec 100644
--- a/apps/automated/src/ui-helper.ts
+++ b/apps/automated/src/ui-helper.ts
@@ -1,4 +1,4 @@
-import { Color, Button, FormattedString, Span, ActionBar, Builder, isIOS, unsetValue, View, ViewBase, Frame, NavigationEntry, LayoutBase, StackLayout, Page, TabView, TabViewItem, Utils } from '@nativescript/core';
+import { Color, Button, FormattedString, Span, ActionBar, Builder, unsetValue, View, ViewBase, Frame, NavigationEntry, LayoutBase, StackLayout, Page, TabView, TabViewItem, Utils } from '@nativescript/core';
import * as TKUnit from './tk-unit';
@@ -255,7 +255,7 @@ export function assertTabSelectedTabTextColor(testView: ViewBase, hexColor: stri
}
export function forceGC() {
- if (isIOS) {
+ if (__APPLE__) {
/* tslint:disable:no-unused-expression */
// Could cause GC on the next call.
new ArrayBuffer(4 * 1024 * 1024);
@@ -295,7 +295,7 @@ export function _generateFormattedString(): FormattedString {
export function nativeView_recycling_test(createNew: () => View, createLayout?: () => LayoutBase, nativeGetters?: Map any>, customSetters?: Map) {
return;
- // if (isIOS) {
+ // if (__APPLE__) {
// // recycling not implemented yet.
// return;
// }
diff --git a/apps/automated/src/ui/action-bar/action-bar-tests-common.ts b/apps/automated/src/ui/action-bar/action-bar-tests-common.ts
index b0abe4c7ed..708414ff1f 100644
--- a/apps/automated/src/ui/action-bar/action-bar-tests-common.ts
+++ b/apps/automated/src/ui/action-bar/action-bar-tests-common.ts
@@ -1,16 +1,6 @@
import * as TKUnit from '../../tk-unit';
import * as helper from '../../ui-helper';
-import { Builder } from '@nativescript/core/ui/builder';
-import { Label } from '@nativescript/core/ui/label';
-import { Button } from '@nativescript/core/ui/button';
-import { Page } from '@nativescript/core/ui/page';
-import { View, isIOS } from '@nativescript/core';
-import { fromObject } from '@nativescript/core/data/observable';
-import { Frame } from '@nativescript/core/ui/frame';
-
-// >> actionbar-common-require
-import * as actionBarModule from '@nativescript/core/ui/action-bar';
-// << actionbar-common-require
+import { View, fromObject, Frame, Page, Button, Label, Builder, ActionItem, ActionBar } from '@nativescript/core';
export function test_actionItem_inherit_bindingContext() {
let page: Page;
@@ -20,7 +10,7 @@ export function test_actionItem_inherit_bindingContext() {
const pageFactory = function (): Page {
page = new Page();
page.bindingContext = context;
- const actionItem = new actionBarModule.ActionItem();
+ const actionItem = new ActionItem();
actionItem.bind({
sourceProperty: 'text',
@@ -164,7 +154,7 @@ export function test_Setting_ActionItems_doesnt_thrown() {
const pageFactory = function (): Page {
page = new Page();
- const actionItem = new actionBarModule.ActionItem();
+ const actionItem = new ActionItem();
actionItem.text = 'Item';
page.actionBar.actionItems.addItem(actionItem);
@@ -286,12 +276,12 @@ export function test_ActionBarVisibility_Never_ShouldNotShowDeclaredActionBar()
- `
+ `,
);
helper.navigate(() => page);
let actionBarHidden = false;
- if (isIOS) {
+ if (__APPLE__) {
actionBarHidden = page.actionBar.nativeView.hidden;
} else {
actionBarHidden = !page.actionBar.nativeView.isShown();
@@ -314,12 +304,12 @@ export function test_ActionBarVisibility_Always_ShouldShownHiddenActionBar() {
- `
+ `,
);
helper.navigate(() => page);
let actionBarHidden = false;
- if (isIOS) {
+ if (__APPLE__) {
actionBarHidden = page.actionBar.nativeView.hidden;
} else {
actionBarHidden = !page.actionBar.nativeView.isShown();
@@ -342,12 +332,12 @@ export function test_ActionBarVisibility_Auto_ShouldRespectPageActionBarHiddenPr
- `
+ `,
);
helper.navigate(() => page);
let actionBarHidden = false;
- if (isIOS) {
+ if (__APPLE__) {
actionBarHidden = page.actionBar.nativeView.hidden;
} else {
actionBarHidden = !page.actionBar.nativeView.isShown();
@@ -391,5 +381,5 @@ export function createPageAndNavigate() {
}
export function test_recycling() {
- helper.nativeView_recycling_test(() => new actionBarModule.ActionBar());
+ helper.nativeView_recycling_test(() => new ActionBar());
}
diff --git a/apps/automated/src/ui/activity-indicator/activity-indicator-tests.ts b/apps/automated/src/ui/activity-indicator/activity-indicator-tests.ts
index 9c029e0a76..b06a470ec8 100644
--- a/apps/automated/src/ui/activity-indicator/activity-indicator-tests.ts
+++ b/apps/automated/src/ui/activity-indicator/activity-indicator-tests.ts
@@ -49,8 +49,8 @@ export function test_set_TNS_value_updates_native_value() {
}
// Uncomment this when find way to check android Drawable color set by setColorFilter() method.
-if (platform.Device.os === platform.platformNames.ios) {
- exports.test_set_color = function () {
+export function test_set_color() {
+ if (__APPLE__) {
var ai = new activityIndicatorModule.ActivityIndicator();
ai.color = new color.Color('red');
@@ -59,7 +59,7 @@ if (platform.Device.os === platform.platformNames.ios) {
}
helper.buildUIAndRunTest(ai, testAction);
- };
+ }
}
// This method is only for the code snippet
@@ -79,7 +79,7 @@ function binding_busy_to_image() {
sourceProperty: 'isLoading',
targetProperty: 'busy',
},
- image
+ image,
);
// << activity-indicator-loading
}
diff --git a/apps/automated/src/ui/animation/animation-tests.ts b/apps/automated/src/ui/animation/animation-tests.ts
index ad75839ce4..75bbbd6f0d 100644
--- a/apps/automated/src/ui/animation/animation-tests.ts
+++ b/apps/automated/src/ui/animation/animation-tests.ts
@@ -1,11 +1,6 @@
import * as TKUnit from '../../tk-unit';
import * as helper from '../../ui-helper';
-import * as viewModule from '@nativescript/core/ui/core/view';
-import { Label } from '@nativescript/core/ui/label';
-import { StackLayout } from '@nativescript/core/ui/layouts/stack-layout';
-import * as colorModule from '@nativescript/core/color';
-import { CoreTypes, PercentLength } from '@nativescript/core';
-import { AnimationPromise, AnimationDefinition, Animation } from '@nativescript/core/ui/animation';
+import { AnimationPromise, AnimationDefinition, Animation, CoreTypes, PercentLength, Label, StackLayout, View, Color } from '@nativescript/core';
// >> animation-require
// import * as animation from '@nativescript/core/ui/animation';
@@ -38,7 +33,7 @@ export function test_AnimatingProperties(done) {
label
.animate({
opacity: 0.75,
- backgroundColor: new colorModule.Color('Red'),
+ backgroundColor: new Color('Red'),
translate: { x: 100, y: 100 },
scale: { x: 2, y: 2 },
rotate: 180,
@@ -79,7 +74,7 @@ export function test_PlayRejectsWhenAlreadyPlayingAnimation(done) {
if (e === 'Animation is already playing.') {
done();
}
- }
+ },
);
}
@@ -269,7 +264,7 @@ export function test_AnimateOpacity(done) {
export function test_AnimateOpacity_ShouldThrow_IfNotNumber() {
var label = new Label();
- helper.buildUIAndRunTest(label, (views: Array) => {
+ helper.buildUIAndRunTest(label, (views: Array) => {
TKUnit.assertThrows(() => {
label.animate({ opacity: '0.75' });
}, 'Setting opacity to a non number should throw.');
@@ -278,7 +273,7 @@ export function test_AnimateOpacity_ShouldThrow_IfNotNumber() {
export function test_AnimateDelay_ShouldThrow_IfNotNumber() {
var label = new Label();
- helper.buildUIAndRunTest(label, (views: Array) => {
+ helper.buildUIAndRunTest(label, (views: Array) => {
TKUnit.assertThrows(() => {
label.animate({ delay: '1' });
}, 'Setting delay to a non number should throw.');
@@ -287,7 +282,7 @@ export function test_AnimateDelay_ShouldThrow_IfNotNumber() {
export function test_AnimateDuration_ShouldThrow_IfNotNumber() {
var label = new Label();
- helper.buildUIAndRunTest(label, (views: Array) => {
+ helper.buildUIAndRunTest(label, (views: Array) => {
TKUnit.assertThrows(() => {
label.animate({ duration: '1' });
}, 'Setting duration to a non number should throw.');
@@ -296,7 +291,7 @@ export function test_AnimateDuration_ShouldThrow_IfNotNumber() {
export function test_AnimateIterations_ShouldThrow_IfNotNumber() {
var label = new Label();
- helper.buildUIAndRunTest(label, (views: Array) => {
+ helper.buildUIAndRunTest(label, (views: Array) => {
TKUnit.assertThrows(() => {
label.animate({ iterations: '1' });
}, 'Setting iterations to a non number should throw.');
@@ -305,7 +300,7 @@ export function test_AnimateIterations_ShouldThrow_IfNotNumber() {
export function test_AnimateRotate_ShouldThrow_IfNotNumber() {
var label = new Label();
- helper.buildUIAndRunTest(label, (views: Array) => {
+ helper.buildUIAndRunTest(label, (views: Array) => {
TKUnit.assertThrows(() => {
label.animate({ rotate: '1' });
}, 'Setting rotate to a non number should throw.');
@@ -314,7 +309,7 @@ export function test_AnimateRotate_ShouldThrow_IfNotNumber() {
export function test_AnimateScale_ShouldThrow_IfNotPair() {
var label = new Label();
- helper.buildUIAndRunTest(label, (views: Array) => {
+ helper.buildUIAndRunTest(label, (views: Array) => {
TKUnit.assertThrows(() => {
label.animate({ scale: '1' });
}, 'Setting scale to a non Pair should throw.');
@@ -323,7 +318,7 @@ export function test_AnimateScale_ShouldThrow_IfNotPair() {
export function test_AnimateTranslate_ShouldThrow_IfNotPair() {
var label = new Label();
- helper.buildUIAndRunTest(label, (views: Array) => {
+ helper.buildUIAndRunTest(label, (views: Array) => {
TKUnit.assertThrows(() => {
label.animate({ translate: '1' });
}, 'Setting translate to a non Pair should throw.');
@@ -332,7 +327,7 @@ export function test_AnimateTranslate_ShouldThrow_IfNotPair() {
export function test_AnimateBackgroundColor_ShouldThrow_IfNotValidColorStringOrColor() {
var label = new Label();
- helper.buildUIAndRunTest(label, (views: Array) => {
+ helper.buildUIAndRunTest(label, (views: Array) => {
TKUnit.assertThrows(() => {
label.animate({ backgroundColor: 'test' });
}, 'Setting backgroundColor to a not valid color string or Color should throw.');
@@ -341,12 +336,12 @@ export function test_AnimateBackgroundColor_ShouldThrow_IfNotValidColorStringOrC
export function test_AnimateBackgroundColor(done) {
let label = prepareTest();
- var red = new colorModule.Color('Red');
+ var red = new Color('Red');
label
.animate({ backgroundColor: red, duration: 5 })
.then(() => {
- TKUnit.assert((label.backgroundColor).equals(red));
+ TKUnit.assert((label.backgroundColor).equals(red));
done();
})
.catch((e) => {
@@ -357,12 +352,12 @@ export function test_AnimateBackgroundColor(done) {
export function test_AnimateBackgroundColor_FromString(done) {
let label = prepareTest();
var expected = 'Red';
- var clr = new colorModule.Color(expected);
+ var clr = new Color(expected);
label
.animate({ backgroundColor: expected, duration: 5 })
.then(() => {
- TKUnit.assert((label.backgroundColor).equals(clr));
+ TKUnit.assert((label.backgroundColor).equals(clr));
done();
})
.catch((e) => {
@@ -505,7 +500,7 @@ export function test_AnimateExtent_Should_AcceptNumberValuesAsDip(done) {
export function test_AnimateExtent_Should_ThrowIfCannotParsePercentLength() {
const label = new Label();
- helper.buildUIAndRunTest(label, (views: Array) => {
+ helper.buildUIAndRunTest(label, (views: Array) => {
TKUnit.assertThrows(() => {
label.animate({ width: '-frog%' });
}, 'Invalid percent string should throw');
@@ -610,7 +605,7 @@ export function test_PlayPromiseIsResolvedWhenAnimationFinishes(done) {
function onRejected(e) {
TKUnit.assert(false, 'Animation play promise should be resolved, not rejected.');
done(e);
- }
+ },
);
}
@@ -627,14 +622,14 @@ export function test_PlayPromiseIsRejectedWhenAnimationIsCancelled(done) {
function onRejected(e) {
TKUnit.assert(animation.isPlaying === false, 'Animation.isPlaying should be false when animation play promise is rejected.');
done();
- }
+ },
);
animation.cancel();
}
-function assertIOSNativeTransformIsCorrect(view: viewModule.View) {
- if (global.isIOS) {
+function assertIOSNativeTransformIsCorrect(view: View) {
+ if (__APPLE__) {
var errorMessage = (require('@nativescript/core/ui/animation'))._getTransformMismatchErrorMessage(view);
if (errorMessage) {
TKUnit.assert(false, errorMessage);
diff --git a/apps/automated/src/ui/animation/css-animation-tests.ts b/apps/automated/src/ui/animation/css-animation-tests.ts
index edb41b1149..4c96efde63 100644
--- a/apps/automated/src/ui/animation/css-animation-tests.ts
+++ b/apps/automated/src/ui/animation/css-animation-tests.ts
@@ -1,7 +1,7 @@
import * as TKUnit from '../../tk-unit';
import { StyleScope } from '@nativescript/core/ui/styling/style-scope';
import * as keyframeAnimation from '@nativescript/core/ui/animation/keyframe-animation';
-import { CoreTypes } from '@nativescript/core';
+import { Application, CoreTypes, Screen } from '@nativescript/core';
import * as helper from '../../ui-helper';
import * as stackModule from '@nativescript/core/ui/layouts/stack-layout';
import * as labelModule from '@nativescript/core/ui/label';
@@ -18,7 +18,6 @@ function createAnimationFromCSS(css: string, name: string): keyframeAnimation.Ke
const selector = findSelectorInScope(scope, name);
if (selector) {
const animation = scope.getAnimations(selector.ruleset)[0];
-
return animation;
}
}
@@ -40,7 +39,7 @@ export function test_ReadAnimationProperties() {
animation-direction: reverse;
animation-fill-mode: forwards;
}`,
- 'test'
+ 'test',
);
TKUnit.assertEqual(animation.name, 'first');
TKUnit.assertEqual(animation.duration, 4000);
@@ -56,7 +55,7 @@ export function test_ReadTheAnimationProperty() {
`.test {
animation: second 0.2s ease-out 1s 2;
}`,
- 'test'
+ 'test',
);
TKUnit.assertEqual(animation.name, 'second');
TKUnit.assertEqual(animation.duration, 200);
@@ -70,42 +69,42 @@ export function test_ReadAnimationCurve() {
`.test {
animation-timing-function: ease-in;
}`,
- 'test'
+ 'test',
);
TKUnit.assertEqual(animation.curve, CoreTypes.AnimationCurve.easeIn);
animation = createAnimationFromCSS(
`.test {
animation-timing-function: ease-out;
}`,
- 'test'
+ 'test',
);
TKUnit.assertEqual(animation.curve, CoreTypes.AnimationCurve.easeOut);
animation = createAnimationFromCSS(
`.test {
animation-timing-function: linear;
}`,
- 'test'
+ 'test',
);
TKUnit.assertEqual(animation.curve, CoreTypes.AnimationCurve.linear);
animation = createAnimationFromCSS(
`.test {
animation-timing-function: ease-in-out;
}`,
- 'test'
+ 'test',
);
TKUnit.assertEqual(animation.curve, CoreTypes.AnimationCurve.easeInOut);
animation = createAnimationFromCSS(
`.test {
animation-timing-function: spring;
}`,
- 'test'
+ 'test',
);
TKUnit.assertEqual(animation.curve, CoreTypes.AnimationCurve.spring);
animation = createAnimationFromCSS(
`.test {
animation-timing-function: cubic-bezier(0.1, 1.0, 0.5, 0.5);
}`,
- 'test'
+ 'test',
);
let curve = animation.curve;
TKUnit.assert(curve.x1 === 0.1 && curve.y1 === 1.0 && curve.x2 === 0.5 && curve.y2 === 0.5);
@@ -116,14 +115,14 @@ export function test_ReadIterations() {
`.test {
animation-iteration-count: 5;
}`,
- 'test'
+ 'test',
);
TKUnit.assertEqual(animation.iterations, 5);
animation = createAnimationFromCSS(
`.test {
animation-iteration-count: infinite;
}`,
- 'test'
+ 'test',
);
TKUnit.assertEqual(animation.iterations, Number.POSITIVE_INFINITY);
}
@@ -133,21 +132,21 @@ export function test_ReadFillMode() {
`.test {
animation-iteration-count: 5;
}`,
- 'test'
+ 'test',
);
TKUnit.assertFalse(animation.isForwards);
animation = createAnimationFromCSS(
`.test {
animation-fill-mode: forwards;
}`,
- 'test'
+ 'test',
);
TKUnit.assertTrue(animation.isForwards);
animation = createAnimationFromCSS(
`.test {
animation-fill-mode: backwards;
}`,
- 'test'
+ 'test',
);
TKUnit.assertFalse(animation.isForwards);
}
@@ -157,21 +156,21 @@ export function test_ReadDirection() {
`.test {
animation-iteration-count: 5;
}`,
- 'test'
+ 'test',
);
TKUnit.assertFalse(animation.isReverse);
animation = createAnimationFromCSS(
`.test {
animation-direction: reverse;
}`,
- 'test'
+ 'test',
);
TKUnit.assertTrue(animation.isReverse);
animation = createAnimationFromCSS(
`.test {
animation-direction: normal;
}`,
- 'test'
+ 'test',
);
TKUnit.assertFalse(animation.isReverse);
}
@@ -183,7 +182,7 @@ export function test_ReadKeyframe() {
from { background-color: red; }
to { background-color: blue; }
}`,
- 'test'
+ 'test',
);
TKUnit.assert(animation !== undefined, 'CSS selector was not created!');
TKUnit.assertEqual(animation.name, 'test', 'Wrong animation name!');
@@ -200,7 +199,7 @@ export function test_ReadTransformAllSet() {
@keyframes test {
to { transform: rotate(10) scaleX(5) translate(100, 200); }
}`,
- 'test'
+ 'test',
);
const { rotate, scale, translate } = getTransformsValues(animation.keyframes[0].declarations);
@@ -219,7 +218,7 @@ export function test_ReadTransformNone() {
@keyframes test {
to { transform: none; }
}`,
- 'test'
+ 'test',
);
const { rotate, scale, translate } = getTransformsValues(animation.keyframes[0].declarations);
@@ -238,7 +237,7 @@ export function test_ReadScale() {
@keyframes test {
to { transform: scale(-5, 12.3pt); }
}`,
- 'test'
+ 'test',
);
const { scale } = getTransforms(animation.keyframes[0].declarations);
@@ -253,7 +252,7 @@ export function test_ReadScaleSingle() {
@keyframes test {
to { transform: scale(2); }
}`,
- 'test'
+ 'test',
);
const { scale } = getTransforms(animation.keyframes[0].declarations);
@@ -268,7 +267,7 @@ export function test_ReadScaleXY() {
@keyframes test {
to { transform: scaleX(5) scaleY(10); }
}`,
- 'test'
+ 'test',
);
const { scale } = getTransforms(animation.keyframes[0].declarations);
@@ -283,7 +282,7 @@ export function test_ReadScaleX() {
@keyframes test {
to { transform: scaleX(12.5); }
}`,
- 'test'
+ 'test',
);
const { scale } = getTransforms(animation.keyframes[0].declarations);
@@ -299,7 +298,7 @@ export function test_ReadScaleY() {
@keyframes test {
to { transform: scaleY(10); }
}`,
- 'test'
+ 'test',
);
const { scale } = getTransforms(animation.keyframes[0].declarations);
@@ -315,7 +314,7 @@ export function test_ReadScale3d() {
@keyframes test {
to { transform: scale3d(10, 20, 30); }
}`,
- 'test'
+ 'test',
);
const { scale } = getTransforms(animation.keyframes[0].declarations);
@@ -330,7 +329,7 @@ export function test_ReadTranslate() {
@keyframes test {
to { transform: translate(100, 20); }
}`,
- 'test'
+ 'test',
);
const { translate } = getTransforms(animation.keyframes[0].declarations);
@@ -345,7 +344,7 @@ export function test_ReadTranslateSingle() {
@keyframes test {
to { transform: translate(30); }
}`,
- 'test'
+ 'test',
);
const { translate } = getTransforms(animation.keyframes[0].declarations);
@@ -360,7 +359,7 @@ export function test_ReadTranslateXY() {
@keyframes test {
to { transform: translateX(5) translateY(10); }
}`,
- 'test'
+ 'test',
);
const { translate } = getTransforms(animation.keyframes[0].declarations);
@@ -375,7 +374,7 @@ export function test_ReadTranslateX() {
@keyframes test {
to { transform: translateX(12.5); }
}`,
- 'test'
+ 'test',
);
const { translate } = getTransforms(animation.keyframes[0].declarations);
@@ -391,7 +390,7 @@ export function test_ReadTranslateY() {
@keyframes test {
to { transform: translateY(10); }
}`,
- 'test'
+ 'test',
);
const { translate } = getTransforms(animation.keyframes[0].declarations);
@@ -407,7 +406,7 @@ export function test_ReadTranslate3d() {
@keyframes test {
to { transform: translate3d(10, 20, 30); }
}`,
- 'test'
+ 'test',
);
const { translate } = getTransforms(animation.keyframes[0].declarations);
@@ -422,7 +421,7 @@ export function test_ReadRotate() {
@keyframes test {
to { transform: rotate(5); }
}`,
- 'test'
+ 'test',
);
const { rotate } = getTransforms(animation.keyframes[0].declarations);
@@ -436,7 +435,7 @@ export function test_ReadRotateDeg() {
@keyframes test {
to { transform: rotate(45deg); }
}`,
- 'test'
+ 'test',
);
const { rotate } = getTransforms(animation.keyframes[0].declarations);
@@ -450,7 +449,7 @@ export function test_ReadRotateRad() {
@keyframes test {
to { transform: rotate(0.7853981634rad); }
}`,
- 'test'
+ 'test',
);
const { rotate } = getTransforms(animation.keyframes[0].declarations);
@@ -467,7 +466,7 @@ export function test_ReadAnimationWithUnsortedKeyframes() {
40%, 80% { opacity: 0.3; }
to { opacity: 1; }
}`,
- 'test'
+ 'test',
);
TKUnit.assertEqual(animation.keyframes.length, 6);
TKUnit.assertEqual(animation.keyframes[0].declarations[0].value, 0);
@@ -502,7 +501,7 @@ export function test_LoadTwoAnimationsWithTheSameName() {
from { opacity: 0; }
to { opacity: 0.5; } /* this should override the previous one */
}`,
- 'a'
+ 'a',
);
TKUnit.assertEqual(animation.keyframes.length, 2);
TKUnit.assertEqual(animation.keyframes[1].declarations[0].value, 0.5);
@@ -520,7 +519,7 @@ export function test_LoadTwoAnimationsWithTheSameName() {
from { opacity: 0; }
to { opacity: 1; }
}`,
- 'a'
+ 'a',
);
TKUnit.assertEqual(animation2.keyframes.length, 2);
@@ -542,6 +541,68 @@ export function test_LoadAnimationProgrammatically() {
});
}
+export function test_LoadMatchingMediaQueryKeyframeAnimation() {
+ const animation = createAnimationFromCSS(
+ `.a { animation-name: mq1; }
+ @media only screen and (max-width: ${Screen.mainScreen.widthDIPs}) {
+ @keyframes mq1 {
+ from { opacity: 0; }
+ to { opacity: 1; }
+ }
+ }`,
+ 'a',
+ );
+ TKUnit.assertEqual(animation.keyframes.length, 2);
+ TKUnit.assertEqual(animation.keyframes[1].declarations[0].value, 1);
+}
+
+export function test_IgnoreNonMatchingMediaQueryKeyframe() {
+ const animation = createAnimationFromCSS(
+ `.a { animation-name: mq1; }
+ @media only screen and (max-width: ${Screen.mainScreen.widthDIPs - 1}) {
+ @keyframes mq1 {
+ from { opacity: 0; }
+ to { opacity: 1; }
+ }
+ }`,
+ 'a',
+ );
+ TKUnit.assertEqual(animation.keyframes, null);
+}
+
+export function test_LoadMatchingNestedMediaQueryKeyframeAnimation() {
+ const animation = createAnimationFromCSS(
+ `.a { animation-name: mq1; }
+ @media only screen and (orientation: ${Application.orientation()}) {
+ @media only screen and (max-width: ${Screen.mainScreen.widthDIPs}) {
+ @keyframes mq1 {
+ from { opacity: 0; }
+ to { opacity: 1; }
+ }
+ }
+ }`,
+ 'a',
+ );
+ TKUnit.assertEqual(animation.keyframes.length, 2);
+ TKUnit.assertEqual(animation.keyframes[1].declarations[0].value, 1);
+}
+
+export function test_IgnoreNonMatchingNestedMediaQueryKeyframe() {
+ const animation = createAnimationFromCSS(
+ `.a { animation-name: mq1; }
+ @media only screen and (orientation: ${Application.orientation()}) {
+ @media only screen and (max-width: ${Screen.mainScreen.widthDIPs - 1}) {
+ @keyframes mq1 {
+ from { opacity: 0; }
+ to { opacity: 1; }
+ }
+ }
+ }`,
+ 'a',
+ );
+ TKUnit.assertEqual(animation.keyframes, null);
+}
+
export function test_ExecuteCSSAnimation() {
let mainPage = helper.getCurrentPage();
mainPage.css = null;
@@ -615,7 +676,7 @@ export function test_AnimationCurveInKeyframes() {
50% { background-color: green; }
to { background-color: black; }
}`,
- 'test'
+ 'test',
);
TKUnit.assertEqual(animation.keyframes[0].curve, CoreTypes.AnimationCurve.linear);
diff --git a/apps/automated/src/ui/button/button-tests-native.android.ts b/apps/automated/src/ui/button/button-tests-native.android.ts
index c5c03d74c8..ac63dff76a 100644
--- a/apps/automated/src/ui/button/button-tests-native.android.ts
+++ b/apps/automated/src/ui/button/button-tests-native.android.ts
@@ -1,4 +1,5 @@
import { Color, Button, Utils, CoreTypes } from '@nativescript/core';
+import { AndroidHelper } from '@nativescript/core/ui/core/view';
export function getNativeText(button: Button): string {
return button.android.getText();
@@ -19,15 +20,7 @@ export function getNativeColor(button: Button): Color {
}
export function getNativeBackgroundColor(button: Button): Color {
- let bg = button.android.getBackground();
- if (bg instanceof org.nativescript.widgets.BorderDrawable) {
- return new Color(bg.getBackgroundColor());
- } else if (bg instanceof android.graphics.drawable.ColorDrawable) {
- console.log(bg);
- return new Color(bg.getColor());
- } else {
- return new Color(bg.backgroundColor);
- }
+ return AndroidHelper.getDrawableColor(button.android.getBackground());
}
export function getNativeTextAlignment(button: Button): string {
diff --git a/apps/automated/src/ui/button/button-tests.ts b/apps/automated/src/ui/button/button-tests.ts
index cc3dfd7036..07f9a1b112 100644
--- a/apps/automated/src/ui/button/button-tests.ts
+++ b/apps/automated/src/ui/button/button-tests.ts
@@ -1,12 +1,7 @@
import * as TKUnit from '../../tk-unit';
import * as helper from '../../ui-helper';
-import { View, EventData, Button, Observable, Color, Page, FormattedString } from '@nativescript/core';
+import { View, EventData, Button, Observable, Color, Page, FormattedString, BindingOptions, Span } from '@nativescript/core';
import * as buttonTestsNative from './button-tests-native';
-import * as spanModule from '@nativescript/core/text/span';
-
-// >> button-require-others
-import { BindingOptions } from '@nativescript/core/ui/core/bindable';
-// << button-require-others
export function test_recycling() {
helper.nativeView_recycling_test(() => new Button());
@@ -274,7 +269,7 @@ export var test_StateHighlighted_also_fires_pressedState = function () {
helper.waitUntilLayoutReady(view);
- view._goToVisualState('highlighted');
+ view._addVisualState('highlighted');
var actualResult = buttonTestsNative.getNativeBackgroundColor(view);
TKUnit.assert(actualResult.hex === expectedNormalizedColor, 'Actual: ' + actualResult.hex + '; Expected: ' + expectedNormalizedColor);
@@ -291,7 +286,7 @@ export var test_StateHighlighted_also_fires_activeState = function () {
helper.waitUntilLayoutReady(view);
- view._goToVisualState('highlighted');
+ view._addVisualState('highlighted');
var actualResult = buttonTestsNative.getNativeBackgroundColor(view);
TKUnit.assert(actualResult.hex === expectedNormalizedColor, 'Actual: ' + actualResult.hex + '; Expected: ' + expectedNormalizedColor);
@@ -326,13 +321,13 @@ export var testNativeTextAlignmentFromLocal = function () {
};
export var test_WhenFormattedTextPropertyChanges_TextIsUpdated_Button = function () {
- var firstSpan = new spanModule.Span();
+ var firstSpan = new Span();
firstSpan.fontSize = 10;
firstSpan.text = 'First';
- var secondSpan = new spanModule.Span();
+ var secondSpan = new Span();
secondSpan.fontSize = 15;
secondSpan.text = 'Second';
- var thirdSpan = new spanModule.Span();
+ var thirdSpan = new Span();
thirdSpan.fontSize = 20;
thirdSpan.text = 'Third';
var formattedString1 = new FormattedString();
@@ -392,7 +387,7 @@ export function test_setting_formattedText_With_UnknownFont_DoesNotCrash() {
helper.buildUIAndRunTest(btn, function (views) {
TKUnit.waitUntilReady(() => btn.isLayoutValid);
- let span = new spanModule.Span();
+ let span = new Span();
span.text = 'Login';
let formattedString = new FormattedString();
formattedString.spans.push(span);
diff --git a/apps/automated/src/ui/core/bindable/bindable-tests.ts b/apps/automated/src/ui/core/bindable/bindable-tests.ts
index 8007ee0ff3..825db61c91 100644
--- a/apps/automated/src/ui/core/bindable/bindable-tests.ts
+++ b/apps/automated/src/ui/core/bindable/bindable-tests.ts
@@ -1,11 +1,7 @@
-import { Observable, fromObject, fromObjectRecursive } from '@nativescript/core/data/observable';
-import { ViewBase } from '@nativescript/core/ui/core/view-base';
-import { BindingOptions } from '@nativescript/core/ui/core/bindable';
+import { Application, View, Button, Page, StackLayout, Label, TextField, Trace, BindingOptions, ViewBase, Observable, fromObject, fromObjectRecursive, Utils } from '@nativescript/core';
import * as TKUnit from '../../../tk-unit';
-import * as types from '@nativescript/core/utils/types';
import * as helper from '../../../ui-helper';
import * as bindingBuilder from '@nativescript/core/ui/builder/binding-builder';
-import { Application, View, Button, Page, StackLayout, Label, TextField, Trace } from '@nativescript/core';
declare var WeakRef: any;
//
// For information and examples how to use bindings please refer to special [**Data binding**](../../../../bindings.md) topic.
@@ -17,8 +13,8 @@ declare var WeakRef: any;
export function test_Bindable_Members() {
const obj = new Label();
- TKUnit.assert(types.isDefined(obj.bind), 'Bindable.bind not defined');
- TKUnit.assert(types.isDefined(obj.unbind), 'Bindable.unbind not defined');
+ TKUnit.assert(Utils.isDefined(obj.bind), 'Bindable.bind not defined');
+ TKUnit.assert(Utils.isDefined(obj.unbind), 'Bindable.unbind not defined');
}
export function test_Binding_to_bindingContext_of_View() {
@@ -502,7 +498,7 @@ export function test_bindingToNestedPropertyWithValueSyntax() {
sourceProperty: '$value.testProperty',
targetProperty: 'targetPropertyName',
},
- bindingSource
+ bindingSource,
);
TKUnit.assertEqual(testElement.get('targetPropertyName'), 'testValue');
@@ -706,7 +702,7 @@ export function test_UpdatingNestedPropertyViaBinding() {
targetProperty: 'text',
twoWay: true,
},
- viewModel
+ viewModel,
);
const testElement2 = new Label();
@@ -717,7 +713,7 @@ export function test_UpdatingNestedPropertyViaBinding() {
targetProperty: 'text',
twoWay: true,
},
- viewModel
+ viewModel,
);
TKUnit.assertEqual(testElement.get('text'), expectedValue1);
@@ -803,7 +799,7 @@ export function test_NestedPropertiesBinding() {
targetProperty: 'targetProperty',
twoWay: true,
},
- viewModel
+ viewModel,
);
TKUnit.assertEqual(target1.get('targetProperty'), expectedValue);
@@ -835,7 +831,7 @@ export function test_WrongNestedPropertiesBinding() {
targetProperty: 'targetProperty',
twoWay: true,
},
- viewModel
+ viewModel,
);
TKUnit.assertNotEqual(errorMessage, undefined);
@@ -856,7 +852,7 @@ export function test_NestedPropertiesBindingTwoTargets() {
targetProperty: 'targetProperty',
twoWay: true,
},
- viewModel
+ viewModel,
);
const target2 = new Label();
@@ -866,7 +862,7 @@ export function test_NestedPropertiesBindingTwoTargets() {
targetProperty: 'targetProp',
twoWay: true,
},
- viewModel
+ viewModel,
);
TKUnit.assertEqual(target1.get('targetProperty'), expectedText);
@@ -897,7 +893,7 @@ export function test_NestedPropertiesBindingTwoTargetsAndSecondChange() {
targetProperty: 'targetProperty',
twoWay: true,
},
- viewModel
+ viewModel,
);
const target2 = new Label();
@@ -907,7 +903,7 @@ export function test_NestedPropertiesBindingTwoTargetsAndSecondChange() {
targetProperty: 'targetProp',
twoWay: true,
},
- viewModel
+ viewModel,
);
TKUnit.assertEqual(target1.get('targetProperty'), expectedText);
@@ -948,7 +944,7 @@ export function test_NestedPropertiesBindingTwoTargetsAndRegularChange() {
targetProperty: 'targetProperty',
twoWay: true,
},
- viewModel
+ viewModel,
);
const target2 = new Label();
@@ -958,7 +954,7 @@ export function test_NestedPropertiesBindingTwoTargetsAndRegularChange() {
targetProperty: 'targetProp',
twoWay: true,
},
- viewModel
+ viewModel,
);
TKUnit.assertEqual(target1.get('targetProperty'), expectedText);
@@ -998,7 +994,7 @@ export function test_NestedPropertiesBindingTwoTargetsAndReplacingSomeNestedObje
targetProperty: 'targetProperty',
twoWay: true,
},
- viewModel
+ viewModel,
);
const target2 = new Label();
@@ -1008,7 +1004,7 @@ export function test_NestedPropertiesBindingTwoTargetsAndReplacingSomeNestedObje
targetProperty: 'targetProp',
twoWay: true,
},
- viewModel
+ viewModel,
);
TKUnit.assertEqual(target1.get('targetProperty'), expectedText);
@@ -1050,7 +1046,7 @@ export function test_NullSourcePropertyShouldNotCrash() {
targetProperty: 'targetProp',
expression: 'convFunc(field)',
},
- model
+ model,
);
TKUnit.assertEqual(target.get('targetProp'), convFunc(expectedValue));
@@ -1123,7 +1119,7 @@ export function test_SupportFunctionsInExpressions() {
targetProperty: 'text',
expression: "isVisible() ? 'visible' : 'collapsed'",
},
- model
+ model,
);
model.set('anyColor', 'blue');
@@ -1151,7 +1147,7 @@ export function test_$ValueSupportWithinExpression() {
targetProperty: 'text',
expression: "$value.anyColor === 'red' ? 'red' : 'blue'",
},
- model
+ model,
);
model.set('anyColor', 'blue');
@@ -1230,7 +1226,7 @@ export function test_BindingToPropertiesWithSameNames() {
targetProperty: 'targetProperty',
twoWay: true,
},
- model
+ model,
);
const target2 = new Label();
@@ -1240,7 +1236,7 @@ export function test_BindingToPropertiesWithSameNames() {
targetProperty: 'targetProp',
twoWay: true,
},
- model
+ model,
);
model.item.set('seconds', model.item.seconds + 1);
@@ -1273,7 +1269,7 @@ export function test_BindingToPropertiesWithSameNamesSecondCase() {
targetProperty: 'targetProperty',
twoWay: true,
},
- model
+ model,
);
const target2 = new Label();
@@ -1283,7 +1279,7 @@ export function test_BindingToPropertiesWithSameNamesSecondCase() {
targetProperty: 'targetProp',
twoWay: true,
},
- model
+ model,
);
model.item.set('seconds', model.item.seconds + 1);
@@ -1372,7 +1368,7 @@ export function test_Observable_from_nested_json_binds_correctly() {
sourceProperty: 'firstObject.secondObject.dummyProperty',
targetProperty: 'text',
},
- model
+ model,
);
model.get('firstObject').get('secondObject').set('dummyProperty', expectedValue);
@@ -1396,7 +1392,7 @@ export function test_Observable_from_nested_json_binds_correctly_when_upper_obje
sourceProperty: 'firstObject.secondObject.dummyProperty',
targetProperty: 'text',
},
- model
+ model,
);
model.get('firstObject').set('secondObject', fromObject({ dummyProperty: expectedValue }));
diff --git a/apps/automated/src/ui/frame/frame-tests.android.ts b/apps/automated/src/ui/frame/frame-tests.android.ts
index 27a049a890..0a18547250 100644
--- a/apps/automated/src/ui/frame/frame-tests.android.ts
+++ b/apps/automated/src/ui/frame/frame-tests.android.ts
@@ -1,10 +1,7 @@
-import { Frame } from '@nativescript/core/ui/frame';
import * as TKUnit from '../../tk-unit';
-import { unsetValue } from '@nativescript/core/ui/core/view';
-import { PercentLength } from '@nativescript/core/ui/styling/style-properties';
+import { PercentLength, unsetValue, Frame } from '@nativescript/core';
export * from './frame-tests-common';
-
export function test_percent_width_and_height_set_to_page_support() {
let topFrame = Frame.topmost();
let currentPage = topFrame.currentPage;
diff --git a/apps/automated/src/ui/gestures/gestures-tests.ts b/apps/automated/src/ui/gestures/gestures-tests.ts
index 8ab92d7a76..8c82f3d77f 100644
--- a/apps/automated/src/ui/gestures/gestures-tests.ts
+++ b/apps/automated/src/ui/gestures/gestures-tests.ts
@@ -1,14 +1,5 @@
/* tslint:disable:no-unused-variable */
-import { GestureEventData, Label, GestureTypes, PanGestureEventData, PinchGestureEventData, SwipeGestureEventData, RotationGestureEventData } from '@nativescript/core';
-
-export var test_DummyTestForSnippetOnly0 = function () {
- // >> gestures-double-tap
- var label = new Label();
- var observer = label.on(GestureTypes.doubleTap, function (args: GestureEventData) {
- console.log('Double Tap');
- });
- // << gestures-double-tap
-};
+import { GestureEventData, Label, PanGestureEventData, PinchGestureEventData, SwipeGestureEventData, RotationGestureEventData } from '@nativescript/core';
export var test_DummyTestForSnippetOnly01 = function () {
// >> gestures-double-tap-alt
@@ -19,15 +10,6 @@ export var test_DummyTestForSnippetOnly01 = function () {
// << gestures-double-tap-alt
};
-export var test_DummyTestForSnippetOnly1 = function () {
- // >> gestures-long-press
- var label = new Label();
- var observer = label.on(GestureTypes.longPress, function (args: GestureEventData) {
- console.log('Long Press');
- });
- // << gestures-long-press
-};
-
export var test_DummyTestForSnippetOnly11 = function () {
// >> gestures-long-press-alt
var label = new Label();
@@ -37,15 +19,6 @@ export var test_DummyTestForSnippetOnly11 = function () {
// << gestures-long-press-alt
};
-export var test_DummyTestForSnippetOnly2 = function () {
- // >> gestures-pan
- var label = new Label();
- var observer = label.on(GestureTypes.pan, function (args: PanGestureEventData) {
- console.log('Pan deltaX:' + args.deltaX + '; deltaY:' + args.deltaY + ';');
- });
- // << gestures-pan
-};
-
export var test_DummyTestForSnippetOnly22 = function () {
// >> gestures-pan-alt
var label = new Label();
@@ -55,15 +28,6 @@ export var test_DummyTestForSnippetOnly22 = function () {
// << gestures-pan-alt
};
-export var test_DummyTestForSnippetOnly3 = function () {
- // >> gestures-pan-pinch
- var label = new Label();
- var observer = label.on(GestureTypes.pinch, function (args: PinchGestureEventData) {
- console.log('Pinch scale: ' + args.scale);
- });
- // << gestures-pan-pinch
-};
-
export var test_DummyTestForSnippetOnly33 = function () {
// >> gestures-pan-pinch-alt
var label = new Label();
@@ -73,15 +37,6 @@ export var test_DummyTestForSnippetOnly33 = function () {
// << gestures-pan-pinch-alt
};
-export var test_DummyTestForSnippetOnly4 = function () {
- // >> gestures-rotation
- var label = new Label();
- var observer = label.on(GestureTypes.rotation, function (args: RotationGestureEventData) {
- console.log('Rotation: ' + args.rotation);
- });
- // << gestures-rotation
-};
-
export var test_DummyTestForSnippetOnly44 = function () {
// >> gestures-rotation-alt
var label = new Label();
@@ -91,15 +46,6 @@ export var test_DummyTestForSnippetOnly44 = function () {
// << gestures-rotation-alt
};
-export var test_DummyTestForSnippetOnly5 = function () {
- // >> gestures-swipe
- var label = new Label();
- var observer = label.on(GestureTypes.swipe, function (args: SwipeGestureEventData) {
- console.log('Swipe direction: ' + args.direction);
- });
- // << gestures-swipe
-};
-
export var test_DummyTestForSnippetOnly55 = function () {
// >> gestures-swipe-alt
var label = new Label();
@@ -109,15 +55,6 @@ export var test_DummyTestForSnippetOnly55 = function () {
// << gestures-swipe-alt
};
-export var test_DummyTestForSnippetOnly6 = function () {
- // >> gestures-tap
- var label = new Label();
- var observer = label.on(GestureTypes.tap, function (args: GestureEventData) {
- console.log('Tap');
- });
- // << gestures-tap
-};
-
export var test_DummyTestForSnippetOnly66 = function () {
// >> gestures-tap-alt
var label = new Label();
@@ -127,25 +64,6 @@ export var test_DummyTestForSnippetOnly66 = function () {
// << gestures-tap-alt
};
-export var test_DummyTestForSnippetOnly7 = function () {
- // >> gestures-stop-observe
- var label = new Label();
- var observer = label.on(GestureTypes.tap, function (args: GestureEventData) {
- console.log('Tap');
- });
- observer.disconnect();
- // << gestures-stop-observe
-};
-
-export var test_DummyTestForSnippetOnly8 = function () {
- // >> gestures-multiple
- var label = new Label();
- var observer = label.on(GestureTypes.tap | GestureTypes.doubleTap | GestureTypes.longPress, function (args: GestureEventData) {
- console.log('Event: ' + args.eventName);
- });
- // << gestures-multiple
-};
-
export var test_DummyTestForSnippetOnly88 = function () {
// >> gestures-string
var label = new Label();
diff --git a/apps/automated/src/ui/image/image-tests.ts b/apps/automated/src/ui/image/image-tests.ts
index 0ea34140c8..20e129e235 100644
--- a/apps/automated/src/ui/image/image-tests.ts
+++ b/apps/automated/src/ui/image/image-tests.ts
@@ -15,7 +15,7 @@ import { ImageSource } from '@nativescript/core/image-source';
import * as ViewModule from '@nativescript/core/ui/core/view';
import * as helper from '../../ui-helper';
import * as color from '@nativescript/core/color';
-import * as backgroundModule from '@nativescript/core/ui/styling/background';
+import * as appHelpers from '@nativescript/core/application/helpers-common';
import { Application } from '@nativescript/core';
const imagePath = '~/assets/logo.png';
@@ -23,8 +23,8 @@ export function test_recycling() {
helper.nativeView_recycling_test(() => new Image());
}
-if (global.isAndroid) {
- (backgroundModule).initImageCache(Application.android.startActivity, (backgroundModule).CacheMode.memory); // use memory cache only.
+if (__ANDROID__) {
+ appHelpers.initImageCache(Application.android.startActivity, appHelpers.CacheMode.memory); // use memory cache only.
}
export const test_Image_Members = function () {
@@ -63,7 +63,7 @@ function runImageTestSync(image: ImageModule.Image, src: string) {
image.src = src;
- let imageSourceAvailable = global.isIOS ? !!image.imageSource : true;
+ let imageSourceAvailable = __APPLE__ ? !!image.imageSource : true;
TKUnit.assertFalse(image.isLoading, 'Image.isLoading should be false.');
TKUnit.assertTrue(imageSourceAvailable, 'imageSource should be set.');
}
@@ -76,7 +76,7 @@ function runImageTestAsync(image: ImageModule.Image, src: string, done: (e: any)
image.off(IMAGE_LOADED_EVENT, handler);
try {
- let imageSourceAvailable = global.isIOS ? !!image.imageSource : true;
+ let imageSourceAvailable = __APPLE__ ? !!image.imageSource : true;
TKUnit.assertFalse(image.isLoading, 'Image.isLoading should be false.');
TKUnit.assertTrue(imageSourceAvailable, 'imageSource should be set.');
done(null);
@@ -253,7 +253,7 @@ export const test_SettingStretch_none = function () {
};
function ios(func: T): T {
- return global.isIOS ? func : undefined;
+ return __APPLE__ ? func : undefined;
}
export const test_SettingImageSourceWhenSizedToParentDoesNotRequestLayout = ios(() => {
@@ -267,7 +267,11 @@ export const test_SettingImageSourceWhenSizedToParentDoesNotRequestLayout = ios(
let mainPage = helper.getCurrentPage();
mainPage.content = host;
- TKUnit.waitUntilReady(() => host.isLoaded);
+
+ const nativeHostView = host.nativeViewProtected as UIView;
+
+ // Check if native view layer is still marked as dirty before proceeding
+ TKUnit.waitUntilReady(() => host.isLoaded && nativeHostView?.layer && !nativeHostView.layer.needsLayout());
let called = false;
image.requestLayout = () => (called = true);
@@ -285,7 +289,11 @@ export const test_SettingImageSourceWhenFixedWidthAndHeightDoesNotRequestLayout
let mainPage = helper.getCurrentPage();
mainPage.content = host;
- TKUnit.waitUntilReady(() => host.isLoaded);
+
+ const nativeHostView = host.nativeViewProtected as UIView;
+
+ // Check if native view layer is still marked as dirty before proceeding
+ TKUnit.waitUntilReady(() => host.isLoaded && nativeHostView?.layer && !nativeHostView.layer.needsLayout());
let called = false;
image.requestLayout = () => (called = true);
diff --git a/apps/automated/src/ui/label/label-tests-native.android.ts b/apps/automated/src/ui/label/label-tests-native.android.ts
index 426bddf5d3..8437beab29 100644
--- a/apps/automated/src/ui/label/label-tests-native.android.ts
+++ b/apps/automated/src/ui/label/label-tests-native.android.ts
@@ -1,32 +1,32 @@
import * as labelModule from '@nativescript/core/ui/label';
-import { CoreTypes } from '@nativescript/core';
-import * as colorModule from '@nativescript/core/color';
+import { Color, CoreTypes } from '@nativescript/core';
+import { AndroidHelper } from '@nativescript/core/ui/core/view';
+
+const UNEXPECTED_VALUE = 'unexpected value';
export function getNativeTextAlignment(label: labelModule.Label): string {
- let gravity = label.android.getGravity();
+ let hGravity = label.android.getGravity() & android.view.Gravity.HORIZONTAL_GRAVITY_MASK;
+ const alignment = label.android.getTextAlignment();
+
+ if (hGravity === android.view.Gravity.START && alignment === android.view.View.TEXT_ALIGNMENT_VIEW_START) {
+ return 'initial';
+ }
- if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.LEFT) {
+ if (hGravity === android.view.Gravity.LEFT && alignment === android.view.View.TEXT_ALIGNMENT_GRAVITY) {
return CoreTypes.TextAlignment.left;
}
- if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.CENTER_HORIZONTAL) {
+ if (hGravity === android.view.Gravity.CENTER_HORIZONTAL && alignment === android.view.View.TEXT_ALIGNMENT_CENTER) {
return CoreTypes.TextAlignment.center;
}
- if ((gravity & android.view.Gravity.HORIZONTAL_GRAVITY_MASK) === android.view.Gravity.RIGHT) {
+ if (hGravity === android.view.Gravity.RIGHT && alignment === android.view.View.TEXT_ALIGNMENT_GRAVITY) {
return CoreTypes.TextAlignment.right;
}
- return 'unexpected value';
+ return UNEXPECTED_VALUE;
}
-export function getNativeBackgroundColor(label: labelModule.Label): colorModule.Color {
- let bg = label.android.getBackground();
- if (bg instanceof org.nativescript.widgets.BorderDrawable) {
- return new colorModule.Color(bg.getBackgroundColor());
- } else if (bg instanceof android.graphics.drawable.ColorDrawable) {
- return new colorModule.Color(bg.getColor());
- } else {
- return new colorModule.Color(bg.backgroundColor);
- }
+export function getNativeBackgroundColor(label: labelModule.Label): Color {
+ return AndroidHelper.getDrawableColor(label.android.getBackground());
}
diff --git a/apps/automated/src/ui/label/label-tests-native.d.ts b/apps/automated/src/ui/label/label-tests-native.d.ts
index dd7dea90ae..77037e0cf4 100644
--- a/apps/automated/src/ui/label/label-tests-native.d.ts
+++ b/apps/automated/src/ui/label/label-tests-native.d.ts
@@ -3,5 +3,4 @@ import * as labelModule from '@nativescript/core/ui/label';
import * as colorModule from '@nativescript/core/color';
export declare function getNativeTextAlignment(label: labelModule.Label): string;
-
export declare function getNativeBackgroundColor(label: labelModule.Label): colorModule.Color;
diff --git a/apps/automated/src/ui/label/label-tests.ts b/apps/automated/src/ui/label/label-tests.ts
index fd1be0c5bd..9696aca3fe 100644
--- a/apps/automated/src/ui/label/label-tests.ts
+++ b/apps/automated/src/ui/label/label-tests.ts
@@ -1,49 +1,32 @@
import * as TKUnit from '../../tk-unit';
import * as testModule from '../../ui-test';
-
-//>> label-require
-import * as LabelModule from '@nativescript/core/ui/label';
-// << label-require
-
-import * as types from '@nativescript/core/utils/types';
-import * as colorModule from '@nativescript/core/color';
-import * as utils from '@nativescript/core/utils';
-import * as observableModule from '@nativescript/core/data/observable';
-import * as bindable from '@nativescript/core/ui/core/bindable';
-import { CoreTypes, Span, FormattedString } from '@nativescript/core';
+import { Label, GridLayout, LayoutBase, StackLayout, BindingOptions, CoreTypes, Span, FormattedString, Utils, Color, Observable, path } from '@nativescript/core';
import * as labelTestsNative from './label-tests-native';
-import * as fs from '@nativescript/core/file-system';
-
-import { StackLayout } from '@nativescript/core/ui/layouts/stack-layout';
-import { GridLayout } from '@nativescript/core/ui/layouts/grid-layout';
-import { isIOS, isAndroid } from '@nativescript/core/platform';
-import { Label } from '@nativescript/core/ui/label';
-import { LayoutBase } from '@nativescript/core/ui/layouts/layout-base';
import * as helper from '../../ui-helper';
const testDir = 'ui/label';
-export class LabelTest extends testModule.UITest {
- public create(): LabelModule.Label {
- const label = new LabelModule.Label();
+export class LabelTest extends testModule.UITest