Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1f472297a | ||
|
|
030af05839 | ||
|
|
7e8b47d012 | ||
|
|
902aa32dda | ||
|
|
42c0cba7f7 | ||
|
|
f2b84d8d83 | ||
|
|
1b11206174 | ||
|
|
c93e3e9f6f | ||
|
|
9808a0d4d3 | ||
|
|
bd1697dbd2 | ||
|
|
b3b8690bbd | ||
|
|
ad742ec93c | ||
|
|
1de7c38134 | ||
|
|
997943a194 | ||
|
|
47c6048d53 | ||
|
|
a64d459c8e | ||
|
|
a5ad440f17 | ||
|
|
acad24d62a | ||
|
|
989b4cc913 | ||
|
|
38c6627999 | ||
|
|
4b9e18c6b8 | ||
|
|
906f8cc002 | ||
|
|
01ab11644c | ||
|
|
4cf3dcfaae | ||
|
|
b177f84825 | ||
|
|
485e6e0e4d | ||
|
|
516c3411aa | ||
|
|
908354e7fa | ||
|
|
9531dbbc7b | ||
|
|
d10dd1c0b4 | ||
|
|
6533474070 | ||
|
|
576edb53bb | ||
|
|
20e390af85 | ||
|
|
931251a5a8 |
65
.travis.yml
@@ -1,37 +1,48 @@
|
||||
language: android
|
||||
sudo: false
|
||||
|
||||
# NOTE: dist is added here to ensure that Travis CI works consistently
|
||||
# on Node.js 12. It is desired to remove it once this issue is resolved
|
||||
# or otherwise goes away.
|
||||
dist: trusty
|
||||
|
||||
env:
|
||||
global:
|
||||
- ANDROID_API_LEVEL=28
|
||||
- ANDROID_BUILD_TOOLS_VERSION=28.0.3
|
||||
- TERM=dumb # Keep gradle from crapping all over the log
|
||||
matrix:
|
||||
- nodejs_version=6
|
||||
- nodejs_version=8
|
||||
- nodejs_version=10
|
||||
- nodejs_version=12
|
||||
|
||||
language: android
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
- oraclejdk8
|
||||
|
||||
android:
|
||||
components:
|
||||
- build-tools-28.0.3
|
||||
env:
|
||||
global:
|
||||
# Keep gradle from crapping all over the log
|
||||
- TERM=dumb
|
||||
matrix:
|
||||
- nodejs_version=6
|
||||
- nodejs_version=8
|
||||
- nodejs_version=10
|
||||
components:
|
||||
- tools
|
||||
- build-tools-$ANDROID_BUILD_TOOLS_VERSION
|
||||
- android-$ANDROID_API_LEVEL
|
||||
licenses:
|
||||
- 'android-sdk-preview-license-.+'
|
||||
- 'android-sdk-license-.+'
|
||||
- 'google-gdk-license-.+'
|
||||
|
||||
before_install:
|
||||
- nvm install $nodejs_version
|
||||
- node --version
|
||||
- npm --version
|
||||
- gradle --version
|
||||
|
||||
install:
|
||||
# Install a sdkmanager version that supports the --licenses switch and
|
||||
# accept any Android SDK licenses. The output redirection prevents us from
|
||||
# hitting the travis log size limit of 4MB which would fail the build.
|
||||
- yes | sdkmanager tools > /dev/null
|
||||
- yes | sdkmanager --licenses > /dev/null
|
||||
|
||||
- nvm install $nodejs_version
|
||||
- npm install
|
||||
- npm install -g codecov
|
||||
- npm install
|
||||
- npm install -g codecov
|
||||
|
||||
script:
|
||||
- gradle --version
|
||||
- node --version
|
||||
- npm --version
|
||||
- npm test
|
||||
- npm run cover
|
||||
- npm test
|
||||
- npm run cover
|
||||
|
||||
after_script:
|
||||
- codecov
|
||||
- codecov
|
||||
|
||||
@@ -20,6 +20,34 @@
|
||||
-->
|
||||
## Release Notes for Cordova (Android) ##
|
||||
|
||||
### 8.1.0 (Sep 11, 2019)
|
||||
|
||||
* [GH-827](https://github.com/apache/cordova-android/pull/827) chore: bump dependencies for release 8.1.0
|
||||
* [GH-651](https://github.com/apache/cordova-android/pull/651) feat: added multiple selection for filepicker
|
||||
* [GH-672](https://github.com/apache/cordova-android/pull/672) chore: compress files in /res with tinypng.com
|
||||
* [GH-815](https://github.com/apache/cordova-android/pull/815) fix: `clean` command
|
||||
* [GH-750](https://github.com/apache/cordova-android/pull/750) Don't request focus explicitly if not needed
|
||||
* [GH-800](https://github.com/apache/cordova-android/pull/800) [GH-799](https://github.com/apache/cordova-android/pull/799) (android) Stop webview from restarting when activity resizes
|
||||
* [GH-764](https://github.com/apache/cordova-android/pull/764) feat: Build app bundles (.aab files)
|
||||
* [GH-788](https://github.com/apache/cordova-android/pull/788) Simplify `apkSorter` using `compare-func` package
|
||||
* [GH-787](https://github.com/apache/cordova-android/pull/787) Simplify and fix promise handling in specs
|
||||
* [GH-784](https://github.com/apache/cordova-android/pull/784) Properly handle promise in create script
|
||||
* [GH-783](https://github.com/apache/cordova-android/pull/783) Do not clobber process properties with test mocks
|
||||
* [GH-782](https://github.com/apache/cordova-android/pull/782) Do not clobber `console.log` to spy on it
|
||||
* [GH-724](https://github.com/apache/cordova-android/pull/724) Add Node.js 12 to CI Services
|
||||
* [GH-777](https://github.com/apache/cordova-android/pull/777) ci(travis): set `dist: trusty` in `.travis.yml`
|
||||
* [GH-779](https://github.com/apache/cordova-android/pull/779) Consistent order from `ProjectBuilder.apkSorter`
|
||||
* [GH-778](https://github.com/apache/cordova-android/pull/778) test: use verbose spec reporter
|
||||
* [GH-774](https://github.com/apache/cordova-android/pull/774) `rewire` workaround for NodeJS 12
|
||||
* [GH-772](https://github.com/apache/cordova-android/pull/772) `nyc@14` update in devDependencies
|
||||
* [GH-765](https://github.com/apache/cordova-android/pull/765) ci(travis): Fix **Android** SDK
|
||||
* [GH-713](https://github.com/apache/cordova-android/pull/713) Do not explicitly require modules from project directory
|
||||
* [GH-676](https://github.com/apache/cordova-android/pull/676) Added allprojects repositories for Framework Release Builds
|
||||
* [GH-699](https://github.com/apache/cordova-android/pull/699) Improve Gradle Build Arguments
|
||||
* [GH-710](https://github.com/apache/cordova-android/pull/710) Fix deprecation warning in `SystemCookieManager`
|
||||
* [GH-691](https://github.com/apache/cordova-android/pull/691) [GH-690](https://github.com/apache/cordova-android/pull/690): Run `prepare` with the correct `ConfigParser`
|
||||
* [GH-673](https://github.com/apache/cordova-android/pull/673) Updated `Android_HOME` Test to Follow [GH-656](https://github.com/apache/cordova-android/pull/656) Change
|
||||
|
||||
### 8.0.0 (Feb 13, 2019)
|
||||
* [GH-669](https://github.com/apache/cordova-android/pull/669) Added Missing License Headers
|
||||
* [GH-655](https://github.com/apache/cordova-android/pull/655) Use custom Gradle properties to read minSdkVersion value from `config.xml`
|
||||
|
||||
@@ -11,6 +11,7 @@ environment:
|
||||
- nodejs_version: 6
|
||||
- nodejs_version: 8
|
||||
- nodejs_version: 10
|
||||
- nodejs_version: 12
|
||||
|
||||
install:
|
||||
# Install Android SDK Tools
|
||||
|
||||
@@ -142,8 +142,8 @@ function writeProjectProperties (projectPath, target_api) {
|
||||
|
||||
// This makes no sense, what if you're building with a different build system?
|
||||
function prepBuildFiles (projectPath) {
|
||||
var buildModule = require(path.resolve(projectPath, 'cordova/lib/builders/builders'));
|
||||
buildModule.getBuilder().prepBuildFiles();
|
||||
var buildModule = require('../templates/cordova/lib/builders/builders');
|
||||
buildModule.getBuilder(projectPath).prepBuildFiles();
|
||||
}
|
||||
|
||||
function copyBuildRules (projectPath, isLegacy) {
|
||||
@@ -272,7 +272,7 @@ exports.create = function (project_path, config, options, events) {
|
||||
// Make the package conform to Java package types
|
||||
return exports.validatePackageName(package_name)
|
||||
.then(function () {
|
||||
exports.validateProjectName(project_name);
|
||||
return exports.validateProjectName(project_name);
|
||||
}).then(function () {
|
||||
// Log the given values for the project
|
||||
events.emit('log', 'Creating Cordova project for the Android platform:');
|
||||
@@ -321,7 +321,6 @@ exports.create = function (project_path, config, options, events) {
|
||||
|
||||
var manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml'));
|
||||
manifest.setPackageId(package_name)
|
||||
.setTargetSdkVersion(target_api.split('-')[1])
|
||||
.getActivity().setName(safe_activity_name);
|
||||
|
||||
var manifest_path = path.join(app_path, 'AndroidManifest.xml');
|
||||
|
||||
18
bin/templates/cordova/Api.js
vendored
@@ -25,6 +25,7 @@ var PluginManager = require('cordova-common').PluginManager;
|
||||
|
||||
var CordovaLogger = require('cordova-common').CordovaLogger;
|
||||
var selfEvents = require('cordova-common').events;
|
||||
var ConfigParser = require('cordova-common').ConfigParser;
|
||||
|
||||
var PLATFORM = 'android';
|
||||
|
||||
@@ -71,10 +72,7 @@ function Api (platform, platformRootDir, events) {
|
||||
strings: path.join(appRes, 'values', 'strings.xml'),
|
||||
manifest: path.join(appMain, 'AndroidManifest.xml'),
|
||||
build: path.join(this.root, 'build'),
|
||||
javaSrc: path.join(appMain, 'java'),
|
||||
// NOTE: Due to platformApi spec we need to return relative paths here
|
||||
cordovaJs: 'bin/templates/project/assets/www/cordova.js',
|
||||
cordovaJsSrc: 'cordova-js-src'
|
||||
javaSrc: path.join(appMain, 'java')
|
||||
};
|
||||
}
|
||||
|
||||
@@ -101,8 +99,7 @@ Api.createPlatform = function (destination, config, options, events) {
|
||||
var result;
|
||||
try {
|
||||
result = require('../../lib/create').create(destination, config, options, events).then(function (destination) {
|
||||
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
||||
return new PlatformApi(PLATFORM, destination, events);
|
||||
return new Api(PLATFORM, destination, events);
|
||||
});
|
||||
} catch (e) {
|
||||
events.emit('error', 'createPlatform is not callable from the android project API.');
|
||||
@@ -132,8 +129,7 @@ Api.updatePlatform = function (destination, options, events) {
|
||||
var result;
|
||||
try {
|
||||
result = require('../../lib/create').update(destination, options, events).then(function (destination) {
|
||||
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
||||
return new PlatformApi('android', destination, events);
|
||||
return new Api(PLATFORM, destination, events);
|
||||
});
|
||||
} catch (e) {
|
||||
events.emit('error', 'updatePlatform is not callable from the android project API, you will need to do this manually.');
|
||||
@@ -174,6 +170,8 @@ Api.prototype.getPlatformInfo = function () {
|
||||
* CordovaError instance.
|
||||
*/
|
||||
Api.prototype.prepare = function (cordovaProject, prepareOptions) {
|
||||
cordovaProject.projectConfig = new ConfigParser(cordovaProject.locations.rootConfigXml || cordovaProject.projectConfig.path);
|
||||
|
||||
return require('./lib/prepare').prepare.call(this, cordovaProject, prepareOptions);
|
||||
};
|
||||
|
||||
@@ -304,12 +302,12 @@ Api.prototype.build = function (buildOptions) {
|
||||
return require('./lib/build').run.call(self, buildOptions);
|
||||
}).then(function (buildResults) {
|
||||
// Cast build result to array of build artifacts
|
||||
return buildResults.apkPaths.map(function (apkPath) {
|
||||
return buildResults.paths.map(function (apkPath) {
|
||||
return {
|
||||
buildType: buildResults.buildType,
|
||||
buildMethod: buildResults.buildMethod,
|
||||
path: apkPath,
|
||||
type: 'apk'
|
||||
type: path.extname(apkPath).replace(/\./g, '')
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
30
bin/templates/cordova/lib/AndroidManifest.js
vendored
@@ -18,7 +18,6 @@
|
||||
*/
|
||||
|
||||
var fs = require('fs');
|
||||
var et = require('elementtree');
|
||||
var xml = require('cordova-common').xmlHelpers;
|
||||
|
||||
var DEFAULT_ORIENTATION = 'default';
|
||||
@@ -98,31 +97,6 @@ AndroidManifest.prototype.getActivity = function () {
|
||||
};
|
||||
};
|
||||
|
||||
['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion'].forEach(function (sdkPrefName) {
|
||||
// Copy variable reference to avoid closure issues
|
||||
var prefName = sdkPrefName;
|
||||
|
||||
AndroidManifest.prototype['get' + capitalize(prefName)] = function () {
|
||||
var usesSdk = this.doc.getroot().find('./uses-sdk');
|
||||
return usesSdk && usesSdk.attrib['android:' + prefName];
|
||||
};
|
||||
|
||||
AndroidManifest.prototype['set' + capitalize(prefName)] = function (prefValue) {
|
||||
var usesSdk = this.doc.getroot().find('./uses-sdk');
|
||||
|
||||
if (!usesSdk && prefValue) { // if there is no required uses-sdk element, we should create it first
|
||||
usesSdk = new et.Element('uses-sdk');
|
||||
this.doc.getroot().append(usesSdk);
|
||||
}
|
||||
|
||||
if (prefValue) {
|
||||
usesSdk.attrib['android:' + prefName] = prefValue;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
||||
AndroidManifest.prototype.getDebuggable = function () {
|
||||
return this.doc.getroot().find('./application').attrib['android:debuggable'] === 'true';
|
||||
};
|
||||
@@ -150,7 +124,3 @@ AndroidManifest.prototype.write = function (destPath) {
|
||||
};
|
||||
|
||||
module.exports = AndroidManifest;
|
||||
|
||||
function capitalize (str) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
|
||||
25
bin/templates/cordova/lib/PackageType.js
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
const PackageType = {
|
||||
APK: 'apk',
|
||||
BUNDLE: 'bundle'
|
||||
};
|
||||
|
||||
module.exports = PackageType;
|
||||
61
bin/templates/cordova/lib/build.js
vendored
@@ -30,6 +30,7 @@ var builders = require('./builders/builders');
|
||||
var events = require('cordova-common').events;
|
||||
var spawn = require('cordova-common').superspawn.spawn;
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var PackageType = require('./PackageType');
|
||||
|
||||
module.exports.parseBuildOptions = parseOpts;
|
||||
function parseOpts (options, resolvedTarget, projectRoot) {
|
||||
@@ -38,12 +39,15 @@ function parseOpts (options, resolvedTarget, projectRoot) {
|
||||
prepenv: Boolean,
|
||||
versionCode: String,
|
||||
minSdkVersion: String,
|
||||
maxSdkVersion: String,
|
||||
targetSdkVersion: String,
|
||||
gradleArg: [String, Array],
|
||||
keystore: path,
|
||||
alias: String,
|
||||
storePassword: String,
|
||||
password: String,
|
||||
keystoreType: String
|
||||
keystoreType: String,
|
||||
packageType: String
|
||||
}, {}, options.argv, 0);
|
||||
|
||||
// Android Studio Build method is the default
|
||||
@@ -56,6 +60,8 @@ function parseOpts (options, resolvedTarget, projectRoot) {
|
||||
|
||||
if (options.argv.versionCode) { ret.extraArgs.push('-PcdvVersionCode=' + options.argv.versionCode); }
|
||||
if (options.argv.minSdkVersion) { ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion); }
|
||||
if (options.argv.maxSdkVersion) { ret.extraArgs.push('-PcdvMaxSdkVersion=' + options.argv.maxSdkVersion); }
|
||||
if (options.argv.targetSdkVersion) { ret.extraArgs.push('-PcdvTargetSdkVersion=' + options.argv.targetSdkVersion); }
|
||||
if (options.argv.gradleArg) {
|
||||
ret.extraArgs = ret.extraArgs.concat(options.argv.gradleArg);
|
||||
}
|
||||
@@ -64,14 +70,14 @@ function parseOpts (options, resolvedTarget, projectRoot) {
|
||||
|
||||
if (options.argv.keystore) { packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore)); }
|
||||
|
||||
['alias', 'storePassword', 'password', 'keystoreType'].forEach(function (flagName) {
|
||||
['alias', 'storePassword', 'password', 'keystoreType', 'packageType'].forEach(function (flagName) {
|
||||
if (options.argv[flagName]) { packageArgs[flagName] = options.argv[flagName]; }
|
||||
});
|
||||
|
||||
var buildConfig = options.buildConfig;
|
||||
|
||||
// If some values are not specified as command line arguments - use build config to supplement them.
|
||||
// Command line arguemnts have precedence over build config.
|
||||
// Command line arguments have precedence over build config.
|
||||
if (buildConfig) {
|
||||
if (!fs.existsSync(buildConfig)) {
|
||||
throw new Error('Specified build config file does not exist: ' + buildConfig);
|
||||
@@ -89,7 +95,7 @@ function parseOpts (options, resolvedTarget, projectRoot) {
|
||||
events.emit('log', 'Reading the keystore from: ' + packageArgs.keystore);
|
||||
}
|
||||
|
||||
['alias', 'storePassword', 'password', 'keystoreType'].forEach(function (key) {
|
||||
['alias', 'storePassword', 'password', 'keystoreType', 'packageType'].forEach(function (key) {
|
||||
packageArgs[key] = packageArgs[key] || androidInfo[key];
|
||||
});
|
||||
}
|
||||
@@ -101,11 +107,38 @@ function parseOpts (options, resolvedTarget, projectRoot) {
|
||||
}
|
||||
|
||||
if (!ret.packageInfo) {
|
||||
if (Object.keys(packageArgs).length > 0) {
|
||||
// The following loop is to decide whether to print a warning about generating a signed archive
|
||||
// We only want to produce a warning if they are using a config property that is related to signing, but
|
||||
// missing the required properties for signing. We don't want to produce a warning if they are simply
|
||||
// using a build property that isn't related to signing, such as --packageType
|
||||
let shouldWarn = false;
|
||||
const signingKeys = ['keystore', 'alias', 'storePassword', 'password', 'keystoreType'];
|
||||
|
||||
for (let key in packageArgs) {
|
||||
if (!shouldWarn && signingKeys.indexOf(key) > -1) {
|
||||
// If we enter this condition, we have a key used for signing a build,
|
||||
// but we are missing some required signing properties
|
||||
shouldWarn = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldWarn) {
|
||||
events.emit('warn', '\'keystore\' and \'alias\' need to be specified to generate a signed archive.');
|
||||
}
|
||||
}
|
||||
|
||||
if (packageArgs.packageType) {
|
||||
const VALID_PACKAGE_TYPES = [PackageType.APK, PackageType.BUNDLE];
|
||||
if (VALID_PACKAGE_TYPES.indexOf(packageArgs.packageType) === -1) {
|
||||
events.emit('warn', '"' + packageArgs.packageType + '" is an invalid packageType. Valid values are: ' + VALID_PACKAGE_TYPES.join(', ') + '\nDefaulting packageType to ' + PackageType.APK);
|
||||
ret.packageType = PackageType.APK;
|
||||
} else {
|
||||
ret.packageType = packageArgs.packageType;
|
||||
}
|
||||
} else {
|
||||
ret.packageType = PackageType.APK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -144,10 +177,17 @@ module.exports.run = function (options, optResolvedTarget) {
|
||||
return;
|
||||
}
|
||||
return builder.build(opts).then(function () {
|
||||
var apkPaths = builder.findOutputApks(opts.buildType, opts.arch);
|
||||
events.emit('log', 'Built the following apk(s): \n\t' + apkPaths.join('\n\t'));
|
||||
var paths;
|
||||
if (opts.packageType === PackageType.BUNDLE) {
|
||||
paths = builder.findOutputBundles(opts.buildType);
|
||||
events.emit('log', 'Built the following bundle(s): \n\t' + paths.join('\n\t'));
|
||||
} else {
|
||||
paths = builder.findOutputApks(opts.buildType, opts.arch);
|
||||
events.emit('log', 'Built the following apk(s): \n\t' + paths.join('\n\t'));
|
||||
}
|
||||
|
||||
return {
|
||||
apkPaths: apkPaths,
|
||||
paths: paths,
|
||||
buildType: opts.buildType
|
||||
};
|
||||
});
|
||||
@@ -265,8 +305,11 @@ module.exports.help = function () {
|
||||
console.log(' \'--nobuild\': will skip build process (useful when using run command)');
|
||||
console.log(' \'--prepenv\': don\'t build, but copy in build scripts where necessary');
|
||||
console.log(' \'--versionCode=#\': Override versionCode for this build. Useful for uploading multiple APKs.');
|
||||
console.log(' \'--minSdkVersion=#\': Override minSdkVersion for this build. Useful for uploading multiple APKs.');
|
||||
console.log(' \'--minSdkVersion=#\': Override minSdkVersion for this build.');
|
||||
console.log(' \'--maxSdkVersion=#\': Override maxSdkVersion for this build. (Not Recommended)');
|
||||
console.log(' \'--targetSdkVersion=#\': Override targetSdkVersion for this build.');
|
||||
console.log(' \'--gradleArg=<gradle command line arg>\': Extra args to pass to the gradle command. Use one flag per arg. Ex. --gradleArg=-PcdvBuildMultipleApks=true');
|
||||
console.log(' \'--packageType=<apk|bundle>\': Builds an APK or a bundle');
|
||||
console.log('');
|
||||
console.log('Signed APK flags (overwrites debug/release-signing.proprties) :');
|
||||
console.log(' \'--keystore=<path to keystore>\': Key store used to build a signed archive. (Required)');
|
||||
|
||||
106
bin/templates/cordova/lib/builders/ProjectBuilder.js
vendored
@@ -27,6 +27,8 @@ var spawn = require('cordova-common').superspawn.spawn;
|
||||
var events = require('cordova-common').events;
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var check_reqs = require('../check_reqs');
|
||||
var PackageType = require('../PackageType');
|
||||
const compareFunc = require('compare-func');
|
||||
|
||||
const MARKER = 'YOUR CHANGES WILL BE ERASED!';
|
||||
const SIGNING_PROPERTIES = '-signing.properties';
|
||||
@@ -37,24 +39,37 @@ const TEMPLATE =
|
||||
class ProjectBuilder {
|
||||
constructor (rootDirectory) {
|
||||
this.root = rootDirectory || path.resolve(__dirname, '../../..');
|
||||
this.binDir = path.join(this.root, 'app', 'build', 'outputs', 'apk');
|
||||
this.apkDir = path.join(this.root, 'app', 'build', 'outputs', 'apk');
|
||||
this.aabDir = path.join(this.root, 'app', 'build', 'outputs', 'bundle');
|
||||
}
|
||||
|
||||
getArgs (cmd, opts) {
|
||||
if (cmd === 'release') {
|
||||
cmd = 'cdvBuildRelease';
|
||||
} else if (cmd === 'debug') {
|
||||
cmd = 'cdvBuildDebug';
|
||||
let args;
|
||||
let buildCmd = cmd;
|
||||
if (opts.packageType === PackageType.BUNDLE) {
|
||||
if (cmd === 'release') {
|
||||
buildCmd = ':app:bundleRelease';
|
||||
} else if (cmd === 'debug') {
|
||||
buildCmd = ':app:bundleDebug';
|
||||
}
|
||||
|
||||
args = [buildCmd, '-b', path.join(this.root, 'build.gradle')];
|
||||
} else {
|
||||
if (cmd === 'release') {
|
||||
buildCmd = 'cdvBuildRelease';
|
||||
} else if (cmd === 'debug') {
|
||||
buildCmd = 'cdvBuildDebug';
|
||||
}
|
||||
|
||||
args = [buildCmd, '-b', path.join(this.root, 'build.gradle')];
|
||||
|
||||
if (opts.arch) {
|
||||
args.push('-PcdvBuildArch=' + opts.arch);
|
||||
}
|
||||
|
||||
args.push.apply(args, opts.extraArgs);
|
||||
}
|
||||
|
||||
let args = [cmd, '-b', path.join(this.root, 'build.gradle')];
|
||||
|
||||
if (opts.arch) {
|
||||
args.push('-PcdvBuildArch=' + opts.arch);
|
||||
}
|
||||
|
||||
args.push.apply(args, opts.extraArgs);
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
@@ -287,7 +302,11 @@ class ProjectBuilder {
|
||||
}
|
||||
|
||||
findOutputApks (build_type, arch) {
|
||||
return findOutputApksHelper(this.binDir, build_type, arch).sort(apkSorter);
|
||||
return findOutputApksHelper(this.apkDir, build_type, arch).sort(apkSorter);
|
||||
}
|
||||
|
||||
findOutputBundles (build_type) {
|
||||
return findOutputBundlesHelper(this.aabDir, build_type);
|
||||
}
|
||||
|
||||
fetchBuildResults (build_type, arch) {
|
||||
@@ -300,26 +319,19 @@ class ProjectBuilder {
|
||||
|
||||
module.exports = ProjectBuilder;
|
||||
|
||||
function apkSorter (fileA, fileB) {
|
||||
// De-prioritize arch specific builds
|
||||
var archSpecificRE = /-x86|-arm/;
|
||||
if (archSpecificRE.exec(fileA)) {
|
||||
return 1;
|
||||
} else if (archSpecificRE.exec(fileB)) {
|
||||
return -1;
|
||||
}
|
||||
const apkSorter = compareFunc([
|
||||
// Sort arch specific builds after generic ones
|
||||
apkPath => /-x86|-arm/.test(apkPath),
|
||||
|
||||
// De-prioritize unsigned builds
|
||||
var unsignedRE = /-unsigned/;
|
||||
if (unsignedRE.exec(fileA)) {
|
||||
return 1;
|
||||
} else if (unsignedRE.exec(fileB)) {
|
||||
return -1;
|
||||
}
|
||||
// Sort unsigned builds after signed ones
|
||||
apkPath => /-unsigned/.test(apkPath),
|
||||
|
||||
var timeDiff = fs.statSync(fileB).mtime - fs.statSync(fileA).mtime;
|
||||
return timeDiff === 0 ? fileA.length - fileB.length : timeDiff;
|
||||
}
|
||||
// Sort by file modification time, latest first
|
||||
apkPath => -fs.statSync(apkPath).mtime.getTime(),
|
||||
|
||||
// Sort by file name length, ascending
|
||||
'length'
|
||||
]);
|
||||
|
||||
function findOutputApksHelper (dir, build_type, arch) {
|
||||
var shellSilent = shell.config.silent;
|
||||
@@ -365,6 +377,36 @@ function findOutputApksHelper (dir, build_type, arch) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// This method was a copy of findOutputApksHelper and modified to look for bundles
|
||||
// While replacing shell with fs-extra, it might be a good idea to see if we can
|
||||
// generalise these findOutput methods.
|
||||
function findOutputBundlesHelper (dir, build_type) {
|
||||
// This is an unused variable that was copied from findOutputApksHelper
|
||||
// we are pretty sure it was meant to reset shell.config.silent back to
|
||||
// the original value. However shell is planned to be replaced,
|
||||
// it was left as is to avoid unintended consequences.
|
||||
const shellSilent = shell.config.silent;
|
||||
shell.config.silent = true;
|
||||
|
||||
// list directory recursively
|
||||
const ret = shell.ls('-R', dir).map(function (file) {
|
||||
return path.join(dir, file); // ls does not include base directory
|
||||
}).filter(function (file) {
|
||||
return file.match(/\.aab?$/i); // find all bundles
|
||||
}).filter(function (candidate) {
|
||||
// Need to choose between release and debug bundle.
|
||||
if (build_type === 'debug') {
|
||||
return /debug/.exec(candidate);
|
||||
}
|
||||
if (build_type === 'release') {
|
||||
return /release/.exec(candidate);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function isAutoGenerated (file) {
|
||||
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
||||
}
|
||||
|
||||
@@ -24,10 +24,10 @@ const CordovaError = require('cordova-common').CordovaError;
|
||||
*
|
||||
* @return {Builder} A builder instance for specified build type.
|
||||
*/
|
||||
module.exports.getBuilder = function () {
|
||||
module.exports.getBuilder = function (projectPath) {
|
||||
try {
|
||||
const Builder = require('./ProjectBuilder');
|
||||
return new Builder();
|
||||
return new Builder(projectPath);
|
||||
} catch (err) {
|
||||
throw new CordovaError('Failed to instantiate ProjectBuilder builder: ' + err);
|
||||
}
|
||||
|
||||
@@ -84,10 +84,20 @@ class GradlePropertiesParser {
|
||||
let value = this.gradleFile.get(key);
|
||||
|
||||
if (!value) {
|
||||
// Handles the case of adding missing defaults or new properties that are missing.
|
||||
events.emit('verbose', `[Gradle Properties] Appending configuration item: ${key}=${properties[key]}`);
|
||||
this.gradleFile.set(key, properties[key]);
|
||||
} else if (value !== properties[key]) {
|
||||
events.emit('info', `[Gradle Properties] Detected Gradle property "${key}" with the value of "${value}", Cordova's recommended value is "${properties[key]}"`);
|
||||
if (this._defaults[key] && this._defaults[key] !== properties[key]) {
|
||||
// Since the value does not match default, we will notify the discrepancy with Cordova's recommended value.
|
||||
events.emit('info', `[Gradle Properties] Detected Gradle property "${key}" with the value of "${properties[key]}", Cordova's recommended value is "${this._defaults[key]}"`);
|
||||
} else {
|
||||
// When the current value exists but does not match the new value or does matches the default key value, the new value it set.
|
||||
events.emit('verbose', `[Gradle Properties] Updating Gradle property "${key}" with the value of "${properties[key]}"`);
|
||||
}
|
||||
|
||||
// We will set the new value in either case.
|
||||
this.gradleFile.set(key, properties[key]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
7
bin/templates/cordova/lib/prepare.js
vendored
@@ -45,9 +45,13 @@ module.exports.prepare = function (cordovaProject, options) {
|
||||
|
||||
// Get the min SDK version from config.xml
|
||||
const minSdkVersion = this._config.getPreference('android-minSdkVersion', 'android');
|
||||
const maxSdkVersion = this._config.getPreference('android-maxSdkVersion', 'android');
|
||||
const targetSdkVersion = this._config.getPreference('android-targetSdkVersion', 'android');
|
||||
|
||||
let gradlePropertiesUserConfig = {};
|
||||
if (minSdkVersion) gradlePropertiesUserConfig.cdvMinSdkVersion = minSdkVersion;
|
||||
if (maxSdkVersion) gradlePropertiesUserConfig.cdvMaxSdkVersion = maxSdkVersion;
|
||||
if (targetSdkVersion) gradlePropertiesUserConfig.cdvTargetSdkVersion = targetSdkVersion;
|
||||
|
||||
let gradlePropertiesParser = new GradlePropertiesParser(this.locations.root);
|
||||
gradlePropertiesParser.configure(gradlePropertiesUserConfig);
|
||||
@@ -205,9 +209,6 @@ function updateProjectAccordingTo (platformConfig, locations) {
|
||||
manifest.setVersionName(platformConfig.version())
|
||||
.setVersionCode(platformConfig.android_versionCode() || default_versionCode(platformConfig.version()))
|
||||
.setPackageId(androidPkgName)
|
||||
.setMinSdkVersion(platformConfig.getPreference('android-minSdkVersion', 'android'))
|
||||
.setMaxSdkVersion(platformConfig.getPreference('android-maxSdkVersion', 'android'))
|
||||
.setTargetSdkVersion(platformConfig.getPreference('android-targetSdkVersion', 'android'))
|
||||
.write();
|
||||
|
||||
// Java file paths shouldn't be hard coded
|
||||
|
||||
9
bin/templates/cordova/lib/run.js
vendored
@@ -23,6 +23,7 @@ var path = require('path');
|
||||
var emulator = require('./emulator');
|
||||
var device = require('./device');
|
||||
var Q = require('q');
|
||||
var PackageType = require('./PackageType');
|
||||
var events = require('cordova-common').events;
|
||||
|
||||
function getInstallTarget (runOptions) {
|
||||
@@ -104,6 +105,14 @@ module.exports.run = function (runOptions) {
|
||||
return new Promise((resolve) => {
|
||||
const builder = require('./builders/builders').getBuilder();
|
||||
const buildOptions = require('./build').parseBuildOptions(runOptions, null, self.root);
|
||||
|
||||
// Android app bundles cannot be deployed directly to the device
|
||||
if (buildOptions.packageType === PackageType.BUNDLE) {
|
||||
const packageTypeErrorMessage = 'Package type "bundle" is not supported during cordova run.';
|
||||
events.emit('error', packageTypeErrorMessage);
|
||||
throw packageTypeErrorMessage;
|
||||
}
|
||||
|
||||
resolve(builder.fetchBuildResults(buildOptions.buildType, buildOptions.arch));
|
||||
}).then(function (buildResults) {
|
||||
if (resolvedTarget && resolvedTarget.isEmulator) {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
// Coho updates this line:
|
||||
var VERSION = "8.0.0";
|
||||
var VERSION = "8.1.0";
|
||||
|
||||
module.exports.version = VERSION;
|
||||
|
||||
|
||||
@@ -37,13 +37,11 @@
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale">
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode">
|
||||
<intent-filter android:label="@string/launcher_name">
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="__APILEVEL__"/>
|
||||
</manifest>
|
||||
|
||||
@@ -64,6 +64,14 @@ ext {
|
||||
if (!project.hasProperty('cdvMinSdkVersion')) {
|
||||
cdvMinSdkVersion = null
|
||||
}
|
||||
// Sets the maxSdkVersion to the given value.
|
||||
if (!project.hasProperty('cdvMaxSdkVersion')) {
|
||||
cdvMaxSdkVersion = null
|
||||
}
|
||||
// The value for android.targetSdkVersion.
|
||||
if (!project.hasProperty('cdvTargetSdkVersion')) {
|
||||
cdvTargetSdkVersion = null;
|
||||
}
|
||||
// Whether to build architecture-specific APKs.
|
||||
if (!project.hasProperty('cdvBuildMultipleApks')) {
|
||||
cdvBuildMultipleApks = null
|
||||
@@ -103,10 +111,12 @@ if (hasBuildExtras2) {
|
||||
}
|
||||
|
||||
// Set property defaults after extension .gradle files.
|
||||
if (ext.cdvCompileSdkVersion == null) {
|
||||
ext.cdvCompileSdkVersion = privateHelpers.getProjectTarget()
|
||||
//ext.cdvCompileSdkVersion = project.ext.defaultCompileSdkVersion
|
||||
}
|
||||
ext.cdvCompileSdkVersion = cdvCompileSdkVersion == null ? (
|
||||
defaultCompileSdkVersion == null
|
||||
? privateHelpers.getProjectTarget()
|
||||
: defaultCompileSdkVersion
|
||||
) : Integer.parseInt('' + cdvCompileSdkVersion);
|
||||
|
||||
if (ext.cdvBuildToolsVersion == null) {
|
||||
ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
|
||||
//ext.cdvBuildToolsVersion = project.ext.defaultBuildToolsVersion
|
||||
@@ -121,7 +131,14 @@ if (ext.cdvReleaseSigningPropertiesFile == null && file('../release-signing.prop
|
||||
// Cast to appropriate types.
|
||||
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
|
||||
ext.cdvVersionCodeForceAbiDigit = cdvVersionCodeForceAbiDigit == null ? false : cdvVersionCodeForceAbiDigit.toBoolean();
|
||||
|
||||
// minSdkVersion, maxSdkVersion and targetSdkVersion
|
||||
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? defaultMinSdkVersion : Integer.parseInt('' + cdvMinSdkVersion)
|
||||
if (cdvMaxSdkVersion != null) {
|
||||
ext.cdvMaxSdkVersion = Integer.parseInt('' + cdvMaxSdkVersion)
|
||||
}
|
||||
ext.cdvTargetSdkVersion = cdvTargetSdkVersion == null ? defaultTargetSdkVersion : Integer.parseInt('' + cdvTargetSdkVersion)
|
||||
|
||||
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
|
||||
|
||||
def computeBuildTargetName(debugBuild) {
|
||||
@@ -151,6 +168,8 @@ task cdvPrintProps {
|
||||
println('cdvVersionCode=' + cdvVersionCode)
|
||||
println('cdvVersionCodeForceAbiDigit=' + cdvVersionCodeForceAbiDigit)
|
||||
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
|
||||
println('cdvMaxSdkVersion=' + cdvMaxSdkVersion)
|
||||
println('cdvTargetSdkVersion=' + cdvTargetSdkVersion)
|
||||
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
|
||||
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
|
||||
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
|
||||
@@ -170,6 +189,14 @@ android {
|
||||
if (cdvMinSdkVersion != null) {
|
||||
minSdkVersion cdvMinSdkVersion
|
||||
}
|
||||
|
||||
if (cdvMaxSdkVersion != null) {
|
||||
maxSdkVersion cdvMaxSdkVersion
|
||||
}
|
||||
|
||||
if(cdvTargetSdkVersion != null) {
|
||||
targetSdkVersion cdvTargetSdkVersion
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
|
||||
59
bin/templates/project/assets/www/cordova.js
vendored
@@ -1,5 +1,5 @@
|
||||
// Platform: android
|
||||
// 882658ab17740dbdece764e68c1f1f1f44fe3f9d
|
||||
// 74fdba8b327b2a13b4366dd141b52def96d4cb56
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
@@ -8,9 +8,9 @@
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@@ -19,9 +19,8 @@
|
||||
under the License.
|
||||
*/
|
||||
;(function() {
|
||||
var PLATFORM_VERSION_BUILD_LABEL = '8.0.0';
|
||||
var PLATFORM_VERSION_BUILD_LABEL = '8.1.0';
|
||||
// file: src/scripts/require.js
|
||||
|
||||
var require;
|
||||
var define;
|
||||
|
||||
@@ -70,7 +69,7 @@ var define;
|
||||
};
|
||||
|
||||
define = function (id, factory) {
|
||||
if (modules[id]) {
|
||||
if (Object.prototype.hasOwnProperty.call(modules, id)) {
|
||||
throw 'module ' + id + ' already defined';
|
||||
}
|
||||
|
||||
@@ -205,8 +204,8 @@ var cordova = {
|
||||
* @return object
|
||||
*/
|
||||
getOriginalHandlers: function () {
|
||||
return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
|
||||
'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
|
||||
return { 'document': { 'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener },
|
||||
'window': { 'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener } };
|
||||
},
|
||||
/**
|
||||
* Method to fire event from native code
|
||||
@@ -324,7 +323,7 @@ module.exports = cordova;
|
||||
|
||||
});
|
||||
|
||||
// file: /Users/erisu/git/apache/cordova/cordova-android/cordova-js-src/android/nativeapiprovider.js
|
||||
// file: ../cordova-android/cordova-js-src/android/nativeapiprovider.js
|
||||
define("cordova/android/nativeapiprovider", function(require, exports, module) {
|
||||
|
||||
/**
|
||||
@@ -347,7 +346,7 @@ module.exports = {
|
||||
|
||||
});
|
||||
|
||||
// file: /Users/erisu/git/apache/cordova/cordova-android/cordova-js-src/android/promptbasednativeapi.js
|
||||
// file: ../cordova-android/cordova-js-src/android/promptbasednativeapi.js
|
||||
define("cordova/android/promptbasednativeapi", function(require, exports, module) {
|
||||
|
||||
/**
|
||||
@@ -386,9 +385,38 @@ var typeMap = {
|
||||
};
|
||||
|
||||
function extractParamName (callee, argIndex) {
|
||||
return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
|
||||
return (/\(\s*([^)]*?)\s*\)/).exec(callee)[1].split(/\s*,\s*/)[argIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given arguments' types and throws if they are not as expected.
|
||||
*
|
||||
* `spec` is a string where each character stands for the required type of the
|
||||
* argument at the same position. In other words: the character at `spec[i]`
|
||||
* specifies the required type for `args[i]`. The characters in `spec` are the
|
||||
* first letter of the required type's name. The supported types are:
|
||||
*
|
||||
* Array, Date, Number, String, Function, Object
|
||||
*
|
||||
* Lowercase characters specify arguments that must not be `null` or `undefined`
|
||||
* while uppercase characters allow those values to be passed.
|
||||
*
|
||||
* Finally, `*` can be used to allow any type at the corresponding position.
|
||||
*
|
||||
* @example
|
||||
* function foo (arr, opts) {
|
||||
* // require `arr` to be an Array and `opts` an Object, null or undefined
|
||||
* checkArgs('aO', 'my.package.foo', arguments);
|
||||
* // ...
|
||||
* }
|
||||
* @param {String} spec - the type specification for `args` as described above
|
||||
* @param {String} functionName - full name of the callee.
|
||||
* Used in the error message
|
||||
* @param {Array|arguments} args - the arguments to be checked against `spec`
|
||||
* @param {Function} [opt_callee=args.callee] - the recipient of `args`.
|
||||
* Used to extract parameter names for the error message
|
||||
* @throws {TypeError} if args do not satisfy spec
|
||||
*/
|
||||
function checkArgs (spec, functionName, args, opt_callee) {
|
||||
if (!moduleExports.enableChecks) {
|
||||
return;
|
||||
@@ -879,7 +907,7 @@ module.exports = channel;
|
||||
|
||||
});
|
||||
|
||||
// file: /Users/erisu/git/apache/cordova/cordova-android/cordova-js-src/exec.js
|
||||
// file: ../cordova-android/cordova-js-src/exec.js
|
||||
define("cordova/exec", function(require, exports, module) {
|
||||
|
||||
/**
|
||||
@@ -1406,7 +1434,7 @@ exports.reset();
|
||||
|
||||
});
|
||||
|
||||
// file: /Users/erisu/git/apache/cordova/cordova-android/cordova-js-src/platform.js
|
||||
// file: ../cordova-android/cordova-js-src/platform.js
|
||||
define("cordova/platform", function(require, exports, module) {
|
||||
|
||||
// The last resume event that was received that had the result of a plugin call.
|
||||
@@ -1516,7 +1544,7 @@ function onMessageFromNative(msg) {
|
||||
|
||||
});
|
||||
|
||||
// file: /Users/erisu/git/apache/cordova/cordova-android/cordova-js-src/plugin/android/app.js
|
||||
// file: ../cordova-android/cordova-js-src/plugin/android/app.js
|
||||
define("cordova/plugin/android/app", function(require, exports, module) {
|
||||
|
||||
var exec = require('cordova/exec');
|
||||
@@ -1902,7 +1930,6 @@ utils.alert = function (msg) {
|
||||
|
||||
window.cordova = require('cordova');
|
||||
// file: src/scripts/bootstrap.js
|
||||
|
||||
require('cordova/init');
|
||||
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -66,6 +66,14 @@ ext {
|
||||
if (!project.hasProperty('cdvMinSdkVersion')) {
|
||||
cdvMinSdkVersion = null
|
||||
}
|
||||
// Sets the maxSdkVersion to the given value.
|
||||
if (!project.hasProperty('cdvMaxSdkVersion')) {
|
||||
cdvMaxSdkVersion = null
|
||||
}
|
||||
// The value for android.targetSdkVersion.
|
||||
if (!project.hasProperty('cdvTargetSdkVersion')) {
|
||||
cdvTargetSdkVersion = null;
|
||||
}
|
||||
// Whether to build architecture-specific APKs.
|
||||
if (!project.hasProperty('cdvBuildMultipleApks')) {
|
||||
cdvBuildMultipleApks = null
|
||||
@@ -112,6 +120,11 @@ if (ext.cdvReleaseSigningPropertiesFile == null && file('release-signing.propert
|
||||
// Cast to appropriate types.
|
||||
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
|
||||
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : Integer.parseInt('' + cdvMinSdkVersion)
|
||||
|
||||
if(cdvMaxSdkVersion != null) {
|
||||
ext.cdvMaxSdkVersion = Integer.parseInt('' + cdvMaxSdkVersion)
|
||||
}
|
||||
|
||||
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
|
||||
|
||||
def computeBuildTargetName(debugBuild) {
|
||||
@@ -139,6 +152,8 @@ task cdvPrintProps << {
|
||||
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
|
||||
println('cdvVersionCode=' + cdvVersionCode)
|
||||
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
|
||||
println('cdvMaxSdkVersion=' + cdvMaxSdkVersion)
|
||||
println('cdvTargetSdkVersion=' + cdvTargetSdkVersion)
|
||||
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
|
||||
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
|
||||
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
|
||||
@@ -170,6 +185,14 @@ android {
|
||||
if (cdvMinSdkVersion != null) {
|
||||
minSdkVersion cdvMinSdkVersion
|
||||
}
|
||||
|
||||
if (cdvMaxSdkVersion != null) {
|
||||
maxSdkVersion cdvMaxSdkVersion
|
||||
}
|
||||
|
||||
if(cdvTargetSdkVersion != null) {
|
||||
targetSdkVersion cdvTargetSdkVersion
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
|
||||
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 286 KiB After Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 207 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 292 KiB After Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 86 B |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 83 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 84 B |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 688 B After Width: | Height: | Size: 113 B |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 121 B |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 131 B |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 5.9 KiB |
@@ -19,5 +19,4 @@
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.apache.cordova" android:versionName="1.0" android:versionCode="1">
|
||||
<uses-sdk android:minSdkVersion="19" />
|
||||
</manifest>
|
||||
|
||||
@@ -37,12 +37,19 @@ buildscript {
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'com.github.dcendents.android-maven'
|
||||
apply plugin: 'com.jfrog.bintray'
|
||||
|
||||
group = 'org.apache.cordova'
|
||||
version = '8.0.0'
|
||||
version = '8.1.0'
|
||||
|
||||
android {
|
||||
compileSdkVersion cdvCompileSdkVersion
|
||||
@@ -53,6 +60,11 @@ android {
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
// For the Android Cordova Lib, we will hardcode the minSdkVersion and not allow changes.
|
||||
defaultConfig {
|
||||
minSdkVersion 19
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
@@ -128,9 +140,9 @@ bintray {
|
||||
licenses = ['Apache-2.0']
|
||||
labels = ['android', 'cordova', 'phonegap']
|
||||
version {
|
||||
name = '8.0.0'
|
||||
name = '8.1.0'
|
||||
released = new Date()
|
||||
vcsTag = '8.0.0'
|
||||
vcsTag = '8.1.0'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,9 +268,11 @@ public class CordovaActivity extends Activity {
|
||||
if (this.appView == null) {
|
||||
return;
|
||||
}
|
||||
// Force window to have focus, so application always
|
||||
// receive user input. Workaround for some devices (Samsung Galaxy Note 3 at least)
|
||||
this.getWindow().getDecorView().requestFocus();
|
||||
if (! this.getWindow().getDecorView().hasFocus()) {
|
||||
// Force window to have focus, so application always
|
||||
// receive user input. Workaround for some devices (Samsung Galaxy Note 3 at least)
|
||||
this.getWindow().getDecorView().requestFocus();
|
||||
}
|
||||
|
||||
this.appView.handleResume(this.keepRunning);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import android.webkit.WebChromeClient.CustomViewCallback;
|
||||
* are not expected to implement it.
|
||||
*/
|
||||
public interface CordovaWebView {
|
||||
public static final String CORDOVA_VERSION = "8.0.0";
|
||||
public static final String CORDOVA_VERSION = "8.1.0";
|
||||
|
||||
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences);
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ class SystemCookieManager implements ICordovaCookieManager {
|
||||
return cookieManager.getCookie(url);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void clearCookies() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
cookieManager.removeAllCookies(null);
|
||||
|
||||
@@ -250,13 +250,34 @@ public class SystemWebChromeClient extends WebChromeClient {
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public boolean onShowFileChooser(WebView webView, final ValueCallback<Uri[]> filePathsCallback, final WebChromeClient.FileChooserParams fileChooserParams) {
|
||||
// Check if multiple-select is specified
|
||||
Boolean selectMultiple = false;
|
||||
if (fileChooserParams.getMode() == WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE) {
|
||||
selectMultiple = true;
|
||||
}
|
||||
Intent intent = fileChooserParams.createIntent();
|
||||
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, selectMultiple);
|
||||
try {
|
||||
parentEngine.cordova.startActivityForResult(new CordovaPlugin() {
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||
Uri[] result = WebChromeClient.FileChooserParams.parseResult(resultCode, intent);
|
||||
LOG.d(LOG_TAG, "Receive file chooser URL: " + result);
|
||||
Uri[] result = null;
|
||||
if (resultCode == Activity.RESULT_OK && intent != null) {
|
||||
if (intent.getClipData() != null) {
|
||||
// handle multiple-selected files
|
||||
final int numSelectedFiles = intent.getClipData().getItemCount();
|
||||
result = new Uri[numSelectedFiles];
|
||||
for (int i = 0; i < numSelectedFiles; i++) {
|
||||
result[i] = intent.getClipData().getItemAt(i).getUri();
|
||||
LOG.d(LOG_TAG, "Receive file chooser URL: " + result[i]);
|
||||
}
|
||||
}
|
||||
else if (intent.getData() != null) {
|
||||
// handle single-selected file
|
||||
result = WebChromeClient.FileChooserParams.parseResult(resultCode, intent);
|
||||
LOG.d(LOG_TAG, "Receive file chooser URL: " + result);
|
||||
}
|
||||
}
|
||||
filePathsCallback.onReceiveValue(result);
|
||||
}
|
||||
}, intent, FILECHOOSER_RESULTCODE);
|
||||
|
||||
13
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cordova-android",
|
||||
"version": "8.0.0",
|
||||
"version": "8.1.0",
|
||||
"description": "cordova-android release",
|
||||
"bin": {
|
||||
"create": "bin/create"
|
||||
@@ -29,12 +29,12 @@
|
||||
"author": "Apache Software Foundation",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"android-versions": "^1.3.0",
|
||||
"cordova-common": "^3.1.0",
|
||||
"elementtree": "^0.1.7",
|
||||
"android-versions": "^1.4.0",
|
||||
"compare-func": "^1.3.2",
|
||||
"cordova-common": "^3.2.0",
|
||||
"nopt": "^4.0.1",
|
||||
"properties-parser": "^0.3.1",
|
||||
"q": "^1.4.1",
|
||||
"q": "^1.5.1",
|
||||
"shelljs": "^0.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -46,7 +46,8 @@
|
||||
"eslint-plugin-promise": "^4.0.1",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"jasmine": "^3.3.1",
|
||||
"nyc": "^13.1.0",
|
||||
"jasmine-spec-reporter": "^4.2.1",
|
||||
"nyc": "^14.1.1",
|
||||
"rewire": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
"unit/**/*[sS]pec.js",
|
||||
"e2e/**/*[sS]pec.js"
|
||||
],
|
||||
"helpers": [
|
||||
"helper.js"
|
||||
],
|
||||
"stopSpecOnExpectationFailure": false,
|
||||
"random": false
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
"spec_files": [
|
||||
"e2e/**/*[sS]pec.js"
|
||||
],
|
||||
"helpers": [
|
||||
"helper.js"
|
||||
],
|
||||
"stopSpecOnExpectationFailure": false,
|
||||
"random": false
|
||||
}
|
||||
|
||||
31
spec/helper.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
const SpecReporter = require('jasmine-spec-reporter').SpecReporter;
|
||||
|
||||
jasmine.getEnv().clearReporters();
|
||||
jasmine.getEnv().addReporter(new SpecReporter({
|
||||
spec: {
|
||||
displayPending: true,
|
||||
displayDuration: true
|
||||
},
|
||||
summary: {
|
||||
displayDuration: true,
|
||||
displayStacktrace: true
|
||||
}
|
||||
}));
|
||||
@@ -29,9 +29,6 @@ describe('AndroidManifest', () => {
|
||||
const ACTIVITY_LAUNCH_MODE = 'singleTop';
|
||||
const ACTIVITY_NAME = 'MainActivity';
|
||||
const ACTIVITY_ORIENTATION = 'portrait';
|
||||
const MIN_SDK_VERSION = '12';
|
||||
const MAX_SDK_VERSION = '88';
|
||||
const TARGET_SDK_VERSION = '27';
|
||||
|
||||
const DEFAULT_MANIFEST = `<?xml version='1.0' encoding='utf-8'?>
|
||||
<manifest android:hardwareAccelerated="true" android:versionCode="${VERSION_CODE}" android:versionName="${VERSION_NAME}"
|
||||
@@ -51,7 +48,6 @@ describe('AndroidManifest', () => {
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
<uses-sdk android:minSdkVersion="${MIN_SDK_VERSION}" android:maxSdkVersion="${MAX_SDK_VERSION}" android:targetSdkVersion="${TARGET_SDK_VERSION}" />
|
||||
</manifest>`;
|
||||
|
||||
const manifestPath = path.join(os.tmpdir(), `AndroidManifest${Date.now()}.xml`);
|
||||
@@ -190,78 +186,6 @@ describe('AndroidManifest', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('minSdkVersion', () => {
|
||||
it('should get minSdkVersion', () => {
|
||||
expect(manifest.getMinSdkVersion()).toBe(MIN_SDK_VERSION);
|
||||
});
|
||||
|
||||
it('should set minSdkVersion', () => {
|
||||
const newMinSdkVersion = `${MIN_SDK_VERSION}111`;
|
||||
manifest.setMinSdkVersion(newMinSdkVersion);
|
||||
expect(manifest.getMinSdkVersion()).toBe(newMinSdkVersion);
|
||||
});
|
||||
|
||||
it('should create the uses-sdk node if it does not exist when setting minSdkVersion', () => {
|
||||
const root = manifest.doc.getroot();
|
||||
root.remove(root.find('./uses-sdk'));
|
||||
|
||||
expect(root.find('./uses-sdk')).toBe(null);
|
||||
|
||||
manifest.setMinSdkVersion(1);
|
||||
|
||||
expect(root.find('./uses-sdk')).not.toBe(null);
|
||||
expect(manifest.getMinSdkVersion()).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('maxSdkVersion', () => {
|
||||
it('should get maxSdkVersion', () => {
|
||||
expect(manifest.getMaxSdkVersion()).toBe(MAX_SDK_VERSION);
|
||||
});
|
||||
|
||||
it('should set maxSdkVersion', () => {
|
||||
const newMaxSdkVersion = `${MAX_SDK_VERSION}999`;
|
||||
manifest.setMaxSdkVersion(newMaxSdkVersion);
|
||||
expect(manifest.getMaxSdkVersion()).toBe(newMaxSdkVersion);
|
||||
});
|
||||
|
||||
it('should create the uses-sdk node if it does not exist when setting maxSdkVersion', () => {
|
||||
const root = manifest.doc.getroot();
|
||||
root.remove(root.find('./uses-sdk'));
|
||||
|
||||
expect(root.find('./uses-sdk')).toBe(null);
|
||||
|
||||
manifest.setMaxSdkVersion(1);
|
||||
|
||||
expect(root.find('./uses-sdk')).not.toBe(null);
|
||||
expect(manifest.getMaxSdkVersion()).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('targetSdkVersion', () => {
|
||||
it('should get targetSdkVersion', () => {
|
||||
expect(manifest.getTargetSdkVersion()).toBe(TARGET_SDK_VERSION);
|
||||
});
|
||||
|
||||
it('should set targetSdkVersion', () => {
|
||||
const newTargetSdkVersion = `${TARGET_SDK_VERSION}555`;
|
||||
manifest.setTargetSdkVersion(newTargetSdkVersion);
|
||||
expect(manifest.getTargetSdkVersion()).toBe(newTargetSdkVersion);
|
||||
});
|
||||
|
||||
it('should create the uses-sdk node if it does not exist when setting targetSdkVersion', () => {
|
||||
const root = manifest.doc.getroot();
|
||||
root.remove(root.find('./uses-sdk'));
|
||||
|
||||
expect(root.find('./uses-sdk')).toBe(null);
|
||||
|
||||
manifest.setTargetSdkVersion(1);
|
||||
|
||||
expect(root.find('./uses-sdk')).not.toBe(null);
|
||||
expect(manifest.getTargetSdkVersion()).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('debuggable', () => {
|
||||
it('should get debuggable', () => {
|
||||
expect(manifest.getDebuggable()).toBe(true);
|
||||
|
||||
@@ -32,7 +32,7 @@ var FIXTURES = path.join(__dirname, '../e2e/fixtures');
|
||||
var FAKE_PROJECT_DIR = path.join(os.tmpdir(), 'plugin-test-project');
|
||||
|
||||
describe('addPlugin method', function () {
|
||||
var api, Api, fail, gradleBuilder;
|
||||
var api, Api, gradleBuilder;
|
||||
|
||||
beforeEach(function () {
|
||||
Api = rewire('../../bin/templates/cordova/Api');
|
||||
@@ -51,24 +51,21 @@ describe('addPlugin method', function () {
|
||||
|
||||
api = new Api('android', FAKE_PROJECT_DIR);
|
||||
|
||||
fail = jasmine.createSpy('fail');
|
||||
gradleBuilder = jasmine.createSpyObj('gradleBuilder', ['prepBuildFiles']);
|
||||
spyOn(builders, 'getBuilder').and.returnValue(gradleBuilder);
|
||||
});
|
||||
|
||||
it('Test#001 : should call gradleBuilder.prepBuildFiles for every plugin with frameworks', function (done) {
|
||||
api.addPlugin(new PluginInfo(path.join(FIXTURES, 'cordova-plugin-fake'))).catch(fail).fin(function () {
|
||||
expect(fail).not.toHaveBeenCalled();
|
||||
const getPluginFixture = name => new PluginInfo(path.join(FIXTURES, name));
|
||||
|
||||
it('Test#001 : should call gradleBuilder.prepBuildFiles for every plugin with frameworks', () => {
|
||||
return api.addPlugin(getPluginFixture('cordova-plugin-fake')).then(() => {
|
||||
expect(gradleBuilder.prepBuildFiles).toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Test#002 : shouldn\'t trigger gradleBuilder.prepBuildFiles for plugins without android frameworks', function (done) {
|
||||
api.addPlugin(new PluginInfo(path.join(FIXTURES, 'cordova-plugin-fake-ios-frameworks'))).catch(fail).fin(function () {
|
||||
expect(fail).not.toHaveBeenCalled();
|
||||
it('Test#002 : shouldn\'t trigger gradleBuilder.prepBuildFiles for plugins without android frameworks', () => {
|
||||
return api.addPlugin(getPluginFixture('cordova-plugin-fake-ios-frameworks')).then(() => {
|
||||
expect(gradleBuilder.prepBuildFiles).not.toHaveBeenCalled();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,16 +45,14 @@ describe('android_sdk', () => {
|
||||
describe('print_newest_available_sdk_target', () => {
|
||||
it('should log the newest version', () => {
|
||||
const sortedIds = ['android-27', 'android-24', 'android-23', 'android-19'];
|
||||
const logSpy = jasmine.createSpy('log');
|
||||
|
||||
spyOn(android_sdk, 'list_targets').and.returnValue(Promise.resolve(sortedIds));
|
||||
spyOn(sortedIds, 'sort');
|
||||
|
||||
android_sdk.__set__({ console: { log: logSpy } });
|
||||
spyOn(console, 'log');
|
||||
|
||||
return android_sdk.print_newest_available_sdk_target().then(() => {
|
||||
expect(sortedIds.sort).toHaveBeenCalledWith(android_sdk.__get__('sort_by_largest_numerical_suffix'));
|
||||
expect(logSpy).toHaveBeenCalledWith(sortedIds[0]);
|
||||
expect(console.log).toHaveBeenCalledWith(sortedIds[0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -66,12 +66,54 @@ describe('ProjectBuilder', () => {
|
||||
expect(args[0]).toBe('cdvBuildDebug');
|
||||
});
|
||||
|
||||
it('should set apk release', () => {
|
||||
const args = builder.getArgs('release', {
|
||||
packageType: 'apk'
|
||||
});
|
||||
expect(args[0]).withContext(args).toBe('cdvBuildRelease');
|
||||
});
|
||||
|
||||
it('should set apk debug', () => {
|
||||
const args = builder.getArgs('debug', {
|
||||
packageType: 'apk'
|
||||
});
|
||||
expect(args[0]).withContext(args).toBe('cdvBuildDebug');
|
||||
});
|
||||
|
||||
it('should set bundle release', () => {
|
||||
const args = builder.getArgs('release', {
|
||||
packageType: 'bundle'
|
||||
});
|
||||
expect(args[0]).withContext(args).toBe(':app:bundleRelease');
|
||||
});
|
||||
|
||||
it('should set bundle debug', () => {
|
||||
const args = builder.getArgs('debug', {
|
||||
packageType: 'bundle'
|
||||
});
|
||||
expect(args[0]).withContext(args).toBe(':app:bundleDebug');
|
||||
});
|
||||
|
||||
it('should add architecture if it is passed', () => {
|
||||
const arch = 'unittest';
|
||||
const args = builder.getArgs('debug', { arch });
|
||||
|
||||
expect(args).toContain(`-PcdvBuildArch=${arch}`);
|
||||
});
|
||||
|
||||
it('should clean apk', () => {
|
||||
const args = builder.getArgs('clean', {
|
||||
packageType: 'apk'
|
||||
});
|
||||
expect(args[0]).toBe('clean');
|
||||
});
|
||||
|
||||
it('should clean bundle', () => {
|
||||
const args = builder.getArgs('clean', {
|
||||
packageType: 'bundle'
|
||||
});
|
||||
expect(args[0]).toBe('clean');
|
||||
});
|
||||
});
|
||||
|
||||
describe('runGradleWrapper', () => {
|
||||
@@ -248,11 +290,11 @@ describe('ProjectBuilder', () => {
|
||||
};
|
||||
|
||||
const expectedResult = ['app-release.apk', 'app-debug.apk', 'app-release-unsigned.apk',
|
||||
'app-release-arm.apk', 'app-debug-arm.apk', 'app-release-x86.apk', 'app-debug-x86.apk'];
|
||||
'app-release-arm.apk', 'app-release-x86.apk', 'app-debug-x86.apk', 'app-debug-arm.apk'];
|
||||
|
||||
const fsSpy = jasmine.createSpyObj('fs', ['statSync']);
|
||||
fsSpy.statSync.and.callFake(filename => {
|
||||
return { mtime: APKs[filename].getTime() };
|
||||
return { mtime: APKs[filename] };
|
||||
});
|
||||
ProjectBuilder.__set__('fs', fsSpy);
|
||||
|
||||
|
||||
@@ -35,42 +35,35 @@ describe('check_reqs', function () {
|
||||
});
|
||||
});
|
||||
describe('check_android', function () {
|
||||
describe('set ANDROID_HOME if not set', function () {
|
||||
describe('find and set ANDROID_HOME when ANDROID_HOME and ANDROID_SDK_ROOT is not set', function () {
|
||||
beforeEach(function () {
|
||||
delete process.env.ANDROID_HOME;
|
||||
delete process.env.ANDROID_SDK_ROOT;
|
||||
});
|
||||
describe('even if no Android binaries are on the PATH', function () {
|
||||
beforeEach(function () {
|
||||
spyOn(shelljs, 'which').and.returnValue(null);
|
||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||
});
|
||||
it('it should set ANDROID_HOME on Windows', function (done) {
|
||||
it('it should set ANDROID_HOME on Windows', () => {
|
||||
spyOn(check_reqs, 'isWindows').and.returnValue(true);
|
||||
process.env.LOCALAPPDATA = 'windows-local-app-data';
|
||||
process.env.ProgramFiles = 'windows-program-files';
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.ANDROID_HOME).toContain('windows-local-app-data');
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
console.log(err);
|
||||
}).fin(function () {
|
||||
delete process.env.LOCALAPPDATA;
|
||||
delete process.env.ProgramFiles;
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('it should set ANDROID_HOME on Darwin', function (done) {
|
||||
it('it should set ANDROID_HOME on Darwin', () => {
|
||||
spyOn(check_reqs, 'isWindows').and.returnValue(false);
|
||||
spyOn(check_reqs, 'isDarwin').and.returnValue(true);
|
||||
process.env.HOME = 'home is where the heart is';
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.ANDROID_HOME).toContain('home is where the heart is');
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
console.log(err);
|
||||
}).fin(function () {
|
||||
delete process.env.HOME;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -80,7 +73,7 @@ describe('check_reqs', function () {
|
||||
return path;
|
||||
});
|
||||
});
|
||||
it('should set ANDROID_HOME based on `android` command if command exists in a SDK-like directory structure', function (done) {
|
||||
it('should set ANDROID_HOME based on `android` command if command exists in a SDK-like directory structure', () => {
|
||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'android') {
|
||||
@@ -91,13 +84,9 @@ describe('check_reqs', function () {
|
||||
});
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.ANDROID_HOME).toEqual('/android/sdk');
|
||||
done();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
it('should error out if `android` command exists in a non-SDK-like directory structure', function (done) {
|
||||
it('should error out if `android` command exists in a non-SDK-like directory structure', () => {
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'android') {
|
||||
return '/just/some/random/path/android';
|
||||
@@ -105,15 +94,14 @@ describe('check_reqs', function () {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return check_reqs.check_android().then(function () {
|
||||
done.fail();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
return check_reqs.check_android().then(() => {
|
||||
fail('Expected promise to be rejected');
|
||||
}, err => {
|
||||
expect(err).toEqual(jasmine.any(Error));
|
||||
expect(err.message).toContain('update your PATH to include valid path');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should set ANDROID_HOME based on `adb` command if command exists in a SDK-like directory structure', function (done) {
|
||||
it('should set ANDROID_HOME based on `adb` command if command exists in a SDK-like directory structure', () => {
|
||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'adb') {
|
||||
@@ -124,13 +112,9 @@ describe('check_reqs', function () {
|
||||
});
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.ANDROID_HOME).toEqual('/android/sdk');
|
||||
done();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
it('should error out if `adb` command exists in a non-SDK-like directory structure', function (done) {
|
||||
it('should error out if `adb` command exists in a non-SDK-like directory structure', () => {
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'adb') {
|
||||
return '/just/some/random/path/adb';
|
||||
@@ -138,15 +122,14 @@ describe('check_reqs', function () {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return check_reqs.check_android().then(function () {
|
||||
done.fail();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
return check_reqs.check_android().then(() => {
|
||||
fail('Expected promise to be rejected');
|
||||
}, err => {
|
||||
expect(err).toEqual(jasmine.any(Error));
|
||||
expect(err.message).toContain('update your PATH to include valid path');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should set ANDROID_HOME based on `avdmanager` command if command exists in a SDK-like directory structure', function (done) {
|
||||
it('should set ANDROID_HOME based on `avdmanager` command if command exists in a SDK-like directory structure', () => {
|
||||
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'avdmanager') {
|
||||
@@ -157,13 +140,9 @@ describe('check_reqs', function () {
|
||||
});
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.ANDROID_HOME).toEqual('/android/sdk');
|
||||
done();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
it('should error out if `avdmanager` command exists in a non-SDK-like directory structure', function (done) {
|
||||
it('should error out if `avdmanager` command exists in a non-SDK-like directory structure', () => {
|
||||
spyOn(shelljs, 'which').and.callFake(function (cmd) {
|
||||
if (cmd === 'avdmanager') {
|
||||
return '/just/some/random/path/avdmanager';
|
||||
@@ -171,12 +150,11 @@ describe('check_reqs', function () {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return check_reqs.check_android().then(function () {
|
||||
done.fail();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
return check_reqs.check_android().then(() => {
|
||||
fail('Expected promise to be rejected');
|
||||
}, err => {
|
||||
expect(err).toEqual(jasmine.any(Error));
|
||||
expect(err.message).toContain('update your PATH to include valid path');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -190,15 +168,11 @@ describe('check_reqs', function () {
|
||||
afterEach(function () {
|
||||
delete process.env.ANDROID_HOME;
|
||||
});
|
||||
it('should add tools/bin,tools,platform-tools to PATH if `avdmanager`,`android`,`adb` is not found', function (done) {
|
||||
it('should add tools/bin,tools,platform-tools to PATH if `avdmanager`,`android`,`adb` is not found', () => {
|
||||
return check_reqs.check_android().then(function () {
|
||||
expect(process.env.PATH).toContain('let the children play' + path.sep + 'tools');
|
||||
expect(process.env.PATH).toContain('let the children play' + path.sep + 'platform-tools');
|
||||
expect(process.env.PATH).toContain('let the children play' + path.sep + 'tools' + path.sep + 'bin');
|
||||
done();
|
||||
}).fail(function (err) {
|
||||
expect(err).toBeUndefined();
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -211,7 +185,7 @@ describe('check_reqs', function () {
|
||||
});
|
||||
});
|
||||
describe('check_android_target', function () {
|
||||
it('should should return full list of supported targets if there is a match to ideal api level', function (done) {
|
||||
it('should should return full list of supported targets if there is a match to ideal api level', () => {
|
||||
var deferred = Q.defer();
|
||||
spyOn(android_sdk, 'list_targets').and.returnValue(deferred.promise);
|
||||
var fake_targets = ['you are my fire', 'my one desire'];
|
||||
@@ -220,19 +194,19 @@ describe('check_reqs', function () {
|
||||
return check_reqs.check_android_target().then(function (targets) {
|
||||
expect(targets).toBeDefined();
|
||||
expect(targets).toEqual(fake_targets);
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should error out if there is no match between ideal api level and installed targets', function (done) {
|
||||
it('should error out if there is no match between ideal api level and installed targets', () => {
|
||||
var deferred = Q.defer();
|
||||
spyOn(android_sdk, 'list_targets').and.returnValue(deferred.promise);
|
||||
var fake_targets = ['you are my fire', 'my one desire'];
|
||||
deferred.resolve(fake_targets);
|
||||
spyOn(check_reqs, 'get_target').and.returnValue('and i knowwwwwwwwwwww');
|
||||
return check_reqs.check_android_target().catch(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
return check_reqs.check_android_target().then(() => {
|
||||
fail('Expected promise to be rejected');
|
||||
}, err => {
|
||||
expect(err).toEqual(jasmine.any(Error));
|
||||
expect(err.message).toContain('Please install Android target');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -106,7 +106,7 @@ describe('Gradle Builder', () => {
|
||||
expect(emitSpy.calls.argsFor(0)[1]).toContain('Appending configuration item');
|
||||
});
|
||||
|
||||
it('should not detect missing defaults and not call set.', () => {
|
||||
it('should not detect missing defaults and call set.', () => {
|
||||
let setSpy = jasmine.createSpy('set');
|
||||
let getSpy = jasmine.createSpy('get').and.returnValue(true);
|
||||
|
||||
@@ -118,10 +118,10 @@ describe('Gradle Builder', () => {
|
||||
parser._configureProperties(parser._defaults);
|
||||
|
||||
expect(getSpy).toHaveBeenCalled();
|
||||
expect(setSpy).not.toHaveBeenCalled();
|
||||
expect(setSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should detect default with changed value.', () => {
|
||||
it('should detect default with changed value to match default and set.', () => {
|
||||
let setSpy = jasmine.createSpy('set');
|
||||
let getSpy = jasmine.createSpy('get').and.returnValue('-Xmx512m');
|
||||
|
||||
@@ -133,7 +133,23 @@ describe('Gradle Builder', () => {
|
||||
parser._configureProperties(parser._defaults);
|
||||
|
||||
expect(getSpy).toHaveBeenCalled();
|
||||
expect(setSpy).not.toHaveBeenCalled();
|
||||
expect(setSpy).toHaveBeenCalled();
|
||||
expect(emitSpy.calls.argsFor(0)[1]).toContain('Updating Gradle property');
|
||||
});
|
||||
|
||||
it('should detect default with changed value different from default and set.', () => {
|
||||
let setSpy = jasmine.createSpy('set');
|
||||
let getSpy = jasmine.createSpy('get').and.returnValue('-Xmx2048m');
|
||||
|
||||
parser.gradleFile = {
|
||||
set: setSpy,
|
||||
get: getSpy
|
||||
};
|
||||
|
||||
parser._configureProperties({ 'org.gradle.jvmargs': '-Xmx512m' });
|
||||
|
||||
expect(getSpy).toHaveBeenCalled();
|
||||
expect(setSpy).toHaveBeenCalled();
|
||||
expect(emitSpy.calls.argsFor(0)[1]).toContain('Cordova\'s recommended value is');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,54 +35,42 @@ describe('create', function () {
|
||||
'ball8.ball8.ball8ball'
|
||||
];
|
||||
valid.forEach(function (package_name) {
|
||||
it('Test#001 : should accept ' + package_name, function (done) {
|
||||
create.validatePackageName(package_name).fail(fail).done(done);
|
||||
it('Test#001 : should accept ' + package_name, () => {
|
||||
return create.validatePackageName(package_name);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('failure cases (invalid package names)', function () {
|
||||
it('should reject empty package names', function (done) {
|
||||
create.validatePackageName('').then(fail).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
function expectPackageNameToBeRejected (name) {
|
||||
return create.validatePackageName(name).then(() => {
|
||||
fail('Expected promise to be rejected');
|
||||
}, err => {
|
||||
expect(err).toEqual(jasmine.any(Error));
|
||||
expect(err.message).toContain('Error validating package name');
|
||||
}).done(done);
|
||||
});
|
||||
}
|
||||
|
||||
it('should reject empty package names', () => {
|
||||
return expectPackageNameToBeRejected('');
|
||||
});
|
||||
it('should reject package names containing "class"', function (done) {
|
||||
create.validatePackageName('com.class.is.bad').then(fail).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain('Error validating package name');
|
||||
}).done(done);
|
||||
it('should reject package names containing "class"', () => {
|
||||
return expectPackageNameToBeRejected('com.class.is.bad');
|
||||
});
|
||||
it('should reject package names that do not start with a latin letter', function (done) {
|
||||
create.validatePackageName('_un.der.score').then(fail).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain('Error validating package name');
|
||||
}).done(done);
|
||||
it('should reject package names that do not start with a latin letter', () => {
|
||||
return expectPackageNameToBeRejected('_un.der.score');
|
||||
});
|
||||
it('should reject package names with terms that do not start with a latin letter', function (done) {
|
||||
create.validatePackageName('un._der.score').then(fail).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain('Error validating package name');
|
||||
}).done(done);
|
||||
it('should reject package names with terms that do not start with a latin letter', () => {
|
||||
return expectPackageNameToBeRejected('un._der.score');
|
||||
});
|
||||
it('should reject package names containing non-alphanumeric or underscore characters', function (done) {
|
||||
create.validatePackageName('th!$.!$.b@d').then(fail).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain('Error validating package name');
|
||||
}).done(done);
|
||||
it('should reject package names containing non-alphanumeric or underscore characters', () => {
|
||||
return expectPackageNameToBeRejected('th!$.!$.b@d');
|
||||
});
|
||||
it('should reject package names that do not contain enough dots', function (done) {
|
||||
create.validatePackageName('therearenodotshere').then(fail).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain('Error validating package name');
|
||||
}).done(done);
|
||||
it('should reject package names that do not contain enough dots', () => {
|
||||
return expectPackageNameToBeRejected('therearenodotshere');
|
||||
});
|
||||
it('should reject package names that end with a dot', function (done) {
|
||||
create.validatePackageName('this.is.a.complete.sentence.').then(fail).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
expect(err.message).toContain('Error validating package name');
|
||||
}).done(done);
|
||||
it('should reject package names that end with a dot', () => {
|
||||
return expectPackageNameToBeRejected('this.is.a.complete.sentence.');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -95,29 +83,35 @@ describe('create', function () {
|
||||
'CordovaLib'
|
||||
];
|
||||
valid.forEach(function (project_name) {
|
||||
it('Test#003 : should accept ' + project_name, function (done) {
|
||||
create.validateProjectName(project_name).fail(fail).done(done);
|
||||
it('Test#003 : should accept ' + project_name, () => {
|
||||
return create.validateProjectName(project_name);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('failure cases (invalid project names)', function () {
|
||||
it('should reject empty project names', function (done) {
|
||||
create.validateProjectName('').then(fail).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
it('should reject empty project names', () => {
|
||||
return create.validateProjectName('').then(() => {
|
||||
fail('Expected promise to be rejected');
|
||||
}, err => {
|
||||
expect(err).toEqual(jasmine.any(Error));
|
||||
expect(err.message).toContain('Project name cannot be empty');
|
||||
}).done(done);
|
||||
});
|
||||
});
|
||||
it('should reject "CordovaActivity" as a project name', function (done) {
|
||||
create.validateProjectName('CordovaActivity').then(fail).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
it('should reject "CordovaActivity" as a project name', () => {
|
||||
return create.validateProjectName('CordovaActivity').then(() => {
|
||||
fail('Expected promise to be rejected');
|
||||
}, err => {
|
||||
expect(err).toEqual(jasmine.any(Error));
|
||||
expect(err.message).toContain('Project name cannot be CordovaActivity');
|
||||
}).done(done);
|
||||
});
|
||||
});
|
||||
it('should reject project names that begin with a number', function (done) {
|
||||
create.validateProjectName('1337').then(fail).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
it('should reject project names that begin with a number', () => {
|
||||
return create.validateProjectName('1337').then(() => {
|
||||
fail('Expected promise to be rejected');
|
||||
}, err => {
|
||||
expect(err).toEqual(jasmine.any(Error));
|
||||
expect(err.message).toContain('Project name must not begin with a number');
|
||||
}).done(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -131,9 +125,8 @@ describe('create', function () {
|
||||
var default_templates = path.join(__dirname, '..', '..', 'bin', 'templates', 'project');
|
||||
var fake_android_target = 'android-1337';
|
||||
beforeEach(function () {
|
||||
Manifest_mock.prototype = jasmine.createSpyObj('AndroidManifest instance mock', ['setPackageId', 'setTargetSdkVersion', 'getActivity', 'setName', 'write']);
|
||||
Manifest_mock.prototype = jasmine.createSpyObj('AndroidManifest instance mock', ['setPackageId', 'getActivity', 'setName', 'write']);
|
||||
Manifest_mock.prototype.setPackageId.and.returnValue(new Manifest_mock());
|
||||
Manifest_mock.prototype.setTargetSdkVersion.and.returnValue(new Manifest_mock());
|
||||
Manifest_mock.prototype.getActivity.and.returnValue(new Manifest_mock());
|
||||
Manifest_mock.prototype.setName.and.returnValue(new Manifest_mock());
|
||||
spyOn(create, 'validatePackageName').and.returnValue(Q());
|
||||
@@ -157,125 +150,138 @@ describe('create', function () {
|
||||
revert_manifest_mock();
|
||||
});
|
||||
describe('parameter values and defaults', function () {
|
||||
it('should have a default package name of my.cordova.project', function (done) {
|
||||
it('should have a default package name of my.cordova.project', () => {
|
||||
config_mock.packageName.and.returnValue(undefined);
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.validatePackageName).toHaveBeenCalledWith('my.cordova.project');
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should use the ConfigParser-provided package name, if exists', function (done) {
|
||||
it('should use the ConfigParser-provided package name, if exists', () => {
|
||||
config_mock.packageName.and.returnValue('org.apache.cordova');
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.validatePackageName).toHaveBeenCalledWith('org.apache.cordova');
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should have a default project name of CordovaExample', function (done) {
|
||||
it('should have a default project name of CordovaExample', () => {
|
||||
config_mock.name.and.returnValue(undefined);
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.validateProjectName).toHaveBeenCalledWith('CordovaExample');
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should use the ConfigParser-provided project name, if exists', function (done) {
|
||||
it('should use the ConfigParser-provided project name, if exists', () => {
|
||||
config_mock.name.and.returnValue('MySweetAppName');
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.validateProjectName).toHaveBeenCalledWith('MySweetAppName');
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should replace any non-word characters (including unicode and spaces) in the ConfigParser-provided project name with underscores', function (done) {
|
||||
it('should replace any non-word characters (including unicode and spaces) in the ConfigParser-provided project name with underscores', () => {
|
||||
config_mock.name.and.returnValue('応応応応 hello 用用用用');
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.validateProjectName).toHaveBeenCalledWith('_____hello_____');
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should have a default activity name of MainActivity', function (done) {
|
||||
it('should have a default activity name of MainActivity', () => {
|
||||
config_mock.android_activityName.and.returnValue(undefined);
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(Manifest_mock.prototype.setName).toHaveBeenCalledWith('MainActivity');
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should use the activityName provided via options parameter, if exists', function (done) {
|
||||
it('should use the activityName provided via options parameter, if exists', () => {
|
||||
config_mock.android_activityName.and.returnValue(undefined);
|
||||
create.create(project_path, config_mock, { activityName: 'AwesomeActivity' }, events_mock).then(function () {
|
||||
return create.create(project_path, config_mock, { activityName: 'AwesomeActivity' }, events_mock).then(() => {
|
||||
expect(Manifest_mock.prototype.setName).toHaveBeenCalledWith('AwesomeActivity');
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should use the ConfigParser-provided activity name, if exists', function (done) {
|
||||
it('should use the ConfigParser-provided activity name, if exists', () => {
|
||||
config_mock.android_activityName.and.returnValue('AmazingActivity');
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(Manifest_mock.prototype.setName).toHaveBeenCalledWith('AmazingActivity');
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('failure', function () {
|
||||
it('should fail if the target path already exists', function (done) {
|
||||
it('should fail if the target path already exists', () => {
|
||||
fs.existsSync.and.returnValue(true);
|
||||
create.create(project_path, config_mock, {}, events_mock).then(fail).fail(function (err) {
|
||||
expect(err).toBeDefined();
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
fail('Expected promise to be rejected');
|
||||
}, err => {
|
||||
expect(err).toEqual(jasmine.any(Error));
|
||||
expect(err.message).toContain('Project already exists!');
|
||||
}).done(done);
|
||||
});
|
||||
});
|
||||
it('should fail if validateProjectName rejects', () => {
|
||||
const fakeError = new Error();
|
||||
create.validateProjectName.and.callFake(() => Promise.reject(fakeError));
|
||||
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
fail('Expected promise to be rejected');
|
||||
}, err => {
|
||||
expect(err).toBe(fakeError);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
describe('happy path', function () {
|
||||
it('should copy project templates from a specified custom template', function (done) {
|
||||
create.create(project_path, config_mock, { customTemplate: '/template/path' }, events_mock).then(function () {
|
||||
it('should copy project templates from a specified custom template', () => {
|
||||
return create.create(project_path, config_mock, { customTemplate: '/template/path' }, events_mock).then(() => {
|
||||
expect(shell.cp).toHaveBeenCalledWith('-r', path.join('/template/path', 'assets'), app_path);
|
||||
expect(shell.cp).toHaveBeenCalledWith('-r', path.join('/template/path', 'res'), app_path);
|
||||
expect(shell.cp).toHaveBeenCalledWith(path.join('/template/path', 'gitignore'), path.join(project_path, '.gitignore'));
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should copy project templates from the default templates location if no custom template is provided', function (done) {
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
it('should copy project templates from the default templates location if no custom template is provided', () => {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(shell.cp).toHaveBeenCalledWith('-r', path.join(default_templates, 'assets'), app_path);
|
||||
expect(shell.cp).toHaveBeenCalledWith('-r', path.join(default_templates, 'res'), app_path);
|
||||
expect(shell.cp).toHaveBeenCalledWith(path.join(default_templates, 'gitignore'), path.join(project_path, '.gitignore'));
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should copy JS and library assets', function (done) {
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
it('should copy JS and library assets', () => {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.copyJsAndLibrary).toHaveBeenCalled();
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should create a java src directory based on the provided project package name', function (done) {
|
||||
it('should create a java src directory based on the provided project package name', () => {
|
||||
config_mock.packageName.and.returnValue('org.apache.cordova');
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(shell.mkdir).toHaveBeenCalledWith('-p', path.join(app_path, 'java', 'org', 'apache', 'cordova'));
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should copy, rename and interpolate the template Activity java class with the project-specific activity name and package name', function (done) {
|
||||
it('should copy, rename and interpolate the template Activity java class with the project-specific activity name and package name', () => {
|
||||
config_mock.packageName.and.returnValue('org.apache.cordova');
|
||||
config_mock.android_activityName.and.returnValue('CEEDEEVEE');
|
||||
var activity_path = path.join(app_path, 'java', 'org', 'apache', 'cordova', 'CEEDEEVEE.java');
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(shell.cp).toHaveBeenCalledWith('-f', path.join(default_templates, 'Activity.java'), activity_path);
|
||||
expect(shell.sed).toHaveBeenCalledWith('-i', /__ACTIVITY__/, 'CEEDEEVEE', activity_path);
|
||||
expect(shell.sed).toHaveBeenCalledWith('-i', /__ID__/, 'org.apache.cordova', activity_path);
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should interpolate the project name into strings.xml', function (done) {
|
||||
it('should interpolate the project name into strings.xml', () => {
|
||||
config_mock.name.and.returnValue('IncredibleApp');
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(shell.sed).toHaveBeenCalledWith('-i', /__NAME__/, 'IncredibleApp', path.join(app_path, 'res', 'values', 'strings.xml'));
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should copy template scripts into generated project', function (done) {
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
it('should copy template scripts into generated project', () => {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.copyScripts).toHaveBeenCalledWith(project_path);
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should copy build rules / gradle files into generated project', function (done) {
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
it('should copy build rules / gradle files into generated project', () => {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.copyBuildRules).toHaveBeenCalledWith(project_path);
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should write project.properties file with project details and target API', function (done) {
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
it('should write project.properties file with project details and target API', () => {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.writeProjectProperties).toHaveBeenCalledWith(project_path, fake_android_target);
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
it('should prepare build files', function (done) {
|
||||
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||
it('should prepare build files', () => {
|
||||
return create.create(project_path, config_mock, {}, events_mock).then(() => {
|
||||
expect(create.prepBuildFiles).toHaveBeenCalledWith(project_path);
|
||||
}).fail(fail).done(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
"spec_files": [
|
||||
"unit/**/*[sS]pec.js"
|
||||
],
|
||||
"helpers": [
|
||||
"helper.js"
|
||||
],
|
||||
"stopSpecOnExpectationFailure": false,
|
||||
"random": true
|
||||
}
|
||||
|
||||
@@ -196,16 +196,27 @@ describe('run', () => {
|
||||
expect(emulatorSpyObj.install).toHaveBeenCalledWith(emulatorTarget, { apkPaths: [], buildType: 'debug' });
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail with the error message if --packageType=bundle setting is used', () => {
|
||||
const deviceList = ['testDevice1', 'testDevice2'];
|
||||
getInstallTargetSpy.and.returnValue(null);
|
||||
|
||||
deviceSpyObj.list.and.returnValue(Promise.resolve(deviceList));
|
||||
|
||||
return run.run({ argv: ['--packageType=bundle'] }).then(
|
||||
() => fail('Expected error to be thrown'),
|
||||
err => expect(err).toContain('Package type "bundle" is not supported during cordova run.')
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('help', () => {
|
||||
it('should print out usage and help', () => {
|
||||
const logSpy = jasmine.createSpy();
|
||||
const procStub = { exit: _ => null, cwd: _ => '', argv: ['', ''] };
|
||||
run.__set__({ console: { log: logSpy }, process: procStub });
|
||||
spyOn(console, 'log');
|
||||
spyOn(process, 'exit');
|
||||
|
||||
run.help();
|
||||
expect(logSpy).toHaveBeenCalledWith(jasmine.stringMatching(/^Usage:/));
|
||||
expect(console.log).toHaveBeenCalledWith(jasmine.stringMatching(/^Usage:/));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||