forked from github/cordova-android
Merge branch 'master' into StudioProjectCompat
This commit is contained in:
commit
849b887e20
@ -32,6 +32,18 @@ var CordovaError = require('cordova-common').CordovaError;
|
|||||||
var AndroidStudio = require('../templates/cordova/lib/AndroidStudio');
|
var AndroidStudio = require('../templates/cordova/lib/AndroidStudio');
|
||||||
var AndroidManifest = require('../templates/cordova/lib/AndroidManifest');
|
var AndroidManifest = require('../templates/cordova/lib/AndroidManifest');
|
||||||
|
|
||||||
|
// Export all helper functions, and make sure internally within this module, we
|
||||||
|
// reference these methods via the `exports` object - this helps with testing
|
||||||
|
// (since we can then mock and control behaviour of all of these functions)
|
||||||
|
exports.validatePackageName = validatePackageName;
|
||||||
|
exports.validateProjectName = validateProjectName;
|
||||||
|
exports.setShellFatal = setShellFatal;
|
||||||
|
exports.copyJsAndLibrary = copyJsAndLibrary;
|
||||||
|
exports.copyScripts = copyScripts;
|
||||||
|
exports.copyBuildRules = copyBuildRules;
|
||||||
|
exports.writeProjectProperties = writeProjectProperties;
|
||||||
|
exports.prepBuildFiles = prepBuildFiles;
|
||||||
|
|
||||||
function setShellFatal (value, func) {
|
function setShellFatal (value, func) {
|
||||||
var oldVal = shell.config.fatal;
|
var oldVal = shell.config.fatal;
|
||||||
shell.config.fatal = value;
|
shell.config.fatal = value;
|
||||||
@ -64,7 +76,7 @@ function copyJsAndLibrary (projectPath, shared, projectName, isLegacy) {
|
|||||||
shell.cp('-rf', path.join(ROOT, 'cordova-js-src'), path.join(projectPath, 'platform_www'));
|
shell.cp('-rf', path.join(ROOT, 'cordova-js-src'), path.join(projectPath, 'platform_www'));
|
||||||
|
|
||||||
// Don't fail if there are no old jars.
|
// Don't fail if there are no old jars.
|
||||||
setShellFatal(false, function () {
|
exports.setShellFatal(false, function () {
|
||||||
shell.ls(path.join(projectPath, 'libs', 'cordova-*.jar')).forEach(function (oldJar) {
|
shell.ls(path.join(projectPath, 'libs', 'cordova-*.jar')).forEach(function (oldJar) {
|
||||||
console.log('Deleting ' + oldJar);
|
console.log('Deleting ' + oldJar);
|
||||||
shell.rm('-f', oldJar);
|
shell.rm('-f', oldJar);
|
||||||
@ -183,6 +195,7 @@ function validatePackageName (package_name) {
|
|||||||
// http://developer.android.com/guide/topics/manifest/manifest-element.html#package
|
// http://developer.android.com/guide/topics/manifest/manifest-element.html#package
|
||||||
// Enforce underscore limitation
|
// Enforce underscore limitation
|
||||||
var msg = 'Error validating package name. ';
|
var msg = 'Error validating package name. ';
|
||||||
|
|
||||||
if (!/^[a-zA-Z][a-zA-Z0-9_]+(\.[a-zA-Z][a-zA-Z0-9_]*)+$/.test(package_name)) {
|
if (!/^[a-zA-Z][a-zA-Z0-9_]+(\.[a-zA-Z][a-zA-Z0-9_]*)+$/.test(package_name)) {
|
||||||
return Q.reject(new CordovaError(msg + 'Package name must look like: com.company.Name'));
|
return Q.reject(new CordovaError(msg + 'Package name must look like: com.company.Name'));
|
||||||
}
|
}
|
||||||
@ -257,9 +270,9 @@ exports.create = function (project_path, config, options, events) {
|
|||||||
var target_api = check_reqs.get_target();
|
var target_api = check_reqs.get_target();
|
||||||
|
|
||||||
// Make the package conform to Java package types
|
// Make the package conform to Java package types
|
||||||
return validatePackageName(package_name)
|
return exports.validatePackageName(package_name)
|
||||||
.then(function () {
|
.then(function () {
|
||||||
validateProjectName(project_name);
|
exports.validateProjectName(project_name);
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
// Log the given values for the project
|
// Log the given values for the project
|
||||||
events.emit('log', 'Creating Cordova project for the Android platform:');
|
events.emit('log', 'Creating Cordova project for the Android platform:');
|
||||||
@ -271,7 +284,7 @@ exports.create = function (project_path, config, options, events) {
|
|||||||
|
|
||||||
events.emit('verbose', 'Copying android template project to ' + project_path);
|
events.emit('verbose', 'Copying android template project to ' + project_path);
|
||||||
|
|
||||||
setShellFatal(true, function () {
|
exports.setShellFatal(true, function () {
|
||||||
var project_template_dir = options.customTemplate || path.join(ROOT, 'bin', 'templates', 'project');
|
var project_template_dir = options.customTemplate || path.join(ROOT, 'bin', 'templates', 'project');
|
||||||
var app_path = path.join(project_path, 'app', 'src', 'main');
|
var app_path = path.join(project_path, 'app', 'src', 'main');
|
||||||
|
|
||||||
@ -285,7 +298,7 @@ exports.create = function (project_path, config, options, events) {
|
|||||||
shell.mkdir(path.join(app_path, 'libs'));
|
shell.mkdir(path.join(app_path, 'libs'));
|
||||||
|
|
||||||
// copy cordova.js, cordova.jar
|
// copy cordova.js, cordova.jar
|
||||||
copyJsAndLibrary(project_path, options.link, safe_activity_name);
|
exports.copyJsAndLibrary(project_path, options.link, safe_activity_name);
|
||||||
|
|
||||||
// Set up ther Android Studio paths
|
// Set up ther Android Studio paths
|
||||||
var java_path = path.join(app_path, 'java');
|
var java_path = path.join(app_path, 'java');
|
||||||
@ -314,12 +327,12 @@ exports.create = function (project_path, config, options, events) {
|
|||||||
var manifest_path = path.join(app_path, 'AndroidManifest.xml');
|
var manifest_path = path.join(app_path, 'AndroidManifest.xml');
|
||||||
manifest.write(manifest_path);
|
manifest.write(manifest_path);
|
||||||
|
|
||||||
copyScripts(project_path);
|
exports.copyScripts(project_path);
|
||||||
copyBuildRules(project_path);
|
exports.copyBuildRules(project_path);
|
||||||
});
|
});
|
||||||
// Link it to local android install.
|
// Link it to local android install.
|
||||||
writeProjectProperties(project_path, target_api);
|
exports.writeProjectProperties(project_path, target_api);
|
||||||
prepBuildFiles(project_path, 'studio');
|
exports.prepBuildFiles(project_path, 'studio');
|
||||||
events.emit('log', generateDoneMessage('create', options.link));
|
events.emit('log', generateDoneMessage('create', options.link));
|
||||||
}).thenResolve(project_path);
|
}).thenResolve(project_path);
|
||||||
};
|
};
|
||||||
@ -363,15 +376,11 @@ exports.update = function (projectPath, options, events) {
|
|||||||
var projectName = manifest.getActivity().getName();
|
var projectName = manifest.getActivity().getName();
|
||||||
var target_api = check_reqs.get_target();
|
var target_api = check_reqs.get_target();
|
||||||
|
|
||||||
copyJsAndLibrary(projectPath, options.link, projectName, isLegacy);
|
exports.copyJsAndLibrary(projectPath, options.link, projectName, isLegacy);
|
||||||
copyScripts(projectPath);
|
exports.copyScripts(projectPath);
|
||||||
copyBuildRules(projectPath, isLegacy);
|
exports.copyBuildRules(projectPath, isLegacy);
|
||||||
writeProjectProperties(projectPath, target_api);
|
exports.writeProjectProperties(projectPath, target_api);
|
||||||
prepBuildFiles(projectPath, builder);
|
exports.prepBuildFiles(projectPath, builder);
|
||||||
events.emit('log', generateDoneMessage('update', options.link));
|
events.emit('log', generateDoneMessage('update', options.link));
|
||||||
}).thenResolve(projectPath);
|
}).thenResolve(projectPath);
|
||||||
};
|
};
|
||||||
|
|
||||||
// For testing
|
|
||||||
exports.validatePackageName = validatePackageName;
|
|
||||||
exports.validateProjectName = validateProjectName;
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run eslint && npm run unit-tests && npm run e2e-tests",
|
"test": "npm run eslint && npm run unit-tests && npm run e2e-tests",
|
||||||
"unit-tests": "jasmine --config=spec/unit/jasmine.json",
|
"unit-tests": "jasmine --config=spec/unit/jasmine.json",
|
||||||
"cover": "istanbul cover --root bin/templates/cordova --print detail jasmine -- --config=spec/unit/jasmine.json",
|
"cover": "istanbul cover --root bin --print detail jasmine -- --config=spec/unit/jasmine.json",
|
||||||
"e2e-tests": "jasmine --config=spec/e2e/jasmine.json",
|
"e2e-tests": "jasmine --config=spec/e2e/jasmine.json",
|
||||||
"eslint": "eslint bin && eslint spec"
|
"eslint": "eslint bin && eslint spec"
|
||||||
},
|
},
|
||||||
|
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var actions = require('./helpers/projectActions.js');
|
|
||||||
|
|
||||||
var CREATE_TIMEOUT = 180000;
|
|
||||||
|
|
||||||
function createAndBuild (projectname, projectid, done) {
|
|
||||||
actions.createProject(projectname, projectid, function (error) {
|
|
||||||
expect(error).toBe(null);
|
|
||||||
actions.buildProject(projectid, function (error) {
|
|
||||||
expect(error).toBe(null);
|
|
||||||
actions.removeProject(projectid);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('create', function () {
|
|
||||||
|
|
||||||
it('Test#001 : create project with ascii name, no spaces', function (done) {
|
|
||||||
var projectname = 'testcreate';
|
|
||||||
var projectid = 'com.test.create.app1';
|
|
||||||
|
|
||||||
createAndBuild(projectname, projectid, done);
|
|
||||||
}, CREATE_TIMEOUT);
|
|
||||||
|
|
||||||
it('Test#002 : create project with ascii name, and spaces', function (done) {
|
|
||||||
var projectname = 'test create';
|
|
||||||
var projectid = 'com.test.create.app2';
|
|
||||||
|
|
||||||
createAndBuild(projectname, projectid, done);
|
|
||||||
}, CREATE_TIMEOUT);
|
|
||||||
|
|
||||||
it('Test#003 : create project with unicode name, no spaces', function (done) {
|
|
||||||
var projectname = '応応応応用用用用';
|
|
||||||
var projectid = 'com.test.create.app3';
|
|
||||||
|
|
||||||
createAndBuild(projectname, projectid, done);
|
|
||||||
}, CREATE_TIMEOUT);
|
|
||||||
|
|
||||||
it('Test#004 : create project with unicode name, and spaces', function (done) {
|
|
||||||
var projectname = '応応応応 用用用用';
|
|
||||||
var projectid = 'com.test.create.app4';
|
|
||||||
|
|
||||||
createAndBuild(projectname, projectid, done);
|
|
||||||
}, CREATE_TIMEOUT);
|
|
||||||
|
|
||||||
it('Test#005 : create project with ascii+unicode name, no spaces', function (done) {
|
|
||||||
var projectname = '応応応応hello用用用用';
|
|
||||||
var projectid = 'com.test.create.app5';
|
|
||||||
|
|
||||||
createAndBuild(projectname, projectid, done);
|
|
||||||
}, CREATE_TIMEOUT);
|
|
||||||
|
|
||||||
it('Test#006 : create project with ascii+unicode name, and spaces', function (done) {
|
|
||||||
var projectname = '応応応応 hello 用用用用';
|
|
||||||
var projectid = 'com.test.create.app6';
|
|
||||||
|
|
||||||
createAndBuild(projectname, projectid, done);
|
|
||||||
}, CREATE_TIMEOUT);
|
|
||||||
|
|
||||||
});
|
|
@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var actions = require('./helpers/projectActions.js');
|
|
||||||
var shell = require('shelljs');
|
|
||||||
var fs = require('fs');
|
|
||||||
var util = require('util');
|
|
||||||
var platformOld = { version: '4.0.0', path: 'cordova-android-old' };
|
|
||||||
var platformEdge = { version: getCurrentVersion(), path: '.' };
|
|
||||||
|
|
||||||
var DOWNLOAD_TIMEOUT = 2 * 60 * 1000;
|
|
||||||
var UPDATE_TIMEOUT = 90 * 1000;
|
|
||||||
var PLATFORM_GIT_URL = 'https://github.com/apache/cordova-android';
|
|
||||||
|
|
||||||
function getCurrentVersion () {
|
|
||||||
return fs.readFileSync('VERSION').toString().trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
function testUpdate (projectname, projectid, createfrom, updatefrom, doBuild, done) {
|
|
||||||
actions.createProject(projectname, projectid, createfrom.path, function (error) {
|
|
||||||
expect(error).toBe(null);
|
|
||||||
actions.updateProject(projectid, updatefrom.path, function (error) {
|
|
||||||
expect(error).toBe(null);
|
|
||||||
actions.getPlatformVersion(projectid, function (v) {
|
|
||||||
expect(v).toEqual(updatefrom.version);
|
|
||||||
if (doBuild) {
|
|
||||||
actions.buildProject(projectid, function (error) {
|
|
||||||
expect(error).toBe(null);
|
|
||||||
actions.removeProject(projectid);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
actions.removeProject(projectid);
|
|
||||||
done();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('preparing fixtures', function () {
|
|
||||||
|
|
||||||
it('Test#001 : cloning old platform', function (done) {
|
|
||||||
var command = util.format('git clone %s --depth=1 --branch %s %s',
|
|
||||||
PLATFORM_GIT_URL, platformOld.version, platformOld.path);
|
|
||||||
shell.rm('-rf', platformOld.path);
|
|
||||||
shell.exec(command, { silent: true }, function (err) {
|
|
||||||
expect(err).toBe(0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
}, DOWNLOAD_TIMEOUT);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('update', function () {
|
|
||||||
|
|
||||||
it('Test#002 : should update major version and build the project', function (done) {
|
|
||||||
var projectname = 'testupdate';
|
|
||||||
var projectid = 'com.test.update.app1';
|
|
||||||
|
|
||||||
testUpdate(projectname, projectid, platformOld, platformEdge, true, done);
|
|
||||||
|
|
||||||
}, UPDATE_TIMEOUT);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('cleanup', function () {
|
|
||||||
|
|
||||||
it('Test#004 : remove cloned old platform', function () {
|
|
||||||
shell.rm('-rf', platformOld.path);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
@ -17,89 +17,264 @@
|
|||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var create = require('../../bin/lib/create');
|
var rewire = require('rewire');
|
||||||
|
var create = rewire('../../bin/lib/create');
|
||||||
|
var check_reqs = require('../../bin/templates/cordova/lib/check_reqs');
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
var Q = require('q');
|
||||||
|
var shell = require('shelljs');
|
||||||
|
|
||||||
describe('create', function () {
|
describe('create', function () {
|
||||||
describe('validatePackageName', function () {
|
describe('validatePackageName helper method', function () {
|
||||||
var valid = [
|
describe('happy path (valid package names)', function () {
|
||||||
'org.apache.mobilespec',
|
var valid = [
|
||||||
'com.example',
|
'org.apache.mobilespec',
|
||||||
'com.floors42.package',
|
'com.example',
|
||||||
'ball8.ball8.ball8ball'
|
'com.floors42.package',
|
||||||
];
|
'ball8.ball8.ball8ball'
|
||||||
var invalid = [
|
];
|
||||||
'',
|
valid.forEach(function (package_name) {
|
||||||
'com.class.is.bad',
|
it('Test#001 : should accept ' + package_name, function (done) {
|
||||||
'0com.example.mobilespec',
|
create.validatePackageName(package_name).fail(fail).done(done);
|
||||||
'c-m.e@a!p%e.mobilespec',
|
|
||||||
'notenoughdots',
|
|
||||||
'.starts.with.a.dot',
|
|
||||||
'ends.with.a.dot.',
|
|
||||||
'_underscore.anything',
|
|
||||||
'underscore._something',
|
|
||||||
'_underscore._all._the._things',
|
|
||||||
'8.ball',
|
|
||||||
'8ball.ball',
|
|
||||||
'ball8.8ball',
|
|
||||||
'ball8.com.8ball'
|
|
||||||
];
|
|
||||||
|
|
||||||
valid.forEach(function (package_name) {
|
|
||||||
it('Test#001 : should accept ' + package_name, function (done) {
|
|
||||||
return create.validatePackageName(package_name).then(function () {
|
|
||||||
// resolved
|
|
||||||
done();
|
|
||||||
}).fail(function (err) {
|
|
||||||
expect(err).toBeUndefined();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
invalid.forEach(function (package_name) {
|
describe('failure cases (invalid package names)', function () {
|
||||||
it('Test#002 : should reject ' + package_name, function (done) {
|
it('should reject empty package names', function (done) {
|
||||||
return create.validatePackageName(package_name).then(function () {
|
create.validatePackageName('').then(fail).fail(function (err) {
|
||||||
// shouldn't be here
|
|
||||||
expect(true).toBe(false);
|
|
||||||
}).fail(function (err) {
|
|
||||||
expect(err).toBeDefined();
|
expect(err).toBeDefined();
|
||||||
done();
|
expect(err.message).toContain('Error validating package name');
|
||||||
});
|
}).done(done);
|
||||||
|
});
|
||||||
|
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 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', 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 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 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 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);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('validateProjectName', function () {
|
describe('validateProjectName helper method', function () {
|
||||||
var valid = [
|
describe('happy path (valid project names)', function () {
|
||||||
'mobilespec',
|
var valid = [
|
||||||
'package_name',
|
'mobilespec',
|
||||||
'PackageName',
|
'package_name',
|
||||||
'CordovaLib'
|
'PackageName',
|
||||||
];
|
'CordovaLib'
|
||||||
var invalid = [
|
];
|
||||||
'',
|
valid.forEach(function (project_name) {
|
||||||
'0startswithdigit',
|
it('Test#003 : should accept ' + project_name, function (done) {
|
||||||
'CordovaActivity'
|
create.validateProjectName(project_name).fail(fail).done(done);
|
||||||
];
|
|
||||||
|
|
||||||
valid.forEach(function (project_name) {
|
|
||||||
it('Test#003 : should accept ' + project_name, function (done) {
|
|
||||||
return create.validateProjectName(project_name).then(function () {
|
|
||||||
// resolved
|
|
||||||
done();
|
|
||||||
}).fail(function (err) {
|
|
||||||
expect(err).toBeUndefined();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('failure cases (invalid project names)', function () {
|
||||||
invalid.forEach(function (project_name) {
|
it('should reject empty project names', function (done) {
|
||||||
it('Test#004 : should reject ' + project_name, function (done) {
|
create.validateProjectName('').then(fail).fail(function (err) {
|
||||||
return create.validateProjectName(project_name).then(function () {
|
|
||||||
// shouldn't be here
|
|
||||||
expect(true).toBe(false);
|
|
||||||
}).fail(function (err) {
|
|
||||||
expect(err).toBeDefined();
|
expect(err).toBeDefined();
|
||||||
done();
|
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();
|
||||||
|
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();
|
||||||
|
expect(err.message).toContain('Project name must not begin with a number');
|
||||||
|
}).done(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('main method', function () {
|
||||||
|
var config_mock;
|
||||||
|
var events_mock;
|
||||||
|
var Manifest_mock = function () {};
|
||||||
|
var revert_manifest_mock;
|
||||||
|
var project_path = path.join('some', 'path');
|
||||||
|
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.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());
|
||||||
|
spyOn(create, 'validateProjectName').and.returnValue(Q());
|
||||||
|
spyOn(create, 'setShellFatal').and.callFake(function (noop, cb) { cb(); });
|
||||||
|
spyOn(create, 'copyJsAndLibrary');
|
||||||
|
spyOn(create, 'copyScripts');
|
||||||
|
spyOn(create, 'copyBuildRules');
|
||||||
|
spyOn(create, 'writeProjectProperties');
|
||||||
|
spyOn(create, 'prepBuildFiles');
|
||||||
|
revert_manifest_mock = create.__set__('AndroidManifest', Manifest_mock);
|
||||||
|
spyOn(fs, 'existsSync').and.returnValue(false);
|
||||||
|
spyOn(shell, 'cp');
|
||||||
|
spyOn(shell, 'mkdir');
|
||||||
|
spyOn(shell, 'sed');
|
||||||
|
config_mock = jasmine.createSpyObj('ConfigParser mock instance', ['packageName', 'name', 'android_activityName']);
|
||||||
|
events_mock = jasmine.createSpyObj('EventEmitter mock instance', ['emit']);
|
||||||
|
spyOn(check_reqs, 'get_target').and.returnValue(fake_android_target);
|
||||||
|
});
|
||||||
|
afterEach(function () {
|
||||||
|
revert_manifest_mock();
|
||||||
|
});
|
||||||
|
describe('parameter values and defaults', function () {
|
||||||
|
it('should have a default package name of my.cordova.project', function (done) {
|
||||||
|
config_mock.packageName.and.returnValue(undefined);
|
||||||
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
|
expect(create.validatePackageName).toHaveBeenCalledWith('my.cordova.project');
|
||||||
|
}).fail(fail).done(done);
|
||||||
|
});
|
||||||
|
it('should use the ConfigParser-provided package name, if exists', function (done) {
|
||||||
|
config_mock.packageName.and.returnValue('org.apache.cordova');
|
||||||
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
|
expect(create.validatePackageName).toHaveBeenCalledWith('org.apache.cordova');
|
||||||
|
}).fail(fail).done(done);
|
||||||
|
});
|
||||||
|
it('should have a default project name of CordovaExample', function (done) {
|
||||||
|
config_mock.name.and.returnValue(undefined);
|
||||||
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
|
expect(create.validateProjectName).toHaveBeenCalledWith('CordovaExample');
|
||||||
|
}).fail(fail).done(done);
|
||||||
|
});
|
||||||
|
it('should use the ConfigParser-provided project name, if exists', function (done) {
|
||||||
|
config_mock.name.and.returnValue('MySweetAppName');
|
||||||
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
|
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) {
|
||||||
|
config_mock.name.and.returnValue('応応応応 hello 用用用用');
|
||||||
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
|
expect(create.validateProjectName).toHaveBeenCalledWith('_____hello_____');
|
||||||
|
}).fail(fail).done(done);
|
||||||
|
});
|
||||||
|
it('should have a default activity name of MainActivity', function (done) {
|
||||||
|
config_mock.android_activityName.and.returnValue(undefined);
|
||||||
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
|
expect(Manifest_mock.prototype.setName).toHaveBeenCalledWith('MainActivity');
|
||||||
|
}).fail(fail).done(done);
|
||||||
|
});
|
||||||
|
it('should use the activityName provided via options parameter, if exists', function (done) {
|
||||||
|
config_mock.android_activityName.and.returnValue(undefined);
|
||||||
|
create.create(project_path, config_mock, {activityName: 'AwesomeActivity'}, events_mock).then(function () {
|
||||||
|
expect(Manifest_mock.prototype.setName).toHaveBeenCalledWith('AwesomeActivity');
|
||||||
|
}).fail(fail).done(done);
|
||||||
|
});
|
||||||
|
it('should use the ConfigParser-provided activity name, if exists', function (done) {
|
||||||
|
config_mock.android_activityName.and.returnValue('AmazingActivity');
|
||||||
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
|
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) {
|
||||||
|
fs.existsSync.and.returnValue(true);
|
||||||
|
create.create(project_path, config_mock, {}, events_mock).then(fail).fail(function (err) {
|
||||||
|
expect(err).toBeDefined();
|
||||||
|
expect(err.message).toContain('Project already exists!');
|
||||||
|
}).done(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
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 () {
|
||||||
|
expect(shell.cp).toHaveBeenCalledWith('-r', path.join('/template/path', 'assets'), project_path);
|
||||||
|
expect(shell.cp).toHaveBeenCalledWith('-r', path.join('/template/path', 'res'), project_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 () {
|
||||||
|
expect(shell.cp).toHaveBeenCalledWith('-r', path.join(default_templates, 'assets'), project_path);
|
||||||
|
expect(shell.cp).toHaveBeenCalledWith('-r', path.join(default_templates, 'res'), project_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 () {
|
||||||
|
expect(create.copyJsAndLibrary).toHaveBeenCalled();
|
||||||
|
}).fail(fail).done(done);
|
||||||
|
});
|
||||||
|
it('should create a java src directory based on the provided project package name', function (done) {
|
||||||
|
config_mock.packageName.and.returnValue('org.apache.cordova');
|
||||||
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
|
expect(shell.mkdir).toHaveBeenCalledWith('-p', path.join(project_path, 'src', '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) {
|
||||||
|
config_mock.packageName.and.returnValue('org.apache.cordova');
|
||||||
|
config_mock.android_activityName.and.returnValue('CEEDEEVEE');
|
||||||
|
var activity_path = path.join(project_path, 'src', 'org', 'apache', 'cordova', 'CEEDEEVEE.java');
|
||||||
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
|
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) {
|
||||||
|
config_mock.name.and.returnValue('IncredibleApp');
|
||||||
|
create.create(project_path, config_mock, {}, events_mock).then(function () {
|
||||||
|
expect(shell.sed).toHaveBeenCalledWith('-i', /__NAME__/, 'IncredibleApp', path.join(project_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 () {
|
||||||
|
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 () {
|
||||||
|
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 () {
|
||||||
|
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 () {
|
||||||
|
expect(create.prepBuildFiles).toHaveBeenCalledWith(project_path);
|
||||||
|
}).fail(fail).done(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user