Initial commit

Signed-off-by: Chris Cromer <chris@cromer.cl>
This commit is contained in:
2018-10-07 21:10:38 -03:00
commit 27c42a55c8
833 changed files with 113813 additions and 0 deletions

View 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.
*/
var path = require('path');
var AndroidProject = require('../../bin/templates/cordova/lib/AndroidProject');
var android_project = path.join(__dirname, '../fixtures/android_project');
describe('AndroidProject class', function () {
describe('getPackageName method', function () {
it('Test#001 : should return an android project\'s proper package name', function () {
expect(AndroidProject.getProjectFile(android_project).getPackageName())
.toEqual('com.alunny.childapp');
});
});
});

View File

@@ -0,0 +1,16 @@
var path = require('path');
var AndroidStudio = require('../../bin/templates/cordova/lib/AndroidStudio');
describe('AndroidStudio module', function () {
it('should return true for Android Studio project', function () {
var root = path.join(__dirname, '../fixtures/android_studio_project/');
var isAndStud = AndroidStudio.isAndroidStudioProject(root);
expect(isAndStud).toBe(true);
});
it('should return false non Android Studio project', function () {
var root = path.join(__dirname, '../fixtures/android_project/');
var isAndStud = AndroidStudio.isAndroidStudioProject(root);
expect(isAndStud).toBe(false);
});
});

74
node_modules/cordova-android/spec/unit/Api.spec.js generated vendored Normal file
View File

@@ -0,0 +1,74 @@
/**
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 Q = require('q');
var os = require('os');
var path = require('path');
var common = require('cordova-common');
var rewire = require('rewire');
var AndroidProject = require('../../bin/templates/cordova/lib/AndroidProject');
var builders = require('../../bin/templates/cordova/lib/builders/builders');
var PluginInfo = common.PluginInfo;
var FIXTURES = path.join(__dirname, '../e2e/fixtures');
var FAKE_PROJECT_DIR = path.join(os.tmpdir(), 'plugin-test-project');
describe('addPlugin method', function () {
var api, fail, gradleBuilder, oldClean;
var Api = rewire('../../bin/templates/cordova/Api');
beforeEach(function () {
var pluginManager = jasmine.createSpyObj('pluginManager', ['addPlugin']);
pluginManager.addPlugin.and.returnValue(Q());
spyOn(common.PluginManager, 'get').and.returnValue(pluginManager);
var projectSpy = jasmine.createSpyObj('AndroidProject', ['getPackageName', 'write', 'isClean']);
spyOn(AndroidProject, 'getProjectFile').and.returnValue(projectSpy);
oldClean = Api.__get__('Api.prototype.clean');
Api.__set__('Api.prototype.clean', Q);
api = new Api('android', FAKE_PROJECT_DIR);
fail = jasmine.createSpy('fail');
gradleBuilder = jasmine.createSpyObj('gradleBuilder', ['prepBuildFiles']);
spyOn(builders, 'getBuilder').and.returnValue(gradleBuilder);
});
afterEach(function () {
Api.__set__('Api.prototype.clean', oldClean);
});
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();
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();
expect(gradleBuilder.prepBuildFiles).not.toHaveBeenCalled();
done();
});
});
});

View File

@@ -0,0 +1,124 @@
/**
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 android_sdk = require('../../bin/templates/cordova/lib/android_sdk');
var superspawn = require('cordova-common').superspawn;
var fs = require('fs');
var path = require('path');
var Q = require('q');
describe('android_sdk', function () {
describe('list_targets_with_android', function () {
it('should invoke `android` with the `list target` command and _not_ the `list targets` command, as the plural form is not supported in some Android SDK Tools versions', function () {
var deferred = Q.defer();
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
android_sdk.list_targets_with_android();
expect(superspawn.spawn).toHaveBeenCalledWith('android', ['list', 'target']);
});
it('should parse and return results from `android list targets` command', function (done) {
var deferred = Q.defer();
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
deferred.resolve(fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.2-android_list_targets.txt'), 'utf-8'));
return android_sdk.list_targets_with_android().then(function (list) {
[ 'Google Inc.:Google APIs:23',
'Google Inc.:Google APIs:22',
'Google Inc.:Google APIs:21',
'android-25',
'android-24',
'android-N',
'android-23',
'android-MNC',
'android-22',
'android-21',
'android-20' ].forEach(function (target) { expect(list).toContain(target); });
}).fail(function (err) {
console.log(err);
expect(err).toBeUndefined();
}).fin(function () {
done();
});
});
});
describe('list_targets_with_avdmanager', function () {
it('should parse and return results from `avdmanager list target` command', function (done) {
var deferred = Q.defer();
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
deferred.resolve(fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.3-avdmanager_list_target.txt'), 'utf-8'));
return android_sdk.list_targets_with_avdmanager().then(function (list) {
expect(list).toContain('android-25');
}).fail(function (err) {
console.log(err);
expect(err).toBeUndefined();
}).fin(function () {
done();
});
});
});
describe('list_targets', function () {
it('should parse Android SDK installed target information with `avdmanager` command first', function () {
var deferred = Q.defer();
var avdmanager_spy = spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(deferred.promise);
android_sdk.list_targets();
expect(avdmanager_spy).toHaveBeenCalled();
});
it('should parse Android SDK installed target information with `android` command if list_targets_with_avdmanager fails with ENOENT', function (done) {
var deferred = Q.defer();
spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(deferred.promise);
deferred.reject({
code: 'ENOENT'
});
var twoferred = Q.defer();
twoferred.resolve(['target1']);
var avdmanager_spy = spyOn(android_sdk, 'list_targets_with_android').and.returnValue(twoferred.promise);
return android_sdk.list_targets().then(function (targets) {
expect(avdmanager_spy).toHaveBeenCalled();
expect(targets[0]).toEqual('target1');
done();
});
});
it('should parse Android SDK installed target information with `android` command if list_targets_with_avdmanager fails with not-recognized error (Windows)', function (done) {
var deferred = Q.defer();
spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(deferred.promise);
deferred.reject({
code: 1,
stderr: "'avdmanager' is not recognized as an internal or external commmand,\r\noperable program or batch file.\r\n"
});
var twoferred = Q.defer();
twoferred.resolve(['target1']);
var avdmanager_spy = spyOn(android_sdk, 'list_targets_with_android').and.returnValue(twoferred.promise);
return android_sdk.list_targets().then(function (targets) {
expect(avdmanager_spy).toHaveBeenCalled();
expect(targets[0]).toEqual('target1');
done();
});
});
it('should throw an error if no Android targets were found.', function (done) {
var deferred = Q.defer();
spyOn(android_sdk, 'list_targets_with_avdmanager').and.returnValue(deferred.promise);
deferred.resolve([]);
return android_sdk.list_targets().then(function (targets) {
done.fail();
}).catch(function (err) {
expect(err).toBeDefined();
expect(err.message).toContain('No android targets (SDKs) installed!');
done();
});
});
});
});

View File

@@ -0,0 +1,28 @@
var Gradle_builder = require('../../../bin/templates/cordova/lib/builders/GradleBuilder.js');
var fs = require('fs');
var Q = require('q');
var superspawn = require('cordova-common').superspawn;
var builder;
describe('Gradle Builder', function () {
beforeEach(function () {
spyOn(fs, 'existsSync').and.returnValue(true);
builder = new Gradle_builder('/root');
var deferred = Q.defer();
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
});
describe('runGradleWrapper method', function () {
it('should run the provided gradle command if a gradle wrapper does not already exist', function () {
fs.existsSync.and.returnValue(false);
builder.runGradleWrapper('/my/sweet/gradle');
expect(superspawn.spawn).toHaveBeenCalledWith('/my/sweet/gradle', jasmine.any(Array), jasmine.any(Object));
});
it('should do nothing if a gradle wrapper exists in the project directory', function () {
fs.existsSync.and.returnValue(true);
builder.runGradleWrapper('/my/sweet/gradle');
expect(superspawn.spawn).not.toHaveBeenCalledWith('/my/sweet/gradle', jasmine.any(Array), jasmine.any(Object));
});
});
});

View File

@@ -0,0 +1,239 @@
/**
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 check_reqs = require('../../bin/templates/cordova/lib/check_reqs');
var android_sdk = require('../../bin/templates/cordova/lib/android_sdk');
var shelljs = require('shelljs');
var fs = require('fs');
var path = require('path');
var Q = require('q');
describe('check_reqs', function () {
var original_env;
beforeAll(function () {
original_env = Object.create(process.env);
});
afterEach(function () {
Object.keys(original_env).forEach(function (k) {
process.env[k] = original_env[k];
});
});
describe('check_android', function () {
describe('set ANDROID_HOME if not set', function () {
beforeEach(function () {
delete process.env.ANDROID_HOME;
});
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) {
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) {
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();
});
});
});
describe('if some Android tooling exists on the PATH', function () {
beforeEach(function () {
spyOn(fs, 'realpathSync').and.callFake(function (path) {
return path;
});
});
it('should set ANDROID_HOME based on `android` command if command exists in a SDK-like directory structure', function (done) {
spyOn(fs, 'existsSync').and.returnValue(true);
spyOn(shelljs, 'which').and.callFake(function (cmd) {
if (cmd === 'android') {
return '/android/sdk/tools/android';
} else {
return null;
}
});
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) {
spyOn(shelljs, 'which').and.callFake(function (cmd) {
if (cmd === 'android') {
return '/just/some/random/path/android';
} else {
return null;
}
});
return check_reqs.check_android().then(function () {
done.fail();
}).fail(function (err) {
expect(err).toBeDefined();
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) {
spyOn(fs, 'existsSync').and.returnValue(true);
spyOn(shelljs, 'which').and.callFake(function (cmd) {
if (cmd === 'adb') {
return '/android/sdk/platform-tools/adb';
} else {
return null;
}
});
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) {
spyOn(shelljs, 'which').and.callFake(function (cmd) {
if (cmd === 'adb') {
return '/just/some/random/path/adb';
} else {
return null;
}
});
return check_reqs.check_android().then(function () {
done.fail();
}).fail(function (err) {
expect(err).toBeDefined();
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) {
spyOn(fs, 'existsSync').and.returnValue(true);
spyOn(shelljs, 'which').and.callFake(function (cmd) {
if (cmd === 'avdmanager') {
return '/android/sdk/tools/bin/avdmanager';
} else {
return null;
}
});
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) {
spyOn(shelljs, 'which').and.callFake(function (cmd) {
if (cmd === 'avdmanager') {
return '/just/some/random/path/avdmanager';
} else {
return null;
}
});
return check_reqs.check_android().then(function () {
done.fail();
}).fail(function (err) {
expect(err).toBeDefined();
expect(err.message).toContain('update your PATH to include valid path');
done();
});
});
});
});
describe('set PATH for various Android binaries if not available', function () {
beforeEach(function () {
spyOn(shelljs, 'which').and.returnValue(null);
process.env.ANDROID_HOME = 'let the children play';
spyOn(fs, 'existsSync').and.returnValue(true);
});
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) {
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);
});
});
});
});
describe('get_target', function () {
it('should retrieve target from framework project.properties file', function () {
var target = check_reqs.get_target();
expect(target).toBeDefined();
expect(target).toContain('android-');
});
});
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) {
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('you are my fire');
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) {
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();
expect(err.message).toContain('Please install Android target');
done();
});
});
});
});

282
node_modules/cordova-android/spec/unit/create.spec.js generated vendored Normal file
View File

@@ -0,0 +1,282 @@
/**
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 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('validatePackageName helper method', function () {
describe('happy path (valid package names)', function () {
var valid = [
'org.apache.mobilespec',
'com.example',
'com.floors42.package',
'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);
});
});
});
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();
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 helper method', function () {
describe('happy path (valid project names)', function () {
var valid = [
'mobilespec',
'package_name',
'PackageName',
'CordovaLib'
];
valid.forEach(function (project_name) {
it('Test#003 : should accept ' + project_name, function (done) {
create.validateProjectName(project_name).fail(fail).done(done);
});
});
});
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();
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 app_path = path.join(project_path, 'app', 'src', 'main');
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', 'android_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'), 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 () {
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 () {
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(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) {
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 () {
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(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 () {
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, 'studio');
}).fail(fail).done(done);
});
});
});
});

224
node_modules/cordova-android/spec/unit/emulator.spec.js generated vendored Normal file
View File

@@ -0,0 +1,224 @@
/**
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 emu = require('../../bin/templates/cordova/lib/emulator');
var check_reqs = require('../../bin/templates/cordova/lib/check_reqs');
var superspawn = require('cordova-common').superspawn;
var Q = require('q');
var fs = require('fs');
var path = require('path');
var shelljs = require('shelljs');
describe('emulator', function () {
describe('list_images_using_avdmanager', function () {
it('should properly parse details of SDK Tools 25.3.1 `avdmanager` output', function (done) {
var deferred = Q.defer();
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
deferred.resolve(fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.3-avdmanager_list_avd.txt'), 'utf-8'));
return emu.list_images_using_avdmanager().then(function (list) {
expect(list).toBeDefined();
expect(list[0].name).toEqual('nexus5-5.1');
expect(list[0].target).toEqual('Android 5.1 (API level 22)');
expect(list[1].device).toEqual('pixel (Google)');
expect(list[2].abi).toEqual('default/x86_64');
}).fail(function (err) {
expect(err).toBeUndefined();
}).fin(function () {
done();
});
});
});
describe('list_images_using_android', function () {
it('should invoke `android` with the `list avd` command and _not_ the `list avds` command, as the plural form is not supported in some Android SDK Tools versions', function () {
var deferred = Q.defer();
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
emu.list_images_using_android();
expect(superspawn.spawn).toHaveBeenCalledWith('android', ['list', 'avd']);
});
it('should properly parse details of SDK Tools pre-25.3.1 `android list avd` output', function (done) {
var deferred = Q.defer();
spyOn(superspawn, 'spawn').and.returnValue(deferred.promise);
deferred.resolve(fs.readFileSync(path.join('spec', 'fixtures', 'sdk25.2-android_list_avd.txt'), 'utf-8'));
return emu.list_images_using_android().then(function (list) {
expect(list).toBeDefined();
expect(list[0].name).toEqual('QWR');
expect(list[0].device).toEqual('Nexus 5 (Google)');
expect(list[0].path).toEqual('/Users/shazron/.android/avd/QWR.avd');
expect(list[0].target).toEqual('Android 7.1.1 (API level 25)');
expect(list[0].abi).toEqual('google_apis/x86_64');
expect(list[0].skin).toEqual('1080x1920');
}).fail(function (err) {
expect(err).toBeUndefined();
}).fin(function () {
done();
});
});
});
describe('list_images', function () {
beforeEach(function () {
spyOn(fs, 'realpathSync').and.callFake(function (cmd) {
return cmd;
});
});
it('should try to parse AVD information using `avdmanager` first', function (done) {
spyOn(shelljs, 'which').and.callFake(function (cmd) {
if (cmd === 'avdmanager') {
return true;
} else {
return false;
}
});
var deferred = Q.defer();
var avdmanager_spy = spyOn(emu, 'list_images_using_avdmanager').and.returnValue(deferred.promise);
deferred.resolve([]);
emu.list_images().then(function () {
expect(avdmanager_spy).toHaveBeenCalled();
}).fail(function (err) {
expect(err).toBeUndefined();
}).fin(function () {
done();
});
});
it('should delegate to `android` if `avdmanager` cant be found and `android` can', function (done) {
spyOn(shelljs, 'which').and.callFake(function (cmd) {
if (cmd === 'avdmanager') {
return false;
} else {
return true;
}
});
var deferred = Q.defer();
var android_spy = spyOn(emu, 'list_images_using_android').and.returnValue(deferred.promise);
deferred.resolve([]);
emu.list_images().then(function () {
expect(android_spy).toHaveBeenCalled();
}).fail(function (err) {
expect(err).toBeUndefined();
}).fin(function () {
done();
});
});
it('should correct api level information and fill in the blanks about api level if exists', function (done) {
spyOn(shelljs, 'which').and.callFake(function (cmd) {
if (cmd === 'avdmanager') {
return true;
} else {
return false;
}
});
var deferred = Q.defer();
spyOn(emu, 'list_images_using_avdmanager').and.returnValue(deferred.promise);
deferred.resolve([
{
name: 'Pixel_7.0',
device: 'pixel (Google)',
path: '/Users/maj/.android/avd/Pixel_7.0.avd',
abi: 'google_apis/x86_64',
target: 'Android 7.0 (API level 24)'
}, {
name: 'Pixel_8.0',
device: 'pixel (Google)',
path: '/Users/maj/.android/avd/Pixel_8.0.avd',
abi: 'google_apis/x86',
target: 'Android API 26'
}
]);
emu.list_images().then(function (avds) {
expect(avds[1].target).toContain('Android 8');
expect(avds[1].target).toContain('API level 26');
}).fail(function (err) {
expect(err).toBeUndefined();
}).fin(function () {
done();
});
});
it('should throw an error if neither `avdmanager` nor `android` are able to be found', function (done) {
spyOn(shelljs, 'which').and.returnValue(false);
return emu.list_images().catch(function (err) {
expect(err).toBeDefined();
expect(err.message).toContain('Could not find either `android` or `avdmanager`');
done();
});
});
});
describe('best_image', function () {
var avds_promise;
var target_mock;
beforeEach(function () {
avds_promise = Q.defer();
spyOn(emu, 'list_images').and.returnValue(avds_promise.promise);
target_mock = spyOn(check_reqs, 'get_target').and.returnValue('android-26');
});
it('should return undefined if there are no defined AVDs', function (done) {
avds_promise.resolve([]);
emu.best_image().then(function (best_avd) {
expect(best_avd).toBeUndefined();
}).fail(function (err) {
expect(err).toBeUndefined();
}).fin(done);
});
it('should return the first available image if there is no available target information for existing AVDs', function (done) {
var fake_avd = { name: 'MyFakeAVD' };
var second_fake_avd = { name: 'AnotherAVD' };
avds_promise.resolve([fake_avd, second_fake_avd]);
emu.best_image().then(function (best_avd) {
expect(best_avd).toBe(fake_avd);
}).fail(function (err) {
expect(err).toBeUndefined();
}).fin(done);
});
it('should return the first AVD for the API level that matches the project target', function (done) {
target_mock.and.returnValue('android-25');
var fake_avd = { name: 'MyFakeAVD', target: 'Android 7.0 (API level 24)' };
var second_fake_avd = { name: 'AnotherAVD', target: 'Android 7.1 (API level 25)' };
var third_fake_avd = { name: 'AVDThree', target: 'Android 8.0 (API level 26)' };
avds_promise.resolve([fake_avd, second_fake_avd, third_fake_avd]);
emu.best_image().then(function (best_avd) {
expect(best_avd).toBe(second_fake_avd);
}).fail(function (err) {
expect(err).toBeUndefined();
}).fin(done);
});
it('should return the AVD with API level that is closest to the project target API level, without going over', function (done) {
target_mock.and.returnValue('android-26');
var fake_avd = { name: 'MyFakeAVD', target: 'Android 7.0 (API level 24)' };
var second_fake_avd = { name: 'AnotherAVD', target: 'Android 7.1 (API level 25)' };
var third_fake_avd = { name: 'AVDThree', target: 'Android 99.0 (API level 134)' };
avds_promise.resolve([fake_avd, second_fake_avd, third_fake_avd]);
emu.best_image().then(function (best_avd) {
expect(best_avd).toBe(second_fake_avd);
}).fail(function (err) {
expect(err).toBeUndefined();
}).fin(done);
});
it('should not try to compare API levels when an AVD definition is missing API level info', function (done) {
avds_promise.resolve([ { name: 'Samsung_S8_API_26',
device: 'Samsung S8+ (User)',
path: '/Users/daviesd/.android/avd/Samsung_S8_API_26.avd',
abi: 'google_apis/x86',
target: 'Android 8.0'
}]);
emu.best_image().then(function (best_avd) {
expect(best_avd).toBeDefined();
}).fail(function (err) {
expect(err).toBeUndefined();
}).fin(done);
});
});
});

8
node_modules/cordova-android/spec/unit/jasmine.json generated vendored Normal file
View File

@@ -0,0 +1,8 @@
{
"spec_dir": "spec",
"spec_files": [
"unit/**/*[sS]pec.js"
],
"stopSpecOnExpectationFailure": false,
"random": true
}

View File

@@ -0,0 +1,171 @@
/*
*
*
* Licensed 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 rewire = require('rewire');
var common = rewire('../../../bin/templates/cordova/lib/pluginHandlers');
var path = require('path');
var fs = require('fs');
var osenv = require('os');
var shell = require('shelljs');
var test_dir = path.join(osenv.tmpdir(), 'test_plugman');
var project_dir = path.join(test_dir, 'project');
var src = path.join(project_dir, 'src');
var dest = path.join(project_dir, 'dest');
var java_dir = path.join(src, 'one', 'two', 'three');
var java_file = path.join(java_dir, 'test.java');
var symlink_file = path.join(java_dir, 'symlink');
var non_plugin_file = path.join(osenv.tmpdir(), 'non_plugin_file');
var copyFile = common.__get__('copyFile');
var deleteJava = common.__get__('deleteJava');
var copyNewFile = common.__get__('copyNewFile');
describe('common platform handler', function () {
describe('copyFile', function () {
it('Test#001 : should throw if source path not found', function () {
shell.rm('-rf', src);
expect(function () { copyFile(test_dir, src, project_dir, dest); })
.toThrow(new Error('"' + src + '" not found!'));
});
it('Test#002 : should throw if src not in plugin directory', function () {
shell.mkdir('-p', project_dir);
fs.writeFileSync(non_plugin_file, 'contents', 'utf-8');
var outside_file = '../non_plugin_file';
expect(function () { copyFile(test_dir, outside_file, project_dir, dest); })
.toThrow(new Error('File "' + path.resolve(test_dir, outside_file) + '" is located outside the plugin directory "' + test_dir + '"'));
shell.rm('-rf', test_dir);
});
it('Test#003 : should allow symlink src, if inside plugin', function () {
shell.mkdir('-p', java_dir);
fs.writeFileSync(java_file, 'contents', 'utf-8');
// This will fail on windows if not admin - ignore the error in that case.
if (ignoreEPERMonWin32(java_file, symlink_file)) {
return;
}
copyFile(test_dir, symlink_file, project_dir, dest);
shell.rm('-rf', project_dir);
});
it('Test#004 : should throw if symlink is linked to a file outside the plugin', function () {
shell.mkdir('-p', java_dir);
fs.writeFileSync(non_plugin_file, 'contents', 'utf-8');
// This will fail on windows if not admin - ignore the error in that case.
if (ignoreEPERMonWin32(non_plugin_file, symlink_file)) {
return;
}
expect(function () { copyFile(test_dir, symlink_file, project_dir, dest); })
.toThrow(new Error('File "' + path.resolve(test_dir, symlink_file) + '" is located outside the plugin directory "' + test_dir + '"'));
shell.rm('-rf', project_dir);
});
it('Test#005 : should throw if dest is outside the project directory', function () {
shell.mkdir('-p', java_dir);
fs.writeFileSync(java_file, 'contents', 'utf-8');
expect(function () { copyFile(test_dir, java_file, project_dir, non_plugin_file); })
.toThrow(new Error('Destination "' + path.resolve(project_dir, non_plugin_file) + '" for source file "' + path.resolve(test_dir, java_file) + '" is located outside the project'));
shell.rm('-rf', project_dir);
});
it('Test#006 : should call mkdir -p on target path', function () {
shell.mkdir('-p', java_dir);
fs.writeFileSync(java_file, 'contents', 'utf-8');
var s = spyOn(shell, 'mkdir').and.callThrough();
var resolvedDest = path.resolve(project_dir, dest);
copyFile(test_dir, java_file, project_dir, dest);
expect(s).toHaveBeenCalled();
expect(s).toHaveBeenCalledWith('-p', path.dirname(resolvedDest));
shell.rm('-rf', project_dir);
});
it('Test#007 : should call cp source/dest paths', function () {
shell.mkdir('-p', java_dir);
fs.writeFileSync(java_file, 'contents', 'utf-8');
var s = spyOn(shell, 'cp').and.callThrough();
var resolvedDest = path.resolve(project_dir, dest);
copyFile(test_dir, java_file, project_dir, dest);
expect(s).toHaveBeenCalled();
expect(s).toHaveBeenCalledWith('-f', java_file, resolvedDest);
shell.rm('-rf', project_dir);
});
});
describe('copyNewFile', function () {
it('Test#008 : should throw if target path exists', function () {
shell.mkdir('-p', dest);
expect(function () { copyNewFile(test_dir, src, project_dir, dest); })
.toThrow(new Error('"' + dest + '" already exists!'));
shell.rm('-rf', dest);
});
});
describe('deleteJava', function () {
beforeEach(function () {
shell.mkdir('-p', java_dir);
fs.writeFileSync(java_file, 'contents', 'utf-8');
});
afterEach(function () {
shell.rm('-rf', java_dir);
});
it('Test#009 : should call fs.unlinkSync on the provided paths', function () {
var s = spyOn(fs, 'unlinkSync').and.callThrough();
deleteJava(project_dir, java_file);
expect(s).toHaveBeenCalled();
expect(s).toHaveBeenCalledWith(path.resolve(project_dir, java_file));
});
it('Test#010 : should delete empty directories after removing source code in a java src path hierarchy', function () {
deleteJava(project_dir, java_file);
expect(fs.existsSync(java_file)).not.toBe(true);
expect(fs.existsSync(java_dir)).not.toBe(true);
expect(fs.existsSync(path.join(src, 'one'))).not.toBe(true);
});
it('Test#011 : should never delete the top-level src directory, even if all plugins added were removed', function () {
deleteJava(project_dir, java_file);
expect(fs.existsSync(src)).toBe(true);
});
});
});
function ignoreEPERMonWin32 (symlink_src, symlink_dest) {
try {
fs.symlinkSync(symlink_src, symlink_dest);
} catch (e) {
if (process.platform === 'win32' && e.message.indexOf('Error: EPERM, operation not permitted' > -1)) {
return true;
}
throw e;
}
return false;
}

View File

@@ -0,0 +1,391 @@
/**
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 rewire = require('rewire');
var common = rewire('../../../bin/templates/cordova/lib/pluginHandlers');
var android = common.__get__('handlers');
var path = require('path');
var fs = require('fs');
var shell = require('shelljs');
var os = require('os');
var temp = path.join(os.tmpdir(), 'plugman');
var plugins_dir = path.join(temp, 'cordova/plugins');
var dummyplugin = path.join(__dirname, '../../fixtures/org.test.plugins.dummyplugin');
var faultyplugin = path.join(__dirname, '../../fixtures/org.test.plugins.faultyplugin');
var android_project = path.join(__dirname, '../../fixtures/android_project/*');
var PluginInfo = require('cordova-common').PluginInfo;
var AndroidProject = require('../../../bin/templates/cordova/lib/AndroidProject');
var dummyPluginInfo = new PluginInfo(dummyplugin);
var valid_source = dummyPluginInfo.getSourceFiles('android');
var valid_resources = dummyPluginInfo.getResourceFiles('android');
var valid_libs = dummyPluginInfo.getLibFiles('android');
var faultyPluginInfo = new PluginInfo(faultyplugin);
var invalid_source = faultyPluginInfo.getSourceFiles('android');
describe('android project handler', function () {
describe('installation', function () {
var copyFileOrig = common.__get__('copyFile');
var copyFileSpy = jasmine.createSpy('copyFile');
var dummyProject;
beforeEach(function () {
shell.mkdir('-p', temp);
dummyProject = AndroidProject.getProjectFile(temp);
copyFileSpy.calls.reset();
common.__set__('copyFile', copyFileSpy);
});
afterEach(function () {
shell.rm('-rf', temp);
common.__set__('copyFile', copyFileOrig);
});
describe('of <lib-file> elements', function () {
it('Test#001 : should copy files', function () {
android['lib-file'].install(valid_libs[0], dummyPluginInfo, dummyProject);
expect(copyFileSpy).toHaveBeenCalledWith(dummyplugin, 'src/android/TestLib.jar', temp, path.join('libs', 'TestLib.jar'), false);
});
it('Test#002 : should copy files for Android Studio projects', function () {
android['lib-file'].install(valid_libs[0], dummyPluginInfo, dummyProject, {android_studio: true});
expect(copyFileSpy).toHaveBeenCalledWith(dummyplugin, 'src/android/TestLib.jar', temp, path.join('app', 'libs', 'TestLib.jar'), false);
});
});
describe('of <resource-file> elements', function () {
it('Test#003 : should copy files to the correct location on a non-Android Studio project', function () {
android['resource-file'].install(valid_resources[0], dummyPluginInfo, dummyProject);
expect(copyFileSpy).toHaveBeenCalledWith(dummyplugin, 'android-resource.xml', temp, path.join('res', 'xml', 'dummy.xml'), false);
});
});
describe('of <source-file> elements', function () {
beforeEach(function () {
shell.cp('-rf', android_project, temp);
});
it('Test#004 : should copy stuff from one location to another by calling common.copyFile', function () {
android['source-file'].install(valid_source[0], dummyPluginInfo, dummyProject);
expect(copyFileSpy)
.toHaveBeenCalledWith(dummyplugin, 'src/android/DummyPlugin.java', temp, path.join('src/com/phonegap/plugins/dummyplugin/DummyPlugin.java'), false);
});
it('Test#005 : should install source files to the right location for Android Studio projects', function () {
android['source-file'].install(valid_source[0], dummyPluginInfo, dummyProject, {android_studio: true});
expect(copyFileSpy)
.toHaveBeenCalledWith(dummyplugin, 'src/android/DummyPlugin.java', temp, path.join('app/src/main/java/com/phonegap/plugins/dummyplugin/DummyPlugin.java'), false);
});
it('Test#006 : should throw if source file cannot be found', function () {
common.__set__('copyFile', copyFileOrig);
expect(function () {
android['source-file'].install(invalid_source[0], faultyPluginInfo, dummyProject);
}).toThrow(new Error('"' + path.resolve(faultyplugin, 'src/android/NotHere.java') + '" not found!'));
});
it('Test#007 : should throw if target file already exists', function () {
// write out a file
var target = path.resolve(temp, 'src/com/phonegap/plugins/dummyplugin');
shell.mkdir('-p', target);
target = path.join(target, 'DummyPlugin.java');
fs.writeFileSync(target, 'some bs', 'utf-8');
expect(function () {
android['source-file'].install(valid_source[0], dummyPluginInfo, dummyProject);
}).toThrow(new Error('"' + target + '" already exists!'));
});
});
describe('of <framework> elements', function () {
var someString = jasmine.any(String);
var copyNewFileOrig = common.__get__('copyNewFile');
var copyNewFileSpy = jasmine.createSpy('copyNewFile');
beforeEach(function () {
shell.cp('-rf', android_project, temp);
spyOn(dummyProject, 'addSystemLibrary');
spyOn(dummyProject, 'addSubProject');
spyOn(dummyProject, 'addGradleReference');
common.__set__('copyNewFile', copyNewFileSpy);
});
afterEach(function () {
common.__set__('copyNewFile', copyNewFileOrig);
});
it('Test#008 : should throw if framework doesn\'t have "src" attribute', function () {
expect(function () { android.framework.install({}, dummyPluginInfo, dummyProject); }).toThrow();
});
it('Test#009 : should install framework without "parent" attribute into project root', function () {
var framework = {src: 'plugin-lib'};
android.framework.install(framework, dummyPluginInfo, dummyProject);
expect(dummyProject.addSystemLibrary).toHaveBeenCalledWith(dummyProject.projectDir, someString);
});
it('Test#010 : should install framework with "parent" attribute into parent framework dir', function () {
var childFramework = {src: 'plugin-lib2', parent: 'plugin-lib'};
android.framework.install(childFramework, dummyPluginInfo, dummyProject);
expect(dummyProject.addSystemLibrary).toHaveBeenCalledWith(path.resolve(dummyProject.projectDir, childFramework.parent), someString);
});
it('Test#011 : should not copy anything if "custom" attribute is not set', function () {
var framework = {src: 'plugin-lib'};
var cpSpy = spyOn(shell, 'cp');
android.framework.install(framework, dummyPluginInfo, dummyProject);
expect(dummyProject.addSystemLibrary).toHaveBeenCalledWith(someString, framework.src);
expect(cpSpy).not.toHaveBeenCalled();
});
it('Test#012 : should copy framework sources if "custom" attribute is set', function () {
var framework = {src: 'plugin-lib', custom: true};
android.framework.install(framework, dummyPluginInfo, dummyProject);
expect(dummyProject.addSubProject).toHaveBeenCalledWith(dummyProject.projectDir, someString);
expect(copyNewFileSpy).toHaveBeenCalledWith(dummyPluginInfo.dir, framework.src, dummyProject.projectDir, someString, false);
});
it('Test#013 : should install gradleReference using project.addGradleReference', function () {
var framework = {src: 'plugin-lib', custom: true, type: 'gradleReference'};
android.framework.install(framework, dummyPluginInfo, dummyProject);
expect(copyNewFileSpy).toHaveBeenCalledWith(dummyPluginInfo.dir, framework.src, dummyProject.projectDir, someString, false);
expect(dummyProject.addGradleReference).toHaveBeenCalledWith(dummyProject.projectDir, someString);
});
});
describe('of <js-module> elements', function () {
var jsModule = {src: 'www/dummyplugin.js'};
var wwwDest, platformWwwDest;
beforeEach(function () {
spyOn(fs, 'writeFileSync');
wwwDest = path.resolve(dummyProject.www, 'plugins', dummyPluginInfo.id, jsModule.src);
platformWwwDest = path.resolve(dummyProject.platformWww, 'plugins', dummyPluginInfo.id, jsModule.src);
});
it('Test#014 : should put module to both www and platform_www when options.usePlatformWww flag is specified', function () {
android['js-module'].install(jsModule, dummyPluginInfo, dummyProject, {usePlatformWww: true});
expect(fs.writeFileSync).toHaveBeenCalledWith(wwwDest, jasmine.any(String), 'utf-8');
expect(fs.writeFileSync).toHaveBeenCalledWith(platformWwwDest, jasmine.any(String), 'utf-8');
});
it('Test#015 : should put module to www only when options.usePlatformWww flag is not specified', function () {
android['js-module'].install(jsModule, dummyPluginInfo, dummyProject);
expect(fs.writeFileSync).toHaveBeenCalledWith(wwwDest, jasmine.any(String), 'utf-8');
expect(fs.writeFileSync).not.toHaveBeenCalledWith(platformWwwDest, jasmine.any(String), 'utf-8');
});
});
describe('of <asset> elements', function () {
var asset = {src: 'www/dummyPlugin.js', target: 'foo/dummy.js'};
var wwwDest; /* eslint no-unused-vars: "off" */
var platformWwwDest; /* eslint no-unused-vars: "off" */
beforeEach(function () {
wwwDest = path.resolve(dummyProject.www, asset.target);
platformWwwDest = path.resolve(dummyProject.platformWww, asset.target);
});
it('Test#016 : should put asset to both www and platform_www when options.usePlatformWww flag is specified', function () {
android.asset.install(asset, dummyPluginInfo, dummyProject, {usePlatformWww: true});
expect(copyFileSpy).toHaveBeenCalledWith(dummyPluginInfo.dir, asset.src, dummyProject.www, asset.target);
expect(copyFileSpy).toHaveBeenCalledWith(dummyPluginInfo.dir, asset.src, dummyProject.platformWww, asset.target);
});
it('Test#017 : should put asset to www only when options.usePlatformWww flag is not specified', function () {
android.asset.install(asset, dummyPluginInfo, dummyProject);
expect(copyFileSpy).toHaveBeenCalledWith(dummyPluginInfo.dir, asset.src, dummyProject.www, asset.target);
expect(copyFileSpy).not.toHaveBeenCalledWith(dummyPluginInfo.dir, asset.src, dummyProject.platformWww, asset.target);
});
});
});
describe('uninstallation', function () {
var removeFileOrig = common.__get__('removeFile');
var deleteJavaOrig = common.__get__('deleteJava');
var removeFileSpy = jasmine.createSpy('removeFile');
var deleteJavaSpy = jasmine.createSpy('deleteJava');
var dummyProject;
beforeEach(function () {
shell.mkdir('-p', temp);
shell.mkdir('-p', plugins_dir);
shell.cp('-rf', android_project, temp);
AndroidProject.purgeCache();
dummyProject = AndroidProject.getProjectFile(temp);
common.__set__('removeFile', removeFileSpy);
common.__set__('deleteJava', deleteJavaSpy);
});
afterEach(function () {
shell.rm('-rf', temp);
common.__set__('removeFile', removeFileOrig);
common.__set__('deleteJava', deleteJavaOrig);
});
describe('of <lib-file> elements', function () {
it('Test#018 : should remove jar files', function () {
android['lib-file'].install(valid_libs[0], dummyPluginInfo, dummyProject);
android['lib-file'].uninstall(valid_libs[0], dummyPluginInfo, dummyProject);
expect(removeFileSpy).toHaveBeenCalledWith(temp, path.join('libs/TestLib.jar'));
});
it('Test#019 : should remove jar files for Android Studio projects', function () {
android['lib-file'].install(valid_libs[0], dummyPluginInfo, dummyProject, {android_studio: true});
android['lib-file'].uninstall(valid_libs[0], dummyPluginInfo, dummyProject, {android_studio: true});
expect(removeFileSpy).toHaveBeenCalledWith(temp, path.join('app/libs/TestLib.jar'));
});
});
describe('of <resource-file> elements', function () {
it('Test#020 : should remove files', function () {
android['resource-file'].install(valid_resources[0], dummyPluginInfo, dummyProject);
android['resource-file'].uninstall(valid_resources[0], dummyPluginInfo, dummyProject);
expect(removeFileSpy).toHaveBeenCalledWith(temp, path.join('res/xml/dummy.xml'));
});
it('Test#021 : should remove files for Android Studio projects', function () {
android['resource-file'].install(valid_resources[0], dummyPluginInfo, dummyProject, {android_studio: true});
android['resource-file'].uninstall(valid_resources[0], dummyPluginInfo, dummyProject, {android_studio: true});
expect(removeFileSpy).toHaveBeenCalledWith(temp, path.join('app/src/main/res/xml/dummy.xml'));
});
});
describe('of <source-file> elements', function () {
it('Test#022 : should remove stuff by calling common.deleteJava', function () {
android['source-file'].install(valid_source[0], dummyPluginInfo, dummyProject);
android['source-file'].uninstall(valid_source[0], dummyPluginInfo, dummyProject);
expect(deleteJavaSpy).toHaveBeenCalledWith(temp, path.join('src/com/phonegap/plugins/dummyplugin/DummyPlugin.java'));
});
it('Test#023 : should remove stuff by calling common.deleteJava for Android Studio projects', function () {
android['source-file'].install(valid_source[0], dummyPluginInfo, dummyProject, {android_studio: true});
android['source-file'].uninstall(valid_source[0], dummyPluginInfo, dummyProject, {android_studio: true});
expect(deleteJavaSpy).toHaveBeenCalledWith(temp, path.join('app/src/main/java/com/phonegap/plugins/dummyplugin/DummyPlugin.java'));
});
});
describe('of <framework> elements', function () {
var someString = jasmine.any(String);
beforeEach(function () {
shell.mkdir(path.join(dummyProject.projectDir, dummyPluginInfo.id));
spyOn(dummyProject, 'removeSystemLibrary');
spyOn(dummyProject, 'removeSubProject');
spyOn(dummyProject, 'removeGradleReference');
});
it('Test#024 : should throw if framework doesn\'t have "src" attribute', function () {
expect(function () { android.framework.uninstall({}, dummyPluginInfo, dummyProject); }).toThrow();
});
it('Test#025 : should uninstall framework without "parent" attribute into project root', function () {
var framework = {src: 'plugin-lib'};
android.framework.uninstall(framework, dummyPluginInfo, dummyProject);
expect(dummyProject.removeSystemLibrary).toHaveBeenCalledWith(dummyProject.projectDir, someString);
});
it('Test#026 : should uninstall framework with "parent" attribute into parent framework dir', function () {
var childFramework = {src: 'plugin-lib2', parent: 'plugin-lib'};
android.framework.uninstall(childFramework, dummyPluginInfo, dummyProject);
expect(dummyProject.removeSystemLibrary).toHaveBeenCalledWith(path.resolve(dummyProject.projectDir, childFramework.parent), someString);
});
it('Test#027 : should remove framework sources if "custom" attribute is set', function () {
var framework = {src: 'plugin-lib', custom: true};
android.framework.uninstall(framework, dummyPluginInfo, dummyProject);
expect(dummyProject.removeSubProject).toHaveBeenCalledWith(dummyProject.projectDir, someString);
expect(removeFileSpy).toHaveBeenCalledWith(dummyProject.projectDir, someString);
});
it('Test#28 : should install gradleReference using project.removeGradleReference', function () {
var framework = {src: 'plugin-lib', custom: true, type: 'gradleReference'};
android.framework.uninstall(framework, dummyPluginInfo, dummyProject);
expect(removeFileSpy).toHaveBeenCalledWith(dummyProject.projectDir, someString);
expect(dummyProject.removeGradleReference).toHaveBeenCalledWith(dummyProject.projectDir, someString);
});
});
describe('of <js-module> elements', function () {
var jsModule = {src: 'www/dummyPlugin.js'};
var wwwDest;
var platformWwwDest;
beforeEach(function () {
wwwDest = path.resolve(dummyProject.www, 'plugins', dummyPluginInfo.id, jsModule.src);
platformWwwDest = path.resolve(dummyProject.platformWww, 'plugins', dummyPluginInfo.id, jsModule.src);
spyOn(shell, 'rm');
var existsSyncOrig = fs.existsSync;
spyOn(fs, 'existsSync').and.callFake(function (file) {
if ([wwwDest, platformWwwDest].indexOf(file) >= 0) return true;
return existsSyncOrig.call(fs, file);
});
});
it('Test#029 : should put module to both www and platform_www when options.usePlatformWww flag is specified', function () {
android['js-module'].uninstall(jsModule, dummyPluginInfo, dummyProject, {usePlatformWww: true});
expect(shell.rm).toHaveBeenCalledWith('-Rf', wwwDest);
expect(shell.rm).toHaveBeenCalledWith('-Rf', platformWwwDest);
});
it('Test#030 : should put module to www only when options.usePlatformWww flag is not specified', function () {
android['js-module'].uninstall(jsModule, dummyPluginInfo, dummyProject);
expect(shell.rm).toHaveBeenCalledWith('-Rf', wwwDest);
expect(shell.rm).not.toHaveBeenCalledWith('-Rf', platformWwwDest);
});
});
describe('of <asset> elements', function () {
var asset = {src: 'www/dummyPlugin.js', target: 'foo/dummy.js'};
var wwwDest, platformWwwDest;
beforeEach(function () {
wwwDest = path.resolve(dummyProject.www, asset.target);
platformWwwDest = path.resolve(dummyProject.platformWww, asset.target);
spyOn(shell, 'rm');
var existsSyncOrig = fs.existsSync;
spyOn(fs, 'existsSync').and.callFake(function (file) {
if ([wwwDest, platformWwwDest].indexOf(file) >= 0) return true;
return existsSyncOrig.call(fs, file);
});
});
it('Test#031 : should put module to both www and platform_www when options.usePlatformWww flag is specified', function () {
android.asset.uninstall(asset, dummyPluginInfo, dummyProject, {usePlatformWww: true});
expect(shell.rm).toHaveBeenCalledWith(jasmine.any(String), wwwDest);
expect(shell.rm).toHaveBeenCalledWith(jasmine.any(String), platformWwwDest);
});
it('Test#032 : should put module to www only when options.usePlatformWww flag is not specified', function () {
android.asset.uninstall(asset, dummyPluginInfo, dummyProject);
expect(shell.rm).toHaveBeenCalledWith(jasmine.any(String), wwwDest);
expect(shell.rm).not.toHaveBeenCalledWith(jasmine.any(String), platformWwwDest);
});
});
});
});

38
node_modules/cordova-android/spec/unit/run.spec.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
/**
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 rewire = require('rewire');
var run = rewire('../../bin/templates/cordova/lib/run');
var getInstallTarget = run.__get__('getInstallTarget');
describe('run', function () {
describe('getInstallTarget', function () {
var targetOpts = { target: 'emu' };
var deviceOpts = { device: true };
var emulatorOpts = { emulator: true };
var emptyOpts = {};
it('Test#001 : should select correct target based on the run opts', function () {
expect(getInstallTarget(targetOpts)).toBe('emu');
expect(getInstallTarget(deviceOpts)).toBe('--device');
expect(getInstallTarget(emulatorOpts)).toBe('--emulator');
expect(getInstallTarget(emptyOpts)).toBeUndefined();
});
});
});