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 <[email protected]> Authored: Wed Mar 2 16:44:09 2016 +0300 Committer: Vladimir Kotikov <[email protected]> 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: [email protected] For additional commands, e-mail: [email protected]
