CB-10729 Move plugin handlers tests for into platform's repo

This commit is contained in:
Vladimir Kotikov 2016-02-29 18:49:17 +03:00
parent aa2b3d3da1
commit 8ab75e7109
29 changed files with 784 additions and 14 deletions

4
.gitignore vendored
View File

@ -35,6 +35,7 @@ Desktop.ini
*.swp
*.class
*.jar
!/spec/fixtures/org.test.plugins.dummyplugin/src/android/TestLib.jar
# IntelliJ IDEA files
*.iml
.idea
@ -43,3 +44,6 @@ npm-debug.log
node_modules/jshint
node_modules/promise-matchers
node_modules/jasmine-node
node_modules/rewire
node_modules/istanbul
/coverage

View File

@ -1,2 +1,3 @@
bin/node_modules/*
bin/templates/project/*
spec/fixtures/*

View File

@ -31,7 +31,7 @@ var handlers = {
if (!obj.src) throw new CordovaError('<source-file> element is missing "src" attribute for plugin: ' + plugin.id);
if (!obj.targetDir) throw new CordovaError('<source-file> element is missing "target-dir" attribute for plugin: ' + plugin.id);
var dest = path.join(obj.targetDir, path.basename(obj.src));
copyNewFile(plugin.dir, obj.src, project.projectDir, dest, options && options.link);
copyNewFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
},
uninstall:function(obj, plugin, project, options) {
var dest = path.join(obj.targetDir, path.basename(obj.src));
@ -41,7 +41,7 @@ var handlers = {
'lib-file':{
install:function(obj, plugin, project, options) {
var dest = path.join('libs', path.basename(obj.src));
copyFile(plugin.dir, obj.src, project.projectDir, dest, options && options.link);
copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
},
uninstall:function(obj, plugin, project, options) {
var dest = path.join('libs', path.basename(obj.src));
@ -50,7 +50,7 @@ var handlers = {
},
'resource-file':{
install:function(obj, plugin, project, options) {
copyFile(plugin.dir, obj.src, project.projectDir, path.normalize(obj.target), options && options.link);
copyFile(plugin.dir, obj.src, project.projectDir, path.normalize(obj.target), !!(options && options.link));
},
uninstall:function(obj, plugin, project, options) {
removeFile(project.projectDir, path.normalize(obj.target));
@ -65,22 +65,24 @@ var handlers = {
var parentDir = obj.parent ? path.resolve(project.projectDir, obj.parent) : project.projectDir;
var subDir;
if (obj.custom) {
var subRelativeDir = project.getCustomSubprojectRelativeDir(plugin.id, src);
copyNewFile(plugin.dir, src, project.projectDir, subRelativeDir, options && options.link);
subDir = path.resolve(project.projectDir, subRelativeDir);
} else {
obj.type = 'sys';
subDir = src;
if (obj.custom) {
var subRelativeDir = project.getCustomSubprojectRelativeDir(plugin.id, src);
copyNewFile(plugin.dir, src, project.projectDir, subRelativeDir, !!(options && options.link));
subDir = path.resolve(project.projectDir, subRelativeDir);
} else {
obj.type = 'sys';
subDir = src;
}
if (obj.type == 'gradleReference') {
project.addGradleReference(parentDir, subDir);
} else if (obj.type == 'sys') {
project.addSystemLibrary(parentDir, subDir);
} else {
project.addSubProject(parentDir, subDir);
} else if (obj.type == 'sys') {
project.addSystemLibrary(parentDir, subDir);
} else {
project.addSubProject(parentDir, subDir);
}
project.addSubProject(parentDir, subDir);
},
uninstall:function(obj, plugin, project, options) {
var src = obj.src;

15
node_modules/.bin/istanbul generated vendored Normal file
View File

@ -0,0 +1,15 @@
#!/bin/sh
basedir=`dirname "$0"`
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../istanbul/lib/cli.js" "$@"
ret=$?
else
node "$basedir/../istanbul/lib/cli.js" "$@"
ret=$?
fi
exit $ret

7
node_modules/.bin/istanbul.cmd generated vendored Normal file
View File

@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\istanbul\lib\cli.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\istanbul\lib\cli.js" %*
)

View File

@ -17,6 +17,7 @@
],
"scripts": {
"test": "npm run jshint && jasmine-node --color spec/unit",
"cover": "istanbul cover --root bin/templates/cordova --print detail node_modules/jasmine-node/bin/jasmine-node -- spec/unit",
"test-build": "jasmine-node --captureExceptions --color spec/e2e",
"jshint": "node node_modules/jshint/bin/jshint bin && node node_modules/jshint/bin/jshint spec"
},
@ -39,6 +40,7 @@
"shelljs"
],
"devDependencies": {
"istanbul": "^0.4.2",
"jasmine-node": "^1.14.5",
"jshint": "^2.6.0",
"promise-matchers": "~0",

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2013 Anis Kadri
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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
package="com.alunny.childapp" android:versionName="1.1" android:versionCode="5">
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true"
android:resizeable="true"
android:anyDensity="true"
/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application android:icon="@drawable/icon" android:label="@string/app_name"
android:debuggable="true">
<activity android:name="ChildApp" android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="org.test.DroidGap" android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="5" />
</manifest>

View File

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<cordova>
<!--
access elements control the Android whitelist.
Domains are assumed blocked unless set otherwise
-->
<access origin="http://127.0.0.1*"/> <!-- allow local pages -->
<!-- <access origin="https://example.com" /> allow any secure requests to example.com -->
<!-- <access origin="https://example.com" subdomains="true" /> such as above, but including subdomains, such as www -->
<!-- <access origin=".*"/> Allow all domains, suggested development use only -->
<log level="DEBUG"/>
<preference name="useBrowserHistory" value="false" />
<plugins>
<plugin name="App" value="org.apache.cordova.App"/>
<plugin name="Geolocation" value="org.apache.cordova.GeoBroker"/>
<plugin name="Device" value="org.apache.cordova.Device"/>
<plugin name="Accelerometer" value="org.apache.cordova.AccelListener"/>
<plugin name="Compass" value="org.apache.cordova.CompassListener"/>
<plugin name="Media" value="org.apache.cordova.AudioHandler"/>
<plugin name="Camera" value="org.apache.cordova.CameraLauncher"/>
<plugin name="org.apache.cordova.core.contacts" value="org.apache.cordova.ContactManager"/>
<plugin name="File" value="org.apache.cordova.FileUtils"/>
<plugin name="NetworkStatus" value="org.apache.cordova.NetworkManager"/>
<plugin name="Notification" value="org.apache.cordova.Notification"/>
<plugin name="Storage" value="org.apache.cordova.Storage"/>
<plugin name="Temperature" value="org.apache.cordova.TempListener"/>
<plugin name="FileTransfer" value="org.apache.cordova.FileTransfer"/>
<plugin name="Capture" value="org.apache.cordova.Capture"/>
<plugin name="Battery" value="org.apache.cordova.BatteryListener"/>
<plugin name="SplashScreen" value="org.apache.cordova.SplashScreen"/>
</plugins>
</cordova>

View File

View File

@ -0,0 +1 @@
./org.test.plugins.dummyplugin/android-resource.xml

View File

@ -0,0 +1 @@
extra.gradle

View File

@ -0,0 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1" package="com.test.somelib">
<uses-sdk android:minSdkVersion="9"/>
<application/>
</manifest>

View File

@ -0,0 +1 @@
libFile contents

View File

@ -0,0 +1 @@
target=android-11

View File

@ -0,0 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1" package="com.test.somelib">
<uses-sdk android:minSdkVersion="9"/>
<application/>
</manifest>

View File

@ -0,0 +1 @@
libFile contents

View File

@ -0,0 +1 @@
target=android-11

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2013 Anis Kadri
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.
-->
<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="org.test.plugins.dummyplugin"
version="0.6.0">
<!-- new requirement: NO SPACES -->
<name>dummyplugin</name>
<!-- These are going to be required by plugman-registry -->
<description>my description</description>
<author>Jackson Badman</author>
<keywords>dummy,plugin</keywords>
<license>BSD</license>
<!-- end plugman-registry requirements -->
<asset src="www/dummyplugin.js" target="dummyplugin.js" />
<asset src="www/dummyplugin" target="dummyplugin" />
<config-file target="config.xml" parent="/*">
<access origin="build.phonegap.com" />
<access origin="s3.amazonaws.com" />
</config-file>
<!-- android -->
<platform name="android">
<config-file target="AndroidManifest.xml" parent="/manifest/application">
<activity android:name="DummyPlugin.org.test.plugins.dummyplugin"
android:label="@string/app_name">
<intent-filter>
</intent-filter>
</activity>
</config-file>
<framework src="plugin-lib" custom="true" />
<framework src="plugin-lib2" custom="true" parent="plugin-lib" />
<framework src="extras/android/support/v7/appcompat" />
<framework src="extra.gradle" type="gradleReference" />
<resource-file src="android-resource.xml" target="res/xml/dummy.xml" />
<!-- CDV < 2.0 -->
<config-file target="res/xml/plugins.xml" parent="/plugins">
<plugin name="org.test.plugins.dummyplugin"
value="DummyPlugin.org.test.plugins.dummyplugin"/>
</config-file>
<!-- CDV 2.0+ (for now) -->
<config-file target="res/xml/config.xml" parent="/cordova/plugins">
<plugin name="org.test.plugins.dummyplugin"
value="DummyPlugin.org.test.plugins.dummyplugin"/>
</config-file>
<source-file src="src/android/DummyPlugin.java"
target-dir="src/com/phonegap/plugins/dummyplugin" />
<lib-file src="src/android/TestLib.jar" />
</platform>
</plugin>

View File

@ -0,0 +1 @@
./org.test.plugins.dummyplugin/src/android/DummyPlugin.java

Binary file not shown.

View File

@ -0,0 +1 @@
./org.test.plugins.dummyplugin/www/dummyplugin.js

View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2013 Anis Kadri
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.
-->
<plugin xmlns="http://cordova.apache.org/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="org.test.plugins.faultyplugin"
version="0.6.0">
<name>Faulty Plugin</name>
<access origin="build.phonegap.com" />
<access origin="s3.amazonaws.com" />
<!-- file doesn't exist -->
<config-file target="config.xml" parent="/widget">
<asset src="www/main.js" target="faultyplugin/main.js" />
<asset src="www/index.js" target="faultyplugin/index.js" />
</config-file>
<!-- android -->
<platform name="android">
<config-file target="AndroidManifest.xml" parent="/manifest/application">
<activity android:name="org.test.plugins.faultyplugin.org.test.plugins.faultyplugin"
android:label="@string/app_name">
<intent-filter>
</intent-filter>
</activity>
</config-file>
<!-- CDV < 2.0 -->
<config-file target="res/xml/plugins.xml" parent="/plugins">
<plugin name="org.test.plugins.faultyplugin"
value="org.test.plugins.faultyplugin.org.test.plugins.faultyplugin"/>
</config-file>
<!-- CDV 2.0+ (for now) -->
<config-file target="res/xml/config.xml" parent="/cordova/plugins">
<plugin name="org.test.plugins.faultyplugin"
value="org.test.plugins.faultyplugin.org.test.plugins.faultyplugin"/>
</config-file>
<!-- this file doesn't exist -->
<source-file src="src/android/NotHere.java"
target-dir="src/com/phonegap/plugins/faultyplugin" />
</platform>
</plugin>

View File

@ -0,0 +1 @@
./org.test.plugins.faultyplugin/src/android/org.test.plugins.faultyplugin.java

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('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,170 @@
/*
*
*
* 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('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('should throw if src not in plugin directory', function(){
shell.mkdir('-p', project_dir);
fs.writeFileSync(non_plugin_file, 'contents', 'utf-8');
expect(function(){copyFile(test_dir, '../non_plugin_file', project_dir, dest);}).
toThrow(new Error('"' + non_plugin_file + '" not located within plugin!'));
shell.rm('-rf', test_dir);
});
it('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('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('"' + symlink_file + '" not located within plugin!'));
shell.rm('-rf', project_dir);
});
it('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('"' + non_plugin_file + '" not located within project!'));
shell.rm('-rf', project_dir);
});
it('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').andCallThrough();
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('should call cp source/dest paths', function(){
shell.mkdir('-p', java_dir);
fs.writeFileSync(java_file, 'contents', 'utf-8');
var s = spyOn(shell, 'cp').andCallThrough();
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('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('should call fs.unlinkSync on the provided paths', function(){
var s = spyOn(fs, 'unlinkSync').andCallThrough();
deleteJava(project_dir, java_file);
expect(s).toHaveBeenCalled();
expect(s).toHaveBeenCalledWith(path.resolve(project_dir, java_file));
});
it('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('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,258 @@
/**
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'),
valid_resources = dummyPluginInfo.getResourceFiles('android'),
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);
common.__set__('copyFile', copyFileSpy);
});
afterEach(function() {
shell.rm('-rf', temp);
common.__set__('copyFile', copyFileOrig);
});
describe('of <lib-file> elements', function() {
it('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);
});
});
describe('of <resource-file> elements', function() {
it('should copy files', 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('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('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('"' + path.resolve(faultyplugin, 'src/android/NotHere.java') + '" not found!');
});
it('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('"' + 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('should throw if framework doesn\'t have "src" attribute', function() {
expect(function() { android.framework.install({}, dummyPluginInfo, dummyProject); }).toThrow();
});
it('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('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('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('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('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('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(done) {
it('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'));
});
});
describe('of <resource-file> elements', function(done) {
it('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'));
});
});
describe('of <source-file> elements', function() {
it('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'));
});
});
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('should throw if framework doesn\'t have "src" attribute', function() {
expect(function() { android.framework.uninstall({}, dummyPluginInfo, dummyProject); }).toThrow();
});
it('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('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('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('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);
});
});
});
});