cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From eymor...@apache.org
Subject [10/28] ios commit: CB-10769 Update specs according to actual implementation
Date Mon, 04 Apr 2016 16:27:06 GMT
CB-10769 Update specs according to actual implementation

This closes #200


Project: http://git-wip-us.apache.org/repos/asf/cordova-ios/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-ios/commit/000a61e6
Tree: http://git-wip-us.apache.org/repos/asf/cordova-ios/tree/000a61e6
Diff: http://git-wip-us.apache.org/repos/asf/cordova-ios/diff/000a61e6

Branch: refs/heads/4.1.x
Commit: 000a61e602f3bddd641316a8fda985d87ad10b62
Parents: c0db5e4
Author: Vladimir Kotikov <v-vlkoti@microsoft.com>
Authored: Wed Mar 2 16:44:09 2016 +0300
Committer: Vladimir Kotikov <v-vlkoti@microsoft.com>
Committed: Fri Mar 11 10:23:00 2016 +0300

----------------------------------------------------------------------
 .gitignore                                    |   2 +-
 .jshintignore                                 |   2 +-
 tests/spec/unit/Api.spec.js                   |  42 ++
 tests/spec/unit/Plugman/common.spec.js        | 135 +++---
 tests/spec/unit/Plugman/ios.spec.js           | 447 ------------------
 tests/spec/unit/Plugman/pluginHandler.spec.js | 408 +++++++++++++++++
 tests/spec/unit/ios_parser.spec.js            | 500 ---------------------
 tests/spec/unit/prepare.spec.js               | 417 +++++++++++++++++
 tests/spec/unit/projectFile.spec.js           |  83 ++++
 9 files changed, 1012 insertions(+), 1024 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/000a61e6/.gitignore
----------------------------------------------------------------------
diff --git a/.gitignore b/.gitignore
index 2744ab7..d1aeeeb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,4 +7,4 @@ tmp
 xcuserdata
 console.log
 node_modules/
-npm-debug.log
\ No newline at end of file
+npm-debug.log

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/000a61e6/.jshintignore
----------------------------------------------------------------------
diff --git a/.jshintignore b/.jshintignore
index 1ec4bc1..281391b 100644
--- a/.jshintignore
+++ b/.jshintignore
@@ -1,3 +1,3 @@
 bin/node_modules/*
 bin/templates/project/*
-tests/spec/unit/fixtures/*
\ No newline at end of file
+tests/spec/unit/fixtures/*

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/000a61e6/tests/spec/unit/Api.spec.js
----------------------------------------------------------------------
diff --git a/tests/spec/unit/Api.spec.js b/tests/spec/unit/Api.spec.js
new file mode 100644
index 0000000..9c25f59
--- /dev/null
+++ b/tests/spec/unit/Api.spec.js
@@ -0,0 +1,42 @@
+/**
+ 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 Api = require('../../../bin/templates/scripts/cordova/Api');
+var FIXTURES = path.join(__dirname, 'fixtures');
+var iosProjectFixture = path.join(FIXTURES, 'ios-config-xml');
+
+describe('Platform Api', function () {
+
+    describe('constructor', function() {
+        it('should throw if provided directory does not contain an xcodeproj file', function() {
+            expect(function() { new Api('ios', path.join(FIXTURES, '..')); }).toThrow();
+        });
+        it('should create an instance with path, pbxproj, xcodeproj, originalName and cordovaproj properties', function() {
+            expect(function() {
+                var p = new Api('ios',iosProjectFixture);
+                expect(p.locations.root).toEqual(iosProjectFixture);
+                expect(p.locations.pbxproj).toEqual(path.join(iosProjectFixture, 'SampleApp.xcodeproj', 'project.pbxproj'));
+                expect(p.locations.xcodeProjDir).toEqual(path.join(iosProjectFixture, 'SampleApp.xcodeproj'));
+                expect(p.locations.www).toEqual(path.join(iosProjectFixture, 'www'));
+                expect(p.locations.configXml).toEqual(path.join(iosProjectFixture, 'SampleApp', 'config.xml'));
+            }).not.toThrow();
+        });
+    });
+});

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/000a61e6/tests/spec/unit/Plugman/common.spec.js
----------------------------------------------------------------------
diff --git a/tests/spec/unit/Plugman/common.spec.js b/tests/spec/unit/Plugman/common.spec.js
index f591193..89451e5 100644
--- a/tests/spec/unit/Plugman/common.spec.js
+++ b/tests/spec/unit/Plugman/common.spec.js
@@ -16,74 +16,59 @@
  *
 */
 
-/* jshint laxcomma:true */
-
-var common = require('../../src/plugman/platforms/common')
-  , path = require('path')
-  , fs = require('fs')
-  , osenv = require('os')
-  , shell = require('shelljs')
-  , test_dir = path.join(osenv.tmpdir(), 'test_plugman')
-  , project_dir = path.join(test_dir, 'project')
-  , src = path.join(project_dir, 'src')
-  , dest = path.join(project_dir, 'dest')
-  , java_dir = path.join(src, 'one', 'two', 'three')
-  , java_file = path.join(java_dir, 'test.java')
-  , symlink_file = path.join(java_dir, 'symlink')
-  , non_plugin_file = path.join(osenv.tmpdir(), 'non_plugin_file');
-
-describe('common platform handler', function() {
-    describe('resolveSrcPath', function() {
-        it('should not throw if path exists', function(){
-            shell.mkdir('-p', test_dir);
-            var target = path.join(test_dir, 'somefile');
-            fs.writeFileSync(target, '80085', 'utf-8');
-            expect(function(){common.resolveSrcPath(test_dir, 'somefile');}).not.toThrow();
-            shell.rm('-rf', test_dir);
-        });
-    });
+var fs = require('fs');
+var path = require('path');
+var osenv = require('os');
+var shell = require('shelljs');
+var rewire = require('rewire');
 
-    describe('resolveTargetPath', function() {
-        it('should throw if path exists', function(){
-            shell.mkdir('-p', test_dir);
-            expect(function(){common.resolveTargetPath(test_dir);}).toThrow();
-            shell.rm('-rf', test_dir);
-        });
+var common = rewire('../../../../bin/templates/scripts/cordova/lib/plugman/pluginHandlers');
 
-        it('should not throw if path cannot be resolved', function(){
-            expect(function(){common.resolveTargetPath(test_dir, 'somefile');}).not.toThrow();
-        });
-    });
+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 srcDirTree = path.join(src, 'one', 'two', 'three');
+var srcFile = path.join(srcDirTree, 'test.java');
+var symlink_file = path.join(srcDirTree, 'symlink');
+var non_plugin_file = path.join(osenv.tmpdir(), 'non_plugin_file');
+
+var copyFile = common.__get__('copyFile');
+var copyNewFile = common.__get__('copyNewFile');
+var removeFileAndParents = common.__get__('removeFileAndParents');
+
+describe('common handler routines', function() {
 
     describe('copyFile', function() {
         it('should throw if source path not found', function(){
-            expect(function(){common.copyFile(test_dir, src, project_dir, dest);}).
+            shell.rm('-rf', test_dir);
+            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(){common.copyFile(test_dir, '../non_plugin_file', project_dir, dest);}).
+            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');
+            shell.mkdir('-p', srcDirTree);
+            fs.writeFileSync(srcFile, 'contents', 'utf-8');
 
             // This will fail on windows if not admin - ignore the error in that case.
-            if (ignoreEPERMonWin32(java_file, symlink_file)) {
+            if (ignoreEPERMonWin32(srcFile, symlink_file)) {
                 return;
             }
 
-            common.copyFile(test_dir, symlink_file, project_dir, dest);
+            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);
+            shell.mkdir('-p', srcDirTree);
             fs.writeFileSync(non_plugin_file, 'contents', 'utf-8');
 
             // This will fail on windows if not admin - ignore the error in that case.
@@ -91,27 +76,27 @@ describe('common platform handler', function() {
                 return;
             }
 
-            expect(function(){common.copyFile(test_dir, symlink_file, project_dir, dest);}).
+            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(){common.copyFile(test_dir, java_file, project_dir, non_plugin_file);}).
+            shell.mkdir('-p', srcDirTree);
+            fs.writeFileSync(srcFile, 'contents', 'utf-8');
+            expect(function(){copyFile(test_dir, srcFile, 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');
+            shell.mkdir('-p', srcDirTree);
+            fs.writeFileSync(srcFile, 'contents', 'utf-8');
 
             var s = spyOn(shell, 'mkdir').andCallThrough();
-            var resolvedDest = common.resolveTargetPath(project_dir, dest);
+            var resolvedDest = path.resolve(project_dir, dest);
 
-            common.copyFile(test_dir, java_file, project_dir, dest);
+            copyFile(test_dir, srcFile, project_dir, dest);
 
             expect(s).toHaveBeenCalled();
             expect(s).toHaveBeenCalledWith('-p', path.dirname(resolvedDest));
@@ -119,16 +104,16 @@ describe('common platform handler', function() {
         });
 
         it('should call cp source/dest paths', function(){
-            shell.mkdir('-p', java_dir);
-            fs.writeFileSync(java_file, 'contents', 'utf-8');
+            shell.mkdir('-p', srcDirTree);
+            fs.writeFileSync(srcFile, 'contents', 'utf-8');
 
             var s = spyOn(shell, 'cp').andCallThrough();
-            var resolvedDest = common.resolveTargetPath(project_dir, dest);
+            var resolvedDest = path.resolve(project_dir, dest);
 
-            common.copyFile(test_dir, java_file, project_dir, dest);
+            copyFile(test_dir, srcFile, project_dir, dest);
 
             expect(s).toHaveBeenCalled();
-            expect(s).toHaveBeenCalledWith('-f', java_file, resolvedDest);
+            expect(s).toHaveBeenCalledWith('-f', srcFile, resolvedDest);
 
             shell.rm('-rf', project_dir);
         });
@@ -138,7 +123,7 @@ describe('common platform handler', function() {
     describe('copyNewFile', function () {
         it('should throw if target path exists', function(){
             shell.mkdir('-p', dest);
-            expect(function(){common.copyNewFile(test_dir, src, project_dir, dest);}).
+            expect(function(){copyNewFile(test_dir, src, project_dir, dest);}).
                 toThrow(new Error('"' + dest + '" already exists!'));
             shell.rm('-rf', dest);
         });
@@ -147,37 +132,37 @@ describe('common platform handler', function() {
 
     describe('deleteJava', function() {
         it('should call fs.unlinkSync on the provided paths', function(){
-            shell.mkdir('-p', java_dir);
-            fs.writeFileSync(java_file, 'contents', 'utf-8');
+            shell.mkdir('-p', srcDirTree);
+            fs.writeFileSync(srcFile, 'contents', 'utf-8');
 
             var s = spyOn(fs, 'unlinkSync').andCallThrough();
-            common.deleteJava(project_dir, java_file);
+            removeFileAndParents(project_dir, srcFile);
             expect(s).toHaveBeenCalled();
-            expect(s).toHaveBeenCalledWith(path.resolve(project_dir, java_file));
+            expect(s).toHaveBeenCalledWith(path.resolve(project_dir, srcFile));
 
-            shell.rm('-rf', java_dir);
+            shell.rm('-rf', srcDirTree);
         });
 
-        it('should delete empty directories after removing source code in a java src path hierarchy', function(){
-            shell.mkdir('-p', java_dir);
-            fs.writeFileSync(java_file, 'contents', 'utf-8');
+        it('should delete empty directories after removing source code in path hierarchy', function(){
+            shell.mkdir('-p', srcDirTree);
+            fs.writeFileSync(srcFile, 'contents', 'utf-8');
 
-            common.deleteJava(project_dir, java_file);
-            expect(fs.existsSync(java_file)).not.toBe(true);
-            expect(fs.existsSync(java_dir)).not.toBe(true);
+            removeFileAndParents(project_dir, srcFile);
+            expect(fs.existsSync(srcFile)).not.toBe(true);
+            expect(fs.existsSync(srcDirTree)).not.toBe(true);
             expect(fs.existsSync(path.join(src,'one'))).not.toBe(true);
 
-            shell.rm('-rf', java_dir);
+            shell.rm('-rf', srcDirTree);
         });
 
-        it('should never delete the top-level src directory, even if all plugins added were removed', function(){
-            shell.mkdir('-p', java_dir);
-            fs.writeFileSync(java_file, 'contents', 'utf-8');
+        it('should delete the top-level src directory if all plugins added were removed', function(){
+            shell.mkdir('-p', srcDirTree);
+            fs.writeFileSync(srcFile, 'contents', 'utf-8');
 
-            common.deleteJava(project_dir, java_file);
-            expect(fs.existsSync(src)).toBe(true);
+            removeFileAndParents(project_dir, srcFile);
+            expect(fs.existsSync(src)).toBe(false);
 
-            shell.rm('-rf', java_dir);
+            shell.rm('-rf', srcDirTree);
         });
     });
 });

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/000a61e6/tests/spec/unit/Plugman/ios.spec.js
----------------------------------------------------------------------
diff --git a/tests/spec/unit/Plugman/ios.spec.js b/tests/spec/unit/Plugman/ios.spec.js
deleted file mode 100644
index 7c245bd..0000000
--- a/tests/spec/unit/Plugman/ios.spec.js
+++ /dev/null
@@ -1,447 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-/* jshint sub:true */
-
-var ios = require('../../src/plugman/platforms/ios'),
-    install = require('../../src/plugman/install'),
-    path = require('path'),
-    fs = require('fs'),
-    shell = require('shelljs'),
-    os = require('os'),
-    temp = path.join(os.tmpdir(), 'plugman'),
-    plugins_dir = path.join(temp, 'cordova', 'plugins'),
-    ios_config_xml_project = path.join(__dirname, '..', 'projects', 'ios-config-xml', '*'),
-    ios_project = path.join(ios_config_xml_project, '..'),
-    faultyplugin = path.join(__dirname, '..', 'plugins', 'org.test.plugins.faultyplugin'),
-    dummyplugin = path.join(__dirname, '..', 'plugins', 'org.test.plugins.dummyplugin'),
-    weblessplugin = path.join(__dirname, '..', 'plugins', 'org.test.plugins.weblessplugin'),
-    done = false;
-
-var PluginInfo = require('cordova-common').PluginInfo;
-
-var dummyPluginInfo = new PluginInfo(dummyplugin);
-var dummy_id = dummyPluginInfo.id;
-var valid_source = dummyPluginInfo.getSourceFiles('ios'),
-    valid_headers = dummyPluginInfo.getHeaderFiles('ios'),
-    valid_resources = dummyPluginInfo.getResourceFiles('ios'),
-    valid_custom_frameworks = dummyPluginInfo.getFrameworks('ios').filter(function(f) { return f.custom; });
-
-var faultyPluginInfo = new PluginInfo(faultyplugin);
-var faulty_id = faultyPluginInfo.id;
-
-var invalid_source = faultyPluginInfo.getSourceFiles('ios');
-var invalid_headers = faultyPluginInfo.getHeaderFiles('ios');
-var invalid_resources = faultyPluginInfo.getResourceFiles('ios');
-var invalid_custom_frameworks = faultyPluginInfo.getFrameworks('ios').filter(function(f) { return f.custom; });
-
-shell.mkdir('-p', temp);
-shell.cp('-rf', ios_config_xml_project, temp);
-var proj_files = ios.parseProjectFile(temp);
-shell.rm('-rf', temp);
-ios.purgeProjectFileCache(temp);
-
-function copyArray(arr) {
-    return Array.prototype.slice.call(arr, 0);
-}
-
-function installPromise(f) {
-    f.then(function(res) { done = true; }, function(err) { done = err; });
-}
-
-function slashJoin() {
-    // In some places we need to use forward slash instead of path.join().
-    // See CB-7311.
-    return Array.prototype.join.call(arguments, '/');
-}
-
-describe('ios project handler', function() {
-    beforeEach(function() {
-        shell.mkdir('-p', temp);
-        shell.mkdir('-p', plugins_dir);
-    });
-    afterEach(function() {
-        shell.rm('-rf', temp);
-        ios.purgeProjectFileCache(temp);
-    });
-
-    describe('www_dir method', function() {
-        it('should return cordova-ios project www location using www_dir', function() {
-            expect(ios.www_dir(path.sep)).toEqual(path.sep + 'www');
-        });
-    });
-
-    describe('package_name method', function() {
-        it('should return the CFBundleIdentifier from the project\'s Info.plist file', function() {
-            expect(ios.package_name(ios_project)).toEqual('com.example.friendstring');
-        });
-    });
-
-    describe('parseProjectFile method', function () {
-        it('should throw if project is not an xcode project', function() {
-            expect(function() {
-                ios.parseProjectFile(temp);
-            }).toThrow('does not appear to be an xcode project (no xcode project file)');
-        });
-        it('should throw if project does not contain an appropriate config.xml file', function() {
-            shell.cp('-rf', ios_config_xml_project, temp);
-            shell.rm(path.join(temp, 'SampleApp', 'config.xml'));
-
-            expect(function() {
-                ios.parseProjectFile(temp);
-            }).toThrow('could not find -Info.plist file, or config.xml file.');
-        });
-        it('should throw if project does not contain an appropriate -Info.plist file', function() {
-            shell.cp('-rf', ios_config_xml_project, temp);
-            shell.rm(path.join(temp, 'SampleApp', 'SampleApp-Info.plist'));
-
-            expect(function () {
-                ios.parseProjectFile(temp);
-            }).toThrow('could not find -Info.plist file, or config.xml file.');
-        });
-        it('should return right directory when multiple .plist files are present', function() {
-            shell.cp('-rf', ios_config_xml_project, temp);
-            //Create a folder named A with config.xml and .plist files in it
-            var pathToFolderA = path.join(temp, 'A');
-            shell.mkdir(pathToFolderA);
-            shell.cp('-rf', path.join(temp, 'SampleApp/*'), pathToFolderA);
-
-            var parsedProjectFile = ios.parseProjectFile(temp);
-            var pluginsDir = parsedProjectFile.plugins_dir,
-                resourcesDir = parsedProjectFile.resources_dir,
-                xcodePath = parsedProjectFile.xcode_path;
-
-            var pluginsDirParent = path.dirname(pluginsDir),
-                resourcesDirParent = path.dirname(resourcesDir),
-                sampleAppDir = path.join(temp, 'SampleApp');
-
-            expect(pluginsDirParent).toEqual(sampleAppDir);
-            expect(resourcesDirParent).toEqual(sampleAppDir);
-            expect(xcodePath).toEqual(sampleAppDir);
-        });
-    });
-
-    describe('installation', function() {
-        beforeEach(function() {
-            shell.cp('-rf', ios_config_xml_project, temp);
-            done = false;
-        });
-
-        describe('of <source-file> elements', function() {
-            it('should throw if source-file src cannot be found', function() {
-                var source = copyArray(invalid_source);
-                expect(function() {
-                    ios['source-file'].install(source[1], faultyplugin, temp, faulty_id, null, proj_files);
-                }).toThrow();
-            });
-            it('should throw if source-file target already exists', function() {
-                var source = copyArray(valid_source);
-                var target = path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'DummyPluginCommand.m');
-                shell.mkdir('-p', path.dirname(target));
-                fs.writeFileSync(target, 'some bs', 'utf-8');
-                expect(function() {
-                    ios['source-file'].install(source[0], dummyplugin, temp, dummy_id, null, proj_files);
-                }).toThrow();
-            });
-            it('should call into xcodeproj\'s addSourceFile appropriately when element has no target-dir', function() {
-                var source = copyArray(valid_source).filter(function(s) { return s.targetDir === undefined; });
-                var spy = spyOn(proj_files.xcode, 'addSourceFile');
-                ios['source-file'].install(source[0], dummyplugin, temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.m'), {});
-            });
-            it('should call into xcodeproj\'s addSourceFile appropriately when element has a target-dir', function() {
-                var source = copyArray(valid_source).filter(function(s) { return s.targetDir !== undefined; });
-                var spy = spyOn(proj_files.xcode, 'addSourceFile');
-                ios['source-file'].install(source[0], dummyplugin, temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.m'), {});
-            });
-            it('should cp the file to the right target location when element has no target-dir', function() {
-                var source = copyArray(valid_source).filter(function(s) { return s.targetDir === undefined; });
-                var spy = spyOn(shell, 'cp');
-                ios['source-file'].install(source[0], dummyplugin, temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith('-f', path.join(dummyplugin, 'src', 'ios', 'DummyPluginCommand.m'), path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'DummyPluginCommand.m'));
-            });
-            it('should cp the file to the right target location when element has a target-dir', function() {
-                var source = copyArray(valid_source).filter(function(s) { return s.targetDir !== undefined; });
-                var spy = spyOn(shell, 'cp');
-                ios['source-file'].install(source[0], dummyplugin, temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith('-f', path.join(dummyplugin, 'src', 'ios', 'TargetDirTest.m'), path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'targetDir', 'TargetDirTest.m'));
-            });
-            it('should call into xcodeproj\'s addFramework appropriately when element has framework=true set', function() {
-                var source = copyArray(valid_source).filter(function(s) { return s.framework; });
-                spyOn(proj_files.xcode, 'addSourceFile');
-                var spy = spyOn(proj_files.xcode, 'addFramework');
-                ios['source-file'].install(source[0], dummyplugin, temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith(path.join('SampleApp', 'Plugins', dummy_id, 'SourceWithFramework.m'), {weak:false});
-            });
-        });
-
-        describe('of <header-file> elements', function() {
-            it('should throw if header-file src cannot be found', function() {
-                var headers = copyArray(invalid_headers);
-                expect(function() {
-                    ios['header-file'].install(headers[1], faultyplugin, temp, faulty_id, null, proj_files);
-                }).toThrow();
-            });
-            it('should throw if header-file target already exists', function() {
-                var headers = copyArray(valid_headers);
-                var target = path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'DummyPluginCommand.h');
-                shell.mkdir('-p', path.dirname(target));
-                fs.writeFileSync(target, 'some bs', 'utf-8');
-                expect(function() {
-                    ios['header-file'].install(headers[0], dummyplugin, temp, dummy_id, null, proj_files);
-                }).toThrow();
-            });
-            it('should call into xcodeproj\'s addHeaderFile appropriately when element has no target-dir', function() {
-                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir === undefined; });
-                var spy = spyOn(proj_files.xcode, 'addHeaderFile');
-                ios['header-file'].install(headers[0], dummyplugin, temp, dummy_id,  null, proj_files);
-                expect(spy).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.h'));
-            });
-            it('should call into xcodeproj\'s addHeaderFile appropriately when element a target-dir', function() {
-                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir !== undefined; });
-                var spy = spyOn(proj_files.xcode, 'addHeaderFile');
-                ios['header-file'].install(headers[0], dummyplugin, temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.h'));
-            });
-            it('should cp the file to the right target location when element has no target-dir', function() {
-                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir === undefined; });
-                var spy = spyOn(shell, 'cp');
-                ios['header-file'].install(headers[0], dummyplugin, temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith('-f', path.join(dummyplugin, 'src', 'ios', 'DummyPluginCommand.h'), path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'DummyPluginCommand.h'));
-            });
-            it('should cp the file to the right target location when element has a target-dir', function() {
-                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir !== undefined; });
-                var spy = spyOn(shell, 'cp');
-                ios['header-file'].install(headers[0], dummyplugin, temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith('-f', path.join(dummyplugin, 'src', 'ios', 'TargetDirTest.h'), path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'targetDir', 'TargetDirTest.h'));
-            });
-        });
-
-        describe('of <resource-file> elements', function() {
-            it('should throw if resource-file src cannot be found', function() {
-                var resources = copyArray(invalid_resources);
-                expect(function() {
-                    ios['resource-file'].install(resources[0], faultyplugin, temp, 'pluginid', null, proj_files);
-                }).toThrow('cannot find "' + path.resolve(faultyplugin, 'src/ios/IDontExist.bundle') + '" ios <resource-file>');
-            });
-            it('should throw if resource-file target already exists', function() {
-                var resources = copyArray(valid_resources);
-                var target = path.join(temp, 'SampleApp', 'Resources', 'DummyPlugin.bundle');
-                shell.mkdir('-p', path.dirname(target));
-                fs.writeFileSync(target, 'some bs', 'utf-8');
-                expect(function() {
-                    ios['resource-file'].install(resources[0], dummyplugin, temp, 'pluginid',null, proj_files);
-                }).toThrow('target destination "' + target + '" already exists');
-            });
-            it('should call into xcodeproj\'s addResourceFile', function() {
-                var resources = copyArray(valid_resources);
-                var spy = spyOn(proj_files.xcode, 'addResourceFile');
-                ios['resource-file'].install(resources[0], dummyplugin, temp, 'pluginid', null, proj_files);
-                expect(spy).toHaveBeenCalledWith(path.join('Resources', 'DummyPlugin.bundle'));
-            });
-            it('should cp the file to the right target location', function() {
-                var resources = copyArray(valid_resources);
-                var spy = spyOn(shell, 'cp');
-                ios['resource-file'].install(resources[0], dummyplugin, temp, 'pluginid', null, proj_files);
-                expect(spy).toHaveBeenCalledWith('-R', path.join(dummyplugin, 'src', 'ios', 'DummyPlugin.bundle'), path.join(temp, 'SampleApp', 'Resources'));
-            });
-        });
-        describe('of <framework> elements', function() {
-
-            it('should call into xcodeproj\'s addFramework', function() {
-                var frameworks = copyArray(valid_custom_frameworks);
-                var spy = spyOn(proj_files.xcode, 'addFramework');
-                ios['framework'].install(frameworks[0], dummyplugin, temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith(path.normalize('SampleApp/Plugins/org.test.plugins.dummyplugin/Custom.framework'), {customFramework:true});
-            });
-
-            // TODO: Add more tests to cover the cases:
-            // * framework with weak attribute
-            // * framework that shouldn't be added/removed
-
-            describe('with custom="true" attribute', function () {
-                it('should throw if framework src cannot be found', function() {
-                    var frameworks = copyArray(invalid_custom_frameworks);
-                    expect(function() {
-                        ios['framework'].install(frameworks[0], faultyplugin, temp, dummy_id, null, proj_files);
-                    }).toThrow('cannot find "' + path.resolve(faultyplugin, 'src/ios/NonExistantCustomFramework.framework') + '" ios <framework>');
-                });
-                it('should throw if framework target already exists', function() {
-                    var frameworks = copyArray(valid_custom_frameworks);
-                    var target = path.join(temp, 'SampleApp/Plugins/org.test.plugins.dummyplugin/Custom.framework');
-                    shell.mkdir('-p', target);
-                    expect(function() {
-                        ios['framework'].install(frameworks[0], dummyplugin, temp, dummy_id, null, proj_files);
-                    }).toThrow('target destination "' + target + '" already exists');
-                });
-                it('should cp the file to the right target location', function() {
-                    var frameworks = copyArray(valid_custom_frameworks);
-                    var spy = spyOn(shell, 'cp');
-                    ios['framework'].install(frameworks[0], dummyplugin, temp, dummy_id, null, proj_files);
-                    expect(spy).toHaveBeenCalledWith('-R', path.join(dummyplugin, 'src', 'ios', 'Custom.framework'),
-                                                     path.join(temp, 'SampleApp/Plugins/org.test.plugins.dummyplugin'));
-                });
-            });
-        });
-        it('of two plugins should apply xcode file changes from both', function(){
-            runs(function() {
-                installPromise(
-                    install('ios', temp, dummyplugin)
-                    .then(function () { install('ios', temp, weblessplugin); })
-                );
-            });
-            waitsFor(function() { return done; }, 'install promise never resolved', 200);
-            runs(function() {
-                var xcode = ios.parseProjectFile(temp).xcode;
-                // from org.test.plugins.dummyplugin
-                expect(xcode.hasFile(slashJoin('Resources', 'DummyPlugin.bundle'))).toBe(true);
-                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.dummyplugin', 'DummyPluginCommand.h'))).toBe(true);
-                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.dummyplugin', 'DummyPluginCommand.m'))).toBe(true);
-                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.dummyplugin','targetDir','TargetDirTest.h'))).toBe(true);
-                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.dummyplugin','targetDir','TargetDirTest.m'))).toBe(true);
-                expect(xcode.hasFile('usr/lib/src/ios/libsqlite3.dylib')).toBe(true);
-                expect(xcode.hasFile(slashJoin('SampleApp','Plugins','org.test.plugins.dummyplugin','Custom.framework'))).toBe(true);
-                // from org.test.plugins.weblessplugin
-                expect(xcode.hasFile(slashJoin('Resources', 'WeblessPluginViewController.xib'))).toBe(true);
-                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.weblessplugin','WeblessPluginCommand.h'))).toBe(true);
-                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.weblessplugin','WeblessPluginCommand.m'))).toBe(true);
-                expect(xcode.hasFile('usr/lib/libsqlite3.dylib')).toBe(true);
-            });
-        });
-    });
-
-    describe('uninstallation', function() {
-        describe('of <source-file> elements', function() {
-            it('should call into xcodeproj\'s removeSourceFile appropriately when element has no target-dir', function(){
-                var source = copyArray(valid_source).filter(function(s) { return s.targetDir === undefined; });
-                shell.cp('-rf', ios_config_xml_project, temp);
-                var spy = spyOn(proj_files.xcode, 'removeSourceFile');
-                ios['source-file'].uninstall(source[0], temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.m'));
-            });
-            it('should call into xcodeproj\'s removeSourceFile appropriately when element a target-dir', function(){
-                var source = copyArray(valid_source).filter(function(s) { return s.targetDir !== undefined; });
-                shell.cp('-rf', ios_config_xml_project, temp);
-                var spy = spyOn(proj_files.xcode, 'removeSourceFile');
-                ios['source-file'].uninstall(source[0], temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.m'));
-            });
-            it('should rm the file from the right target location when element has no target-dir', function(){
-                var source = copyArray(valid_source).filter(function(s) { return s.targetDir === undefined; });
-                shell.cp('-rf', ios_config_xml_project, temp);
-
-                var spy = spyOn(shell, 'rm');
-                ios['source-file'].uninstall(source[0], temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith('-rf', path.join(temp, 'SampleApp', 'Plugins', dummy_id));
-            });
-            it('should rm the file from the right target location when element has a target-dir', function(){
-                var source = copyArray(valid_source).filter(function(s) { return s.targetDir !== undefined; });
-                shell.cp('-rf', ios_config_xml_project, temp);
-                var spy = spyOn(shell, 'rm');
-
-                ios['source-file'].uninstall(source[0], temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith('-rf', path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'targetDir'));
-            });
-            it('should call into xcodeproj\'s removeFramework appropriately when element framework=true set', function(){
-                var source = copyArray(valid_source).filter(function(s) { return s.framework; });
-                shell.cp('-rf', ios_config_xml_project, temp);
-                var spy = spyOn(proj_files.xcode, 'removeFramework');
-
-                ios['source-file'].uninstall(source[0], temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith(path.join('SampleApp', 'Plugins', dummy_id, 'SourceWithFramework.m'));
-            });
-        });
-
-        describe('of <header-file> elements', function() {
-            beforeEach(function() {
-                shell.cp('-rf', ios_config_xml_project, temp);
-            });
-            it('should call into xcodeproj\'s removeHeaderFile appropriately when element has no target-dir', function(){
-                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir === undefined; });
-                var spy = spyOn(proj_files.xcode, 'removeHeaderFile');
-
-                ios['header-file'].uninstall(headers[0], temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.h'));
-            });
-            it('should call into xcodeproj\'s removeHeaderFile appropriately when element a target-dir', function(){
-                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir !== undefined; });
-
-                var spy = spyOn(proj_files.xcode, 'removeHeaderFile');
-
-                ios['header-file'].uninstall(headers[0], temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.h'));
-            });
-            it('should rm the file from the right target location', function(){
-                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir !== undefined; });
-                var spy = spyOn(shell, 'rm');
-
-                ios['header-file'].uninstall(headers[0], temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith('-rf', path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'targetDir'));
-            });
-        });
-
-        describe('of <resource-file> elements', function() {
-            beforeEach(function() {
-                shell.cp('-rf', ios_config_xml_project, temp);
-            });
-            it('should call into xcodeproj\'s removeResourceFile', function(){
-                var resources = copyArray(valid_resources);
-                var spy = spyOn(proj_files.xcode, 'removeResourceFile');
-
-                ios['resource-file'].uninstall(resources[0], temp, 'pluginid', null, proj_files);
-                expect(spy).toHaveBeenCalledWith(path.join('Resources', 'DummyPlugin.bundle'));
-            });
-            it('should rm the file from the right target location', function(){
-                var resources = copyArray(valid_resources);
-                var spy = spyOn(shell, 'rm');
-
-                ios['resource-file'].uninstall(resources[0], temp, 'pluginid', null, proj_files);
-                expect(spy).toHaveBeenCalledWith('-rf', path.join(temp, 'SampleApp', 'Resources', 'DummyPlugin.bundle'));
-            });
-        });
-        describe('of <framework> elements', function() {
-            beforeEach(function() {
-                shell.cp('-rf', ios_config_xml_project, temp);
-            });
-
-            it('should call into xcodeproj\'s removeFramework', function(){
-                var frameworks = copyArray(valid_custom_frameworks);
-                var spy = spyOn(proj_files.xcode, 'removeFramework');
-
-                ios['framework'].uninstall(frameworks[0], temp, dummy_id, null, proj_files);
-                expect(spy).toHaveBeenCalledWith(path.join(temp, 'SampleApp/Plugins/org.test.plugins.dummyplugin/Custom.framework'), {customFramework:true});
-            });
-
-            // TODO: Add more tests to cover the cases:
-            // * framework with weak attribute
-            // * framework that shouldn't be added/removed
-
-            describe('with custom="true" attribute', function () {
-                it('should rm the file from the right target location', function(){
-                    var frameworks = copyArray(valid_custom_frameworks);
-                    var spy = spyOn(shell, 'rm');
-
-                    ios['framework'].uninstall(frameworks[0], temp, dummy_id, null, proj_files);
-                    expect(spy).toHaveBeenCalledWith('-rf', path.join(temp, 'SampleApp/Plugins/org.test.plugins.dummyplugin/Custom.framework'));
-                });
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-ios/blob/000a61e6/tests/spec/unit/Plugman/pluginHandler.spec.js
----------------------------------------------------------------------
diff --git a/tests/spec/unit/Plugman/pluginHandler.spec.js b/tests/spec/unit/Plugman/pluginHandler.spec.js
new file mode 100644
index 0000000..d093970
--- /dev/null
+++ b/tests/spec/unit/Plugman/pluginHandler.spec.js
@@ -0,0 +1,408 @@
+/**
+    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 os = require('os');
+var fs = require('fs');
+var path = require('path');
+var rewire = require('rewire');
+var shell = require('shelljs');
+
+var PluginInfo = require('cordova-common').PluginInfo;
+var Api = require('../../../../bin/templates/scripts/cordova/Api');
+var projectFile = require('../../../../bin/templates/scripts/cordova/lib/projectFile');
+var pluginHandlers = rewire('../../../../bin/templates/scripts/cordova/lib/plugman/pluginHandlers');
+
+var temp = path.join(os.tmpdir(), 'plugman');
+
+var FIXTURES = path.join(__dirname, '../fixtures');
+var iosProject = path.join(FIXTURES, 'ios-config-xml', '*');
+var faultyplugin = path.join(FIXTURES, 'org.test.plugins.faultyplugin');
+var dummyplugin = path.join(FIXTURES, 'org.test.plugins.dummyplugin');
+var weblessplugin = path.join(FIXTURES, 'org.test.plugins.weblessplugin');
+
+var dummyPluginInfo = new PluginInfo(dummyplugin);
+var dummy_id = dummyPluginInfo.id;
+var valid_source = dummyPluginInfo.getSourceFiles('ios'),
+    valid_headers = dummyPluginInfo.getHeaderFiles('ios'),
+    valid_resources = dummyPluginInfo.getResourceFiles('ios'),
+    valid_custom_frameworks = dummyPluginInfo.getFrameworks('ios').filter(function(f) { return f.custom; });
+
+var faultyPluginInfo = new PluginInfo(faultyplugin);
+var invalid_source = faultyPluginInfo.getSourceFiles('ios');
+var invalid_headers = faultyPluginInfo.getHeaderFiles('ios');
+var invalid_resources = faultyPluginInfo.getResourceFiles('ios');
+var invalid_custom_frameworks = faultyPluginInfo.getFrameworks('ios').filter(function(f) { return f.custom; });
+
+var weblessPluginInfo = new PluginInfo(weblessplugin);
+
+function copyArray(arr) {
+    return Array.prototype.slice.call(arr, 0);
+}
+
+function slashJoin() {
+    // In some places we need to use forward slash instead of path.join().
+    // See CB-7311.
+    return Array.prototype.join.call(arguments, '/');
+}
+
+describe('ios plugin handler', function() {
+    var dummyProject;
+
+    beforeEach(function() {
+        shell.cp('-rf', iosProject, temp);
+        projectFile.purgeProjectFileCache(temp);
+
+        dummyProject = projectFile.parse({
+            root: temp,
+            pbxproj: path.join(temp, 'SampleApp.xcodeproj/project.pbxproj')
+        });
+    });
+
+    afterEach(function() {
+        shell.rm('-rf', temp);
+    });
+
+    describe('installation', function() {
+
+        describe('of <source-file> elements', function() {
+            var install = pluginHandlers.getInstaller('source-file');
+
+            beforeEach(function () {
+                spyOn(dummyProject.xcode, 'addSourceFile');
+            });
+
+            it('should throw if source-file src cannot be found', function() {
+                var source = copyArray(invalid_source);
+                expect(function() {
+                    install(source[1], faultyPluginInfo, dummyProject);
+                }).toThrow();
+            });
+            it('should throw if source-file target already exists', function() {
+                var source = copyArray(valid_source);
+                var target = path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'DummyPluginCommand.m');
+                shell.mkdir('-p', path.dirname(target));
+                fs.writeFileSync(target, 'some bs', 'utf-8');
+                expect(function() {
+                    install(source[0], dummyPluginInfo, dummyProject);
+                }).toThrow();
+            });
+            it('should call into xcodeproj\'s addSourceFile appropriately when element has no target-dir', function() {
+                var source = copyArray(valid_source).filter(function(s) { return s.targetDir === undefined; });
+                install(source[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.addSourceFile)
+                    .toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.m'), {});
+            });
+            it('should call into xcodeproj\'s addSourceFile appropriately when element has a target-dir', function() {
+                var source = copyArray(valid_source).filter(function(s) { return s.targetDir !== undefined; });
+                install(source[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.addSourceFile)
+                    .toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.m'), {});
+            });
+            it('should cp the file to the right target location when element has no target-dir', function() {
+                var source = copyArray(valid_source).filter(function(s) { return s.targetDir === undefined; });
+                var spy = spyOn(shell, 'cp');
+                install(source[0], dummyPluginInfo, dummyProject);
+                expect(spy).toHaveBeenCalledWith('-f', path.join(dummyplugin, 'src', 'ios', 'DummyPluginCommand.m'), path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'DummyPluginCommand.m'));
+            });
+            it('should cp the file to the right target location when element has a target-dir', function() {
+                var source = copyArray(valid_source).filter(function(s) { return s.targetDir !== undefined; });
+                var spy = spyOn(shell, 'cp');
+                install(source[0], dummyPluginInfo, dummyProject);
+                expect(spy).toHaveBeenCalledWith('-f', path.join(dummyplugin, 'src', 'ios', 'TargetDirTest.m'), path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'targetDir', 'TargetDirTest.m'));
+            });
+            it('should call into xcodeproj\'s addFramework appropriately when element has framework=true set', function() {
+                var source = copyArray(valid_source).filter(function(s) { return s.framework; });
+                spyOn(dummyProject.xcode, 'addFramework');
+                install(source[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.addFramework)
+                    .toHaveBeenCalledWith(path.join('SampleApp', 'Plugins', dummy_id, 'SourceWithFramework.m'), {weak:false});
+            });
+        });
+
+        describe('of <header-file> elements', function() {
+            var install = pluginHandlers.getInstaller('header-file');
+
+            beforeEach(function () {
+                spyOn(dummyProject.xcode, 'addHeaderFile');
+            });
+
+            it('should throw if header-file src cannot be found', function() {
+                var headers = copyArray(invalid_headers);
+                expect(function() {
+                    install(headers[1], faultyPluginInfo, dummyProject);
+                }).toThrow();
+            });
+            it('should throw if header-file target already exists', function() {
+                var headers = copyArray(valid_headers);
+                var target = path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'DummyPluginCommand.h');
+                shell.mkdir('-p', path.dirname(target));
+                fs.writeFileSync(target, 'some bs', 'utf-8');
+                expect(function() {
+                    install(headers[0], dummyPluginInfo, dummyProject);
+                }).toThrow();
+            });
+            it('should call into xcodeproj\'s addHeaderFile appropriately when element has no target-dir', function() {
+                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir === undefined; });
+                install(headers[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.addHeaderFile)
+                    .toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.h'));
+            });
+            it('should call into xcodeproj\'s addHeaderFile appropriately when element a target-dir', function() {
+                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir !== undefined; });
+                install(headers[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.addHeaderFile)
+                    .toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.h'));
+            });
+            it('should cp the file to the right target location when element has no target-dir', function() {
+                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir === undefined; });
+                var spy = spyOn(shell, 'cp');
+                install(headers[0], dummyPluginInfo, dummyProject);
+                expect(spy).toHaveBeenCalledWith('-f', path.join(dummyplugin, 'src', 'ios', 'DummyPluginCommand.h'), path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'DummyPluginCommand.h'));
+            });
+            it('should cp the file to the right target location when element has a target-dir', function() {
+                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir !== undefined; });
+                var spy = spyOn(shell, 'cp');
+                install(headers[0], dummyPluginInfo, dummyProject);
+                expect(spy).toHaveBeenCalledWith('-f', path.join(dummyplugin, 'src', 'ios', 'TargetDirTest.h'), path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'targetDir', 'TargetDirTest.h'));
+            });
+        });
+
+        describe('of <resource-file> elements', function() {
+            var install = pluginHandlers.getInstaller('resource-file');
+
+            beforeEach(function () {
+                spyOn(dummyProject.xcode, 'addResourceFile');
+            });
+
+            it('should throw if resource-file src cannot be found', function() {
+                var resources = copyArray(invalid_resources);
+                expect(function() {
+                    install(resources[0], faultyPluginInfo, dummyProject);
+                }).toThrow('cannot find "' + path.resolve(faultyplugin, 'src/ios/IDontExist.bundle') + '" ios <resource-file>');
+            });
+            it('should throw if resource-file target already exists', function() {
+                var resources = copyArray(valid_resources);
+                var target = path.join(temp, 'SampleApp', 'Resources', 'DummyPlugin.bundle');
+                shell.mkdir('-p', path.dirname(target));
+                fs.writeFileSync(target, 'some bs', 'utf-8');
+                expect(function() {
+                    install(resources[0], dummyPluginInfo, dummyProject);
+                }).toThrow('target destination "' + target + '" already exists');
+            });
+            it('should call into xcodeproj\'s addResourceFile', function() {
+                var resources = copyArray(valid_resources);
+                install(resources[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.addResourceFile)
+                    .toHaveBeenCalledWith(path.join('Resources', 'DummyPlugin.bundle'));
+            });
+            it('should cp the file to the right target location', function() {
+                var resources = copyArray(valid_resources);
+                var spy = spyOn(shell, 'cp');
+                install(resources[0], dummyPluginInfo, dummyProject);
+                expect(spy).toHaveBeenCalledWith('-R', path.join(dummyplugin, 'src', 'ios', 'DummyPlugin.bundle'), path.join(temp, 'SampleApp', 'Resources'));
+            });
+        });
+
+        describe('of <framework> elements', function() {
+
+            var install = pluginHandlers.getInstaller('framework');
+            beforeEach(function () {
+                spyOn(dummyProject.xcode, 'addFramework');
+            });
+
+            it('should call into xcodeproj\'s addFramework', function() {
+                var frameworks = copyArray(valid_custom_frameworks);
+                install(frameworks[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.addFramework)
+                    .toHaveBeenCalledWith(path.normalize('SampleApp/Plugins/org.test.plugins.dummyplugin/Custom.framework'), {customFramework:true});
+            });
+
+            // TODO: Add more tests to cover the cases:
+            // * framework with weak attribute
+            // * framework that shouldn't be added/removed
+
+            describe('with custom="true" attribute', function () {
+                it('should throw if framework src cannot be found', function() {
+                    var frameworks = copyArray(invalid_custom_frameworks);
+                    expect(function() {
+                        install(frameworks[0], faultyPluginInfo, dummyProject);
+                    }).toThrow('cannot find "' + path.resolve(faultyplugin, 'src/ios/NonExistantCustomFramework.framework') + '" ios <framework>');
+                });
+                it('should throw if framework target already exists', function() {
+                    var frameworks = copyArray(valid_custom_frameworks);
+                    var target = path.join(temp, 'SampleApp/Plugins/org.test.plugins.dummyplugin/Custom.framework');
+                    shell.mkdir('-p', target);
+                    expect(function() {
+                        install(frameworks[0], dummyPluginInfo, dummyProject);
+                    }).toThrow('target destination "' + target + '" already exists');
+                });
+                it('should cp the file to the right target location', function() {
+                    var frameworks = copyArray(valid_custom_frameworks);
+                    var spy = spyOn(shell, 'cp');
+                    install(frameworks[0], dummyPluginInfo, dummyProject);
+                    expect(spy).toHaveBeenCalledWith('-R', path.join(dummyplugin, 'src', 'ios', 'Custom.framework'),
+                                                     path.join(temp, 'SampleApp/Plugins/org.test.plugins.dummyplugin'));
+                });
+            });
+        });
+
+        it('of two plugins should apply xcode file changes from both', function(done){
+            var api = new Api('ios', temp);
+            var fail = jasmine.createSpy('fail');
+
+            api.addPlugin(dummyPluginInfo)
+            .then(function () {
+                return api.addPlugin(weblessPluginInfo);
+            })
+            .fail(fail)
+            .done(function() {
+                expect(fail).not.toHaveBeenCalled();
+
+                var xcode = projectFile.parse({
+                    root: temp,
+                    pbxproj: path.join(temp, 'SampleApp.xcodeproj/project.pbxproj')
+                }).xcode;
+
+                // from org.test.plugins.dummyplugin
+                expect(xcode.hasFile(slashJoin('Resources', 'DummyPlugin.bundle'))).toEqual(jasmine.any(Object));
+                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.dummyplugin', 'DummyPluginCommand.h'))).toEqual(jasmine.any(Object));
+                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.dummyplugin', 'DummyPluginCommand.m'))).toEqual(jasmine.any(Object));
+                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.dummyplugin','targetDir','TargetDirTest.h'))).toEqual(jasmine.any(Object));
+                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.dummyplugin','targetDir','TargetDirTest.m'))).toEqual(jasmine.any(Object));
+                expect(xcode.hasFile('usr/lib/libsqlite3.dylib')).toEqual(jasmine.any(Object));
+                expect(xcode.hasFile(slashJoin('SampleApp','Plugins','org.test.plugins.dummyplugin','Custom.framework'))).toEqual(jasmine.any(Object));
+                // from org.test.plugins.weblessplugin
+                expect(xcode.hasFile(slashJoin('Resources', 'WeblessPluginViewController.xib'))).toEqual(jasmine.any(Object));
+                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.weblessplugin','WeblessPluginCommand.h'))).toEqual(jasmine.any(Object));
+                expect(xcode.hasFile(slashJoin('Plugins','org.test.plugins.weblessplugin','WeblessPluginCommand.m'))).toEqual(jasmine.any(Object));
+                expect(xcode.hasFile('usr/lib/libsqlite3.dylib')).toEqual(jasmine.any(Object));
+
+                done();
+            });
+        });
+    });
+
+    describe('uninstallation', function() {
+        describe('of <source-file> elements', function() {
+            var uninstall = pluginHandlers.getUninstaller('source-file');
+            beforeEach(function () {
+                spyOn(dummyProject.xcode, 'removeSourceFile');
+                spyOn(dummyProject.xcode, 'removeFramework');
+            });
+
+            it('should call into xcodeproj\'s removeSourceFile appropriately when element has no target-dir', function(){
+                var source = copyArray(valid_source).filter(function(s) { return s.targetDir === undefined; });
+                uninstall(source[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.removeSourceFile).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.m'));
+            });
+            it('should call into xcodeproj\'s removeSourceFile appropriately when element a target-dir', function(){
+                var source = copyArray(valid_source).filter(function(s) { return s.targetDir !== undefined; });
+                uninstall(source[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.removeSourceFile).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.m'));
+            });
+            it('should rm the file from the right target location when element has no target-dir', function(){
+                var source = copyArray(valid_source).filter(function(s) { return s.targetDir === undefined; });
+                var spy = spyOn(shell, 'rm');
+                uninstall(source[0], dummyPluginInfo, dummyProject);
+                expect(spy).toHaveBeenCalledWith('-rf', path.join(temp, 'SampleApp', 'Plugins', dummy_id));
+            });
+            it('should rm the file from the right target location when element has a target-dir', function(){
+                var source = copyArray(valid_source).filter(function(s) { return s.targetDir !== undefined; });
+                var spy = spyOn(shell, 'rm');
+                uninstall(source[0], dummyPluginInfo, dummyProject);
+                expect(spy).toHaveBeenCalledWith('-rf', path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'targetDir'));
+            });
+            it('should call into xcodeproj\'s removeFramework appropriately when element framework=true set', function(){
+                var source = copyArray(valid_source).filter(function(s) { return s.framework; });
+                uninstall(source[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.removeFramework).toHaveBeenCalledWith(path.join('SampleApp', 'Plugins', dummy_id, 'SourceWithFramework.m'));
+            });
+        });
+
+        describe('of <header-file> elements', function() {
+            var uninstall = pluginHandlers.getUninstaller('header-file');
+            beforeEach(function () {
+                spyOn(dummyProject.xcode, 'removeHeaderFile');
+            });
+
+            it('should call into xcodeproj\'s removeHeaderFile appropriately when element has no target-dir', function(){
+                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir === undefined; });
+                uninstall(headers[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.removeHeaderFile).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'DummyPluginCommand.h'));
+            });
+            it('should call into xcodeproj\'s removeHeaderFile appropriately when element a target-dir', function(){
+                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir !== undefined; });
+                uninstall(headers[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.removeHeaderFile).toHaveBeenCalledWith(slashJoin('Plugins', dummy_id, 'targetDir', 'TargetDirTest.h'));
+            });
+            it('should rm the file from the right target location', function(){
+                var headers = copyArray(valid_headers).filter(function(s) { return s.targetDir !== undefined; });
+                var spy = spyOn(shell, 'rm');
+                uninstall(headers[0], dummyPluginInfo, dummyProject);
+                expect(spy).toHaveBeenCalledWith('-rf', path.join(temp, 'SampleApp', 'Plugins', dummy_id, 'targetDir'));
+            });
+        });
+
+        describe('of <resource-file> elements', function() {
+            var uninstall = pluginHandlers.getUninstaller('resource-file');
+            beforeEach(function () {
+                spyOn(dummyProject.xcode, 'removeResourceFile');
+            });
+
+            it('should call into xcodeproj\'s removeResourceFile', function(){
+                var resources = copyArray(valid_resources);
+                uninstall(resources[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.removeResourceFile).toHaveBeenCalledWith(path.join('Resources', 'DummyPlugin.bundle'));
+            });
+            it('should rm the file from the right target location', function(){
+                var resources = copyArray(valid_resources);
+                var spy = spyOn(shell, 'rm');
+                uninstall(resources[0], dummyPluginInfo, dummyProject);
+                expect(spy).toHaveBeenCalledWith('-rf', path.join(temp, 'SampleApp', 'Resources', 'DummyPlugin.bundle'));
+            });
+        });
+
+        describe('of <framework> elements', function() {
+            var uninstall = pluginHandlers.getUninstaller('framework');
+            beforeEach(function () {
+                spyOn(dummyProject.xcode, 'removeFramework');
+            });
+
+            it('should call into xcodeproj\'s removeFramework', function(){
+                var frameworks = copyArray(valid_custom_frameworks);
+                uninstall(frameworks[0], dummyPluginInfo, dummyProject);
+                expect(dummyProject.xcode.removeFramework)
+                    .toHaveBeenCalledWith(path.join(temp, 'SampleApp/Plugins/org.test.plugins.dummyplugin/Custom.framework'), {customFramework:true});
+            });
+
+            // TODO: Add more tests to cover the cases:
+            // * framework with weak attribute
+            // * framework that shouldn't be added/removed
+
+            describe('with custom="true" attribute', function () {
+                it('should rm the file from the right target location', function(){
+                    var frameworks = copyArray(valid_custom_frameworks);
+                    var spy = spyOn(shell, 'rm');
+                    uninstall(frameworks[0], dummyPluginInfo, dummyProject);
+                    expect(spy).toHaveBeenCalledWith('-rf', path.join(temp, 'SampleApp/Plugins/org.test.plugins.dummyplugin/Custom.framework'));
+                });
+            });
+        });
+    });
+});


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org


Mime
View raw message