You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by fi...@apache.org on 2017/06/22 17:34:37 UTC

[06/14] cordova-lib git commit: plugin_fetch.spec.js, hooks runner and plugman fetch specs are all integration tests - moving to integration-tests dir

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/04c12e2b/spec-cordova/HooksRunner.spec.js
----------------------------------------------------------------------
diff --git a/spec-cordova/HooksRunner.spec.js b/spec-cordova/HooksRunner.spec.js
deleted file mode 100644
index d8cc62a..0000000
--- a/spec-cordova/HooksRunner.spec.js
+++ /dev/null
@@ -1,683 +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 boss:true */
-
-var cordova = require('../src/cordova/cordova'),
-    HooksRunner = require('../src/hooks/HooksRunner'),
-    shell  = require('shelljs'),
-    path   = require('path'),
-    fs     = require('fs'),
-    os     = require('os'),
-    Q      = require('q'),
-    child_process = require('child_process'),
-    helpers = require('./helpers'),
-    PluginInfo = require('cordova-common').PluginInfo,
-    superspawn = require('cordova-common').superspawn,
-    config = require('../src/cordova/config');
-
-var platform = os.platform();
-var tmpDir = helpers.tmpDir('hooks_test');
-var project = path.join(tmpDir, 'project');
-var dotCordova = path.join(project, '.cordova');
-var hooksDir = path.join(project, 'hooks');
-var hooksDirDot = path.join(project, '.cordova', 'hooks');
-var scriptsDir = path.join(project, 'scripts');
-var ext = platform.match(/(win32|win64)/)?'bat':'sh';
-var testPluginFixturePath = path.join(__dirname, 'fixtures', 'plugins', 'com.plugin.withhooks');
-
-var cordovaUtil = require('../src/cordova/util');
-
-
-// copy fixture
-shell.rm('-rf', project);
-shell.mkdir('-p', project);
-shell.cp('-R', path.join(__dirname, 'fixtures', 'projWithHooks', '*'), project);
-
-shell.mkdir('-p', dotCordova);
-shell.cp('-R', path.join(__dirname, 'fixtures', 'projWithHooks', '.cordova'), project);
-
-// copy sh/bat scripts
-if(ext === 'bat') {
-    shell.cp('-R', path.join(__dirname, 'fixtures', 'projWithHooks', '_bat', '*'), project);
-    shell.cp('-R', path.join(__dirname, 'fixtures', 'projWithHooks', '_bat', '.cordova'), project);
-} else {
-    shell.cp('-R', path.join(__dirname, 'fixtures', 'projWithHooks', '_sh', '*'), project);
-    shell.cp('-R', path.join(__dirname, 'fixtures', 'projWithHooks', '_sh', '.cordova'), project);
-}
-
-shell.chmod('-R', 'ug+x', hooksDir);
-shell.chmod('-R', 'ug+x', hooksDirDot);
-shell.chmod('-R', 'ug+x', scriptsDir);
-
-// To get more verbose output to help trace program flow, uncomment the lines below
-// TODO: think about how to factor this out so that it can be invoked from the command line
-//var events = require('cordova-common').events;
-//events.on('log', function(msg) { console.log(msg); });
-//events.on('verbose', function(msg) { console.log(msg); });
-//events.on('warn', function(msg) { console.log(msg); });
-
-describe('HooksRunner', function() {
-    var hooksRunner;
-    var hookOptions;
-    var testPluginInstalledPath;
-    var projectRoot;
-    var fire;
-
-    beforeEach(function() {
-        process.chdir(project);
-    });
-
-    afterEach(function() {
-        process.chdir(path.join(__dirname, '..'));  // Non e2e tests assume CWD is repo root.
-    });
-
-    it('Test 001 : should throw if provided directory is not a cordova project', function() {
-        expect(function() {
-            new HooksRunner(tmpDir);
-        }).toThrow();
-    });
-
-    it('Test 002 : should not throw if provided directory is a cordova project', function() {
-        expect(function () {
-            new HooksRunner(project);
-        }).not.toThrow();
-    });
-
-    it('Test 003 : should init test fixtures', function(done) {
-        hooksRunner = new HooksRunner(project);
-
-        // Now we load the config.json in the newly created project and edit the target platform's lib entry
-        // to point at the fixture version. This is necessary so that cordova.prepare can find cordova.js there.
-        var c = config.read(project);
-        c.lib[helpers.testPlatform].url = path.join(__dirname, 'fixtures', 'platforms', helpers.testPlatform + '-lib');
-        config.write(project, c);
-
-        // The config.json in the fixture project points at fake "local" paths.
-        // Since it's not a URL, the lazy-loader will just return the junk path.
-        spyOn(superspawn, 'spawn').and.callFake(function(cmd, args) {
-            if (cmd.match(/create\b/)) {
-                // This is a call to the bin/create script, so do the copy ourselves.
-                shell.cp('-R', path.join(__dirname, 'fixtures', 'platforms', 'android'), path.join(project, 'platforms'));
-            } else if(cmd.match(/update\b/)) {
-                fs.writeFileSync(path.join(project, 'platforms', helpers.testPlatform, 'updated'), 'I was updated!', 'utf-8');
-            } else if (cmd.match(/version/)) {
-                return '3.6.0';
-            }
-            return Q();
-        });
-
-
-        // Add the testing platform.
-        cordova.platform('add', [helpers.testPlatform]).fail(function (err) {
-            expect(err).toBeUndefined();
-            console.error(err);
-            done();
-        }).then(function () {
-            // Add the testing plugin
-            projectRoot = cordovaUtil.isCordova();
-
-            var options = {
-                verbose: false,
-                platforms: [],
-                options: []
-            };
-
-            options = cordovaUtil.preProcessOptions(options);
-
-            hookOptions = { projectRoot: project, cordova: options };
-
-            cordova.plugin('add', testPluginFixturePath).fail(function (err) {
-                expect(err && err.stack).toBeUndefined();
-                done();
-            }).then(function () {
-                testPluginInstalledPath = path.join(projectRoot, 'plugins', 'com.plugin.withhooks');
-                shell.chmod('-R', 'ug+x', path.join(testPluginInstalledPath, 'scripts'));
-                done();
-            });
-        });
-    }, 100000);
-
-    describe('fire method', function() {
-        beforeEach(function() {
-            projectRoot = cordovaUtil.isCordova();
-
-            var options = {
-                verbose: false,
-                platforms: [],
-                options: []
-            };
-
-            options = cordovaUtil.preProcessOptions(options);
-            hookOptions = { projectRoot: project, cordova: options };
-
-            var hooksOrderFile = path.join(projectRoot, 'hooks_order.txt');
-            removeFileIfExists(hooksOrderFile);
-
-            fire = spyOn(HooksRunner.prototype, 'fire').and.callThrough();
-        });
-
-        // helper methods
-        function hooksOrderFileContents(hooksOrderFile) {
-            var order = fs.readFileSync(hooksOrderFile, 'ascii').replace(/\W/gm, ' ');
-
-            var orderArrOriginal = order.split(' ').slice(0);
-
-            function splitNumbers(mixedString) {
-                var re = /\w+/g, match, params = [];
-
-                while (match = re.exec(mixedString)) {
-                    params.push(match[0]);
-                }
-                return params;
-            }
-
-            return splitNumbers(orderArrOriginal).map(function(str) { return parseInt(str, 10); });
-        }
-
-        function hooksOrderFileIsOrdered(hooksOrderFile) {
-            var splitArrOriginal = hooksOrderFileContents(hooksOrderFile);
-            var splitArrSorted = splitArrOriginal.slice(0).sort(function(a, b) { return a - b; });
-
-            return JSON.stringify(splitArrOriginal) === JSON.stringify(splitArrSorted);
-        }
-
-        function backupAppConfig(projectRoot) {
-            shell.cp('-f', path.join(projectRoot, 'config.xml'), path.join(projectRoot, 'configOrig.xml'));
-        }
-
-        function restoreAppConfig(projectRoot) {
-            shell.cp('-f', path.join(projectRoot, 'configOrig.xml'), path.join(projectRoot, 'config.xml'));
-            shell.rm('-rf', path.join(projectRoot, 'configOrig.xml'));
-        }
-
-        function switchToOnlyNonPlatformScriptsAppConfig(projectRoot) {
-            backupAppConfig(projectRoot);
-            shell.cp('-f', path.join(projectRoot, 'configOnlyNonPlatformScripts_' + ext + '.xml'), path.join(projectRoot, 'config.xml'));
-        }
-
-        function switchToOnePlatformScriptsAppConfig(projectRoot) {
-            backupAppConfig(projectRoot);
-            shell.cp('-f', path.join(projectRoot, 'configOnePlatform_' + ext + '.xml'), path.join(projectRoot, 'config.xml'));
-        }
-
-        function switchToTwoPlatformsScriptsAppConfig(projectRoot) {
-            backupAppConfig(projectRoot);
-            shell.cp('-f', path.join(projectRoot, 'configTwoPlatforms_' + ext + '.xml'), path.join(projectRoot, 'config.xml'));
-        }
-
-        function backupPluginConfig() {
-            shell.cp('-f', path.join(testPluginInstalledPath, 'plugin.xml'), path.join(testPluginInstalledPath, 'pluginOrig.xml'));
-        }
-
-        function restorePluginConfig() {
-            shell.cp('-f', path.join(testPluginInstalledPath, 'pluginOrig.xml'), path.join(testPluginInstalledPath, 'plugin.xml'));
-            shell.rm('-rf', path.join(testPluginInstalledPath, 'pluginOrig.xml'));
-        }
-
-        function switchToOnlyNonPlatformScriptsPluginConfig(projectRoot) {
-            backupPluginConfig();
-            shell.cp('-f', path.join(testPluginInstalledPath, 'pluginOnlyNonPlatformScripts_' + ext + '.xml'), path.join(testPluginInstalledPath, 'plugin.xml'));
-        }
-
-        function switchToOnePlatformScriptsPluginConfig(projectRoot) {
-            backupPluginConfig();
-            shell.cp('-f', path.join(testPluginInstalledPath, 'pluginOnePlatform_' + ext + '.xml'), path.join(testPluginInstalledPath, 'plugin.xml'));
-        }
-
-        function switchToTwoPlatformsScriptsPluginConfig(projectRoot) {
-            backupPluginConfig();
-            shell.cp('-f', path.join(testPluginInstalledPath, 'pluginTwoPlatforms_' + ext + '.xml'), path.join(testPluginInstalledPath, 'plugin.xml'));
-        }
-
-        function removeFileIfExists(file) {
-            if (fs.existsSync(file)) {
-                fs.unlinkSync(file);
-            }
-        }
-
-        describe('application hooks', function() {
-            it('Test 004 : should execute hook scripts serially', function (done) {
-                var test_event = 'before_build';
-                var projectRoot = cordovaUtil.isCordova();
-                var hooksOrderFile = path.join(projectRoot, 'hooks_order.txt');
-
-                return hooksRunner.fire(test_event, hookOptions).then(function() {
-                    expect(hooksOrderFile).toExist();
-
-                    expect(hooksOrderFileIsOrdered(hooksOrderFile)).toBe(true);
-                }).fail(function (err) {
-                    expect(err).toBeUndefined();
-                }).then(function () {
-                    done();
-                });
-            });
-
-            it('Test 005 : should execute hook scripts serially from .cordova/hooks/hook_type and hooks/hook_type directories', function (done) {
-                var test_event = 'before_build';
-                var projectRoot = cordovaUtil.isCordova();
-                var hooksOrderFile = path.join(projectRoot, 'hooks_order.txt');
-
-                // using empty platforms list to test only hooks/ directories
-                hookOptions.cordova.platforms = [];
-
-                return hooksRunner.fire(test_event, hookOptions).then(function () {
-                    expect(hooksOrderFile).toExist();
-
-                    expect(hooksOrderFileIsOrdered(hooksOrderFile)).toBe(true);
-                }).fail(function (err) {
-                    expect(err).toBeUndefined();
-                }).then(function () {
-                    done();
-                });
-            });
-
-            it('Test 006 : should execute hook scripts serially from config.xml', function (done) {
-                var test_event = 'before_build';
-                var projectRoot = cordovaUtil.isCordova();
-                var hooksOrderFile = path.join(projectRoot, 'hooks_order.txt');
-
-                switchToOnlyNonPlatformScriptsAppConfig(projectRoot);
-
-                return hooksRunner.fire(test_event, hookOptions).then(function () {
-                    expect(hooksOrderFile).toExist();
-
-                    expect(hooksOrderFileIsOrdered(hooksOrderFile)).toBe(true);
-                }).fail(function (err) {
-                    expect(err).toBeUndefined();
-                }).then(function () {
-                    restoreAppConfig(projectRoot);
-                    done();
-                });
-            });
-
-            it('Test 007 : should execute hook scripts serially from config.xml including platform scripts', function (done) {
-                var test_event = 'before_build';
-                var projectRoot = cordovaUtil.isCordova();
-                var hooksOrderFile = path.join(projectRoot, 'hooks_order.txt');
-
-                switchToOnePlatformScriptsAppConfig(projectRoot);
-
-                return hooksRunner.fire(test_event, hookOptions).then(function () {
-                    expect(hooksOrderFile).toExist();
-
-                    expect(hooksOrderFileIsOrdered(hooksOrderFile)).toBe(true);
-                }).fail(function (err) {
-                    expect(err).toBeUndefined();
-                }).then(function () {
-                    restoreAppConfig(projectRoot);
-                    done();
-                });
-            });
-
-            it('Test 008 : should filter hook scripts from config.xml by platform', function (done) {
-                var test_event = 'before_build';
-                var projectRoot = cordovaUtil.isCordova();
-                var hooksOrderFile = path.join(projectRoot, 'hooks_order.txt');
-
-                switchToTwoPlatformsScriptsAppConfig(projectRoot);
-
-                hookOptions.cordova.platforms = ['android'];
-
-                return hooksRunner.fire(test_event, hookOptions).then(function () {
-                    expect(hooksOrderFile).toExist();
-
-                    expect(hooksOrderFileIsOrdered(hooksOrderFile)).toBe(true);
-
-                    var baseScriptResults = [1, 2, 3, 4, 5, 6, 7, 8, 9];
-                    var androidPlatformScriptsResults = [14, 15];
-
-                    expect(JSON.stringify(hooksOrderFileContents(hooksOrderFile)) ===
-                        JSON.stringify(baseScriptResults.slice(0).concat(androidPlatformScriptsResults))).toBe(true);
-                }).fail(function (err) {
-                    expect(err).toBeUndefined();
-                }).then(function () {
-                    restoreAppConfig(projectRoot);
-                    done();
-                });
-            });
-        });
-
-        describe('plugin hooks', function() {
-            it('Test 009 : should execute hook scripts serially from plugin.xml', function (done) {
-                var test_event = 'before_build';
-                var projectRoot = cordovaUtil.isCordova();
-                var hooksOrderFile = path.join(projectRoot, 'hooks_order.txt');
-
-                switchToOnlyNonPlatformScriptsPluginConfig();
-
-                return hooksRunner.fire(test_event, hookOptions).then(function () {
-                    expect(hooksOrderFile).toExist();
-
-                    expect(hooksOrderFileIsOrdered(hooksOrderFile)).toBe(true);
-                }).fail(function (err) {
-                    expect(err).toBeUndefined();
-                }).then(function () {
-                    restorePluginConfig(projectRoot);
-                    done();
-                });
-            });
-
-            it('Test 010 : should execute hook scripts serially from plugin.xml including platform scripts', function (done) {
-                var test_event = 'before_build';
-                var projectRoot = cordovaUtil.isCordova();
-                var hooksOrderFile = path.join(projectRoot, 'hooks_order.txt');
-
-                switchToOnePlatformScriptsPluginConfig();
-
-                return hooksRunner.fire(test_event, hookOptions).then(function () {
-                    expect(hooksOrderFile).toExist();
-
-                    expect(hooksOrderFileIsOrdered(hooksOrderFile)).toBe(true);
-                }).fail(function (err) {
-                    expect(err).toBeUndefined();
-                }).then(function () {
-                    restorePluginConfig(projectRoot);
-                    done();
-                });
-            });
-
-            it('Test 011 : should filter hook scripts from plugin.xml by platform', function (done) {
-                var test_event = 'before_build';
-                var projectRoot = cordovaUtil.isCordova();
-                var hooksOrderFile = path.join(projectRoot, 'hooks_order.txt');
-
-                switchToTwoPlatformsScriptsPluginConfig(projectRoot);
-
-                hookOptions.cordova.platforms = ['android'];
-
-                return hooksRunner.fire(test_event, hookOptions).then(function () {
-                    expect(hooksOrderFile).toExist();
-
-                    expect(hooksOrderFileIsOrdered(hooksOrderFile)).toBe(true);
-
-                    var baseScriptResults = [1, 2, 3, 4, 5, 6, 7, 21, 22];
-                    var androidPlatformScriptsResults = [26];
-
-                    expect(JSON.stringify(hooksOrderFileContents(hooksOrderFile)) ===
-                        JSON.stringify(baseScriptResults.slice(0).concat(androidPlatformScriptsResults))).toBe(true);
-                }).fail(function (err) {
-                    expect(err).toBeUndefined();
-                }).then(function () {
-                    restorePluginConfig(projectRoot);
-                    done();
-                });
-            });
-
-            it('Test 012 : should run before_plugin_uninstall, before_plugin_install, after_plugin_install hooks for a plugin being installed with correct opts.plugin context', function (done) {
-                var projectRoot = cordovaUtil.isCordova();
-
-                // remove plugin
-                cordova.plugin('rm', 'com.plugin.withhooks').fail(function (err) {
-                    expect(err.stack).toBeUndefined();
-                }).then(function () {
-                    cordova.plugin('add', testPluginFixturePath).fail(function (err) {
-                        expect(err).toBeUndefined();
-                    }).then(function () {
-                        testPluginInstalledPath = path.join(projectRoot, 'plugins', 'com.plugin.withhooks');
-                        shell.chmod('-R', 'ug+x', path.join(testPluginInstalledPath, 'scripts'));
-
-                        var pluginInfo = new PluginInfo(testPluginInstalledPath);
-
-                        var cordovaVersion = require('../package').version;
-
-                        var androidPluginOpts = {
-                            cordova: {
-                                platforms: [ 'android' ],
-                                plugins: ['com.plugin.withhooks'],
-                                version: cordovaVersion
-                            },
-                            plugin: {
-                                id: 'com.plugin.withhooks',
-                                pluginInfo: pluginInfo,
-                                platform: 'android',
-                                dir: testPluginInstalledPath
-                            },
-                            projectRoot: projectRoot
-                        };
-                        // Delete unique ids to allow comparing PluginInfo
-                        delete androidPluginOpts.plugin.pluginInfo._et;
-
-                        fire.calls.all().forEach(function(call) {
-                            if(call.args[1] && call.args[1].plugin) {
-                                // Delete unique ids to allow comparing PluginInfo
-                                delete call.args[1].plugin.pluginInfo._et;
-                            }
-
-                            if(call.args[0] == 'before_plugin_uninstall' ||
-                                call.args[0] == 'before_plugin_install' ||
-                                call.args[0] == 'after_plugin_install') {
-                                if(call.args[1]) {
-                                    expect(call.args[1].plugin).toBeDefined();
-                                    if(call.args[1].plugin.platform == 'android') {
-                                        expect(JSON.stringify(androidPluginOpts) ===
-                                            JSON.stringify(call.args[1])).toBe(true);
-                                    }
-                                }
-                            }
-                        });
-                    }).fail(function (err) {
-                        expect(err).toBeUndefined();
-                    }).fin(done);
-                });
-            });
-
-            it('Test 013 : should not execute the designated hook when --nohooks option specifies the exact hook name', function (done) {
-                var test_event = 'before_build';
-                hookOptions.nohooks = ['before_build'];
-
-                return hooksRunner.fire(test_event, hookOptions).then(function (msg) {
-                    expect(msg).toBeDefined();
-                    expect(msg).toBe('hook before_build is disabled.');
-                }).fail(function (err) {
-                    expect(err).toBeUndefined();
-                }).then(function () {
-                    done();
-                });
-            });
-
-            it('Test 014 : should not execute a set of matched hooks when --nohooks option specifies the hook pattern.', function (done) {
-                var test_events = ['before_build', 'after_plugin_add', 'before_platform_rm', 'before_prepare'];
-                hookOptions.nohooks = ['before*'];
-
-                return test_events.reduce(function(soFar, test_event) {
-                    return soFar.then(function() {
-                        return hooksRunner.fire(test_event, hookOptions).then(function (msg) {
-                            if (msg) {
-                                expect(msg).toBe('hook ' + test_event + ' is disabled.');
-                            } else {
-                                expect(test_event).toBe('after_plugin_add');
-                            }
-                        });
-                    });
-                }, Q()).fail(function (err) {
-                    expect(err).toBeUndefined();
-                }).then(function () {
-                    done();
-                });
-            });
-
-            it('Test 015 : should not execute all hooks when --nohooks option specifies .', function (done) {
-                var test_events = ['before_build', 'after_plugin_add', 'before_platform_rm', 'before_prepare'];
-                hookOptions.nohooks = ['.'];
-
-                return test_events.reduce(function(soFar, test_event) {
-                    return soFar.then(function() {
-                        return hooksRunner.fire(test_event, hookOptions).then(function (msg) {
-                            expect(msg).toBeDefined();
-                            expect(msg).toBe('hook ' + test_event + ' is disabled.');
-                        });
-                    });
-                }, Q()).fail(function (err) {
-                    expect(err).toBeUndefined();
-                }).then(function () {
-                    done();
-                });
-            });
-        });
-
-        describe('module-level hooks (event handlers)', function() {
-            var handler = jasmine.createSpy().and.returnValue(Q());
-            var test_event = 'before_build';
-
-            afterEach(function () {
-                cordova.removeAllListeners(test_event);
-                handler.calls.reset();
-            });
-
-            it('Test 016 : should fire handlers using cordova.on', function(done) {
-                cordova.on(test_event, handler);
-                hooksRunner.fire(test_event, hookOptions).then(function () {
-                    expect(handler).toHaveBeenCalled();
-                }).fail(function (err) {
-                    expect(err).not.toBeDefined();
-                }).fin(done);
-            });
-
-            it('Test 017 : should pass the project root folder as parameter into the module-level handlers', function (done) {
-                cordova.on(test_event, handler);
-                hooksRunner.fire(test_event, hookOptions).then(function () {
-                    expect(handler).toHaveBeenCalledWith(hookOptions);
-                }).fail(function (err) {
-                    console.log(err);
-                    expect(err).not.toBeDefined();
-                }).fin(done);
-            });
-
-            it('Test 018 : should be able to stop listening to events using cordova.off', function(done) {
-                cordova.on(test_event, handler);
-                cordova.off(test_event, handler);
-                hooksRunner.fire(test_event, hookOptions).then(function () {
-                    expect(handler).not.toHaveBeenCalled();
-                }).fail(function (err) {
-                    console.log(err);
-                    expect(err).toBeUndefined();
-                }).fin(done);
-            });
-
-            it('Test 019 : should execute event listeners serially', function(done) {
-                var h1_fired = false;
-                var h2_fired;
-                var h1 = function() {
-                    expect(h2_fired).toBe(false);
-                    // Delay 100 ms here to check that h2 is not executed until after
-                    // the promise returned by h1 is resolved.
-                    var q = Q.delay(100).then(function() {
-                        h1_fired = true;
-                    });
-                    return q;
-                };
-                h2_fired = false;
-                var h2 = function() {
-                    h2_fired = true;
-                    expect(h1_fired).toBe(true);
-                    return Q();
-                };
-
-                cordova.on(test_event, h1);
-                cordova.on(test_event, h2);
-
-                return hooksRunner.fire(test_event, hookOptions).then(function() {
-                    expect(h1_fired).toBe(true);
-                    expect(h2_fired).toBe(true);
-                }).fail(function(err) {
-                    expect(err).toBeUndefined();
-                }).then(function() {
-                    cordova.removeAllListeners(test_event);
-                    done();
-                });
-            });
-
-            it('Test 020 : should allow for hook to opt into asynchronous execution and block further hooks from firing using the done callback', function(done) {
-                var h1_fired = false;
-                var h2_fired;
-                var h1 = function () {
-                    h1_fired = true;
-                    expect(h2_fired).toBe(false);
-                    return Q();
-                };
-                h2_fired = false;
-                var h2 = function () {
-                    h2_fired = true;
-                    expect(h1_fired).toBe(true);
-                    return Q();
-                };
-
-                cordova.on(test_event, h1);
-                cordova.on(test_event, h2);
-                hooksRunner.fire(test_event, hookOptions).then(function() {
-                    expect(h1_fired).toBe(true);
-                    expect(h2_fired).toBe(true);
-                    done();
-                });
-            });
-
-            it('Test 021 : should pass data object that fire calls into async handlers', function(done) {
-                var async = function (opts) {
-                    expect(opts).toEqual(hookOptions);
-                    return Q();
-                };
-                cordova.on(test_event, async);
-                hooksRunner.fire(test_event, hookOptions).then(function () {
-                    done();
-                });
-            });
-
-            it('Test 022 : should pass data object that fire calls into sync handlers', function(done) {
-                var async = function (opts) {
-                    expect(opts).toEqual(hookOptions);
-                };
-                cordova.on(test_event, async);
-                hooksRunner.fire(test_event, hookOptions).fin(done);
-            });
-
-            it('Test 023 : should error if any script exits with non-zero code', function(done) {
-                hooksRunner.fire('fail', hookOptions).then(function () {
-                    expect('the call').toBe('a failure');
-                }, function (err) {
-                    expect(err).toBeDefined();
-                }).fin(done);
-            });
-        });
-
-        it('Test 024 :should not error if the hook is unrecognized', function(done) {
-            hooksRunner.fire('CLEAN YOUR SHORTS GODDAMNIT LIKE A BIG BOY!', hookOptions).fail(function (err) {
-                expect('Call with unrecognized hook ').toBe('successful.\n' + err);
-            }).fin(done);
-        });
-    });
-
-    // Cleanup. Must be the last spec. Is there a better place for final cleanup in Jasmine?
-    it('Test 025 : should not fail during cleanup', function () {
-        process.chdir(path.join(__dirname, '..'));  // Non e2e tests assume CWD is repo root.
-        if (ext == 'sh') {
-            shell.rm('-rf', tmpDir);
-        } else { // Windows:
-            // For some mysterious reason, both shell.rm and RMDIR /S /Q won't
-            // delete the dir on Windows, but they do remove the files leaving
-            // only folders. But the dir is removed just fine by
-            // shell.rm('-rf', tmpDir) at the top of this file with the next
-            // invocation of this test. The benefit of RMDIR /S /Q is that it
-            // doesn't print warnings like shell.rmdir() that look like this:
-            // rm: could not remove directory (code ENOTEMPTY): C:\Users\...
-            var cmd = 'RMDIR /S /Q ' + tmpDir;
-            child_process.exec(cmd);
-        }
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/04c12e2b/spec-cordova/plugin_fetch.spec.js
----------------------------------------------------------------------
diff --git a/spec-cordova/plugin_fetch.spec.js b/spec-cordova/plugin_fetch.spec.js
deleted file mode 100644
index eab2768..0000000
--- a/spec-cordova/plugin_fetch.spec.js
+++ /dev/null
@@ -1,536 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-
-var plugin  = require('../src/cordova/plugin'),
-    helpers = require('./helpers'),
-    path    = require('path'),
-    events = require('cordova-common').events,
-    shell   = require('shelljs');
-
-var testPluginVersions = [
-    '0.0.2',
-    '0.7.0',
-    '1.0.0',
-    '1.1.0',
-    '1.1.3',
-    '1.3.0',
-    '1.7.0',
-    '1.7.1',
-    '2.0.0-rc.1',
-    '2.0.0-rc.2',
-    '2.0.0',
-    '2.3.0'
-];
-
-var cordovaVersion = '3.4.2';
-
-var tempDir = helpers.tmpDir('plugin_fetch_spec');
-var project = path.join(tempDir, 'project');
-
-var getVersionErrorCallback;
-var warnings = [];
-
-// Used to extract the constraint, the installed version, and the required
-// semver range from a warning message
-var UNMET_REQ_REGEX = /\s+([^\s]+)[^\d]+(\d+\.\d+\.\d+) in project, (.+) required\)/;
-
-// We generate warnings when we don't fetch latest. Collect them to make sure we
-// are making the correct warnings
-events.on('warn', function(warning) {
-    warnings.push(warning);
-});
-
-// Tests a sample engine against the installed platforms/plugins in our test
-// project
-function testEngineWithProject(done, testEngine, testResult) {
-    plugin.getFetchVersion(project,
-        {
-            'version': '2.3.0',
-            'name': 'test-plugin',
-            'engines': { 'cordovaDependencies': testEngine },
-            'versions': testPluginVersions
-        }, cordovaVersion)
-    .then(function(toFetch) {
-        expect(toFetch).toBe(testResult);
-    })
-    .fail(getVersionErrorCallback)
-    .fin(done);
-}
-
-// Checks the warnings that were printed by the CLI to ensure that the code is
-// listing the correct reasons for failure. Checks against the global warnings
-// object which is reset before each test
-function checkUnmetRequirements(requirements) {
-    var reqWarnings = [];
-
-    warnings.forEach(function(warning) {
-        var extracted = UNMET_REQ_REGEX.exec(warning);
-        if (extracted) {
-            reqWarnings.push({
-                dependency: extracted[1],
-                installed: extracted[2],
-                required: extracted[3]
-            });
-        }
-    });
-    expect(reqWarnings.length).toEqual(requirements.length);
-
-
-    requirements.forEach(function(requirement) {
-        expect(reqWarnings).toContainArray(function(extractedWarning) {
-            return  extractedWarning.dependency === requirement.dependency.trim() &&
-                    extractedWarning.installed  === requirement.installed.trim() &&
-                    extractedWarning.required   === requirement.required.trim();
-        }, requirement);
-    });
-}
-
-// Helper functions for creating the requirements objects taken by
-// checkUnmetRequirements()
-function getPlatformRequirement(requirement) {
-    return {
-        dependency: 'cordova-android',
-        installed: '3.1.0',
-        required: requirement
-    };
-}
-
-function getCordovaRequirement(requirement) {
-    return {
-        dependency: 'cordova',
-        installed: cordovaVersion,
-        required: requirement
-    };
-}
-
-function getPluginRequirement(requirement) {
-    return {
-        dependency: 'ca.filmaj.AndroidPlugin',
-        installed: '4.2.0',
-        required: requirement
-    };
-}
-
-// Generates a callback that checks warning messages after the test is complete
-function getWarningCheckCallback(done, requirements) {
-    return function() {
-        checkUnmetRequirements(requirements);
-        expect(getVersionErrorCallback).not.toHaveBeenCalled();
-        done();
-    };
-}
-
-function createTestProject() {
-    // Get the base project
-    shell.cp('-R', path.join(__dirname, 'fixtures', 'base'), tempDir);
-    shell.mv(path.join(tempDir, 'base'), project);
-
-    // Copy a platform and a plugin to our sample project
-    shell.cp('-R',
-        path.join(__dirname, 'fixtures', 'platforms', helpers.testPlatform),
-        path.join(project, 'platforms'));
-    shell.cp('-R',
-        path.join(__dirname, 'fixtures', 'plugins', 'android'),
-        path.join(project, 'plugins'));
-}
-
-function removeTestProject() {
-    shell.rm('-rf', tempDir);
-}
-
-describe('plugin fetching version selection', function() {
-    createTestProject();
-    beforeEach(function() {
-        jasmine.addMatchers({
-            'toContainArray': function() {
-                return {
-                    compare: function(actual, expected) {
-                        var result = {};
-                        result.pass = false;
-                        for(var i = 0; i < actual.length; i++) {
-                            if (expected(actual[i])) {
-                                result.pass = true;
-                                break;
-                            }
-                        }
-                        return result;
-                    }
-                };
-            }
-        });
-
-        warnings = [];
-        getVersionErrorCallback = jasmine.createSpy('unexpectedPluginFetchErrorCallback');
-    });
-
-    it('Test 001 : should handle a mix of upper bounds and single versions', function(done) {
-        var testEngine = {
-            '0.0.0' : { 'cordova-android': '1.0.0' },
-            '0.0.2' : { 'cordova-android': '>1.0.0' },
-            '<1.0.0': { 'cordova-android': '<2.0.0' },
-            '1.0.0' : { 'cordova-android': '>2.0.0' },
-            '1.7.0' : { 'cordova-android': '>4.0.0' },
-            '<2.3.0': { 'cordova-android': '<6.1.1' },
-            '2.3.0' : { 'cordova-android': '6.1.1' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('6.1.1')
-        ]);
-        testEngineWithProject(after, testEngine, '1.3.0');
-    }, 6000);
-
-    it('Test 002 : should apply upper bound engine constraints when there are no unspecified constraints above the upper bound', function(done) {
-        var testEngine = {
-            '1.0.0' : { 'cordova-android': '>2.0.0' },
-            '1.7.0' : { 'cordova-android': '>4.0.0' },
-            '<2.3.0': {
-                'cordova-android': '<6.1.1',
-                'ca.filmaj.AndroidPlugin': '<1.0.0'
-            },
-            '2.3.0' : { 'cordova-android': '6.1.1' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('6.1.1')
-        ]);
-        testEngineWithProject(after, testEngine, null);
-    });
-
-    it('Test 003 : should apply upper bound engine constraints when there are unspecified constraints above the upper bound', function(done) {
-        var testEngine = {
-            '0.0.0' : {},
-            '2.0.0' : { 'cordova-android': '~5.0.0' },
-            '<1.0.0': { 'cordova-android': '>5.0.0' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('~5.0.0')
-        ]);
-        testEngineWithProject(after, testEngine, '1.7.1');
-
-    });
-
-    it('Test 004 : should handle the case where there are no constraints for earliest releases', function(done) {
-        var testEngine = {
-            '1.0.0' : { 'cordova-android': '~5.0.0' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('~5.0.0')
-        ]);
-        testEngineWithProject(after, testEngine, '0.7.0');
-
-    });
-
-    it('Test 005 : should handle the case where the lowest version is unsatisfied', function(done) {
-        var testEngine = {
-            '0.0.2' : { 'cordova-android': '~5.0.0' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('~5.0.0')
-        ]);
-        testEngineWithProject(after, testEngine, null);
-
-    });
-
-    it('Test 006 : should handle upperbounds if no single version constraints are given', function(done) {
-        var testEngine = {
-            '<1.0.0': { 'cordova-android': '<2.0.0' }
-        };
-
-        var after = getWarningCheckCallback(done, []);
-
-        testEngineWithProject(after, testEngine, '2.3.0');
-
-    });
-
-    it('Test 007 : should apply upper bounds greater than highest version', function(done) {
-        var testEngine = {
-            '0.0.0' : {},
-            '<5.0.0': { 'cordova-android': '<2.0.0' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('<2.0.0')
-        ]);
-
-        testEngineWithProject(after, testEngine, null);
-
-    });
-
-    it('Test 008 : should treat empty constraints as satisfied', function(done) {
-        var testEngine = {
-            '1.0.0' : {},
-            '1.1.0' : { 'cordova-android': '>5.0.0' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('>5.0.0')
-        ]);
-
-        testEngineWithProject(after, testEngine, '1.0.0');
-
-    });
-
-    it('Test 009 : should ignore an empty cordovaDependencies entry', function(done) {
-        var testEngine = {};
-
-        var after = getWarningCheckCallback(done, []);
-
-        testEngineWithProject(after, testEngine, null);
-
-    });
-
-    it('Test 010 : should ignore a badly formatted semver range', function(done) {
-        var testEngine = {
-            '1.1.3' : { 'cordova-android': 'badSemverRange' }
-        };
-
-        var after = getWarningCheckCallback(done, []);
-
-        testEngineWithProject(after, testEngine, '2.3.0');
-
-    });
-
-    it('Test 011 : should respect unreleased versions in constraints', function(done) {
-        var testEngine = {
-            '1.0.0' : { 'cordova-android': '3.1.0' },
-            '1.1.2' : { 'cordova-android': '6.1.1' },
-            '1.3.0' : { 'cordova-android': '6.1.1' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('6.1.1')
-        ]);
-
-        testEngineWithProject(after, testEngine, '1.1.0');
-
-    });
-
-    it('Test 012 : should respect plugin constraints', function(done) {
-        var testEngine = {
-            '0.0.0' : { 'ca.filmaj.AndroidPlugin': '1.2.0' },
-            '1.1.3' : { 'ca.filmaj.AndroidPlugin': '<5.0.0 || >2.3.0' },
-            '2.3.0' : { 'ca.filmaj.AndroidPlugin': '6.1.1' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPluginRequirement('6.1.1')
-        ]);
-
-        testEngineWithProject(after, testEngine, '2.0.0');
-
-    });
-
-    it('Test 013 : should respect cordova constraints', function(done) {
-        var testEngine = {
-            '0.0.0' : { 'cordova': '>1.0.0' },
-            '1.1.3' : { 'cordova': '<3.0.0 || >4.0.0' },
-            '2.3.0' : { 'cordova': '6.1.1' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getCordovaRequirement('6.1.1')
-        ]);
-
-        testEngineWithProject(after, testEngine, '1.1.0');
-
-    });
-
-    it('Test 014 : should not include pre-release versions', function(done) {
-        var testEngine = {
-            '0.0.0' : {},
-            '2.0.0' : { 'cordova-android': '>5.0.0' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('>5.0.0')
-        ]);
-
-        // Should not return 2.0.0-rc.2
-        testEngineWithProject(after, testEngine, '1.7.1');
-
-    });
-
-    it('Test 015 : should not fail if there is no engine in the npm info', function(done) {
-        plugin.getFetchVersion(project, {
-                version: '2.3.0',
-                name: 'test-plugin',
-                versions: testPluginVersions
-            }, cordovaVersion)
-        .then(function(toFetch) {
-            expect(toFetch).toBe(null);
-        })
-        .fail(getVersionErrorCallback).fin(done);
-    });
-
-    it('Test 016 : should not fail if there is no cordovaDependencies in the engines', function(done) {
-        var after = getWarningCheckCallback(done, []);
-
-        plugin.getFetchVersion(project, {
-                version: '2.3.0',
-                name: 'test-plugin',
-                versions: testPluginVersions,
-                engines: {
-                    'node': '>7.0.0',
-                    'npm': '~2.0.0'
-                }
-            }, cordovaVersion)
-        .then(function(toFetch) {
-            expect(toFetch).toBe(null);
-        })
-        .fail(getVersionErrorCallback).fin(after);
-
-    });
-
-    it('Test 017 : should handle extra whitespace', function(done) {
-        var testEngine = {
-            '  1.0.0    '   : {},
-            '2.0.0   '      : { ' cordova-android': '~5.0.0   ' },
-            ' <  1.0.0\t'   : { ' cordova-android  ': ' > 5.0.0' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('~5.0.0')
-        ]);
-
-        testEngineWithProject(after, testEngine, '1.7.1');
-
-    });
-
-    it('Test 018 : should ignore badly typed version requirement entries', function(done) {
-        var testEngine = {
-            '1.1.0' : ['cordova', '5.0.0'],
-            '1.3.0' : undefined,
-            '1.7.0' : null
-        };
-
-        var after = getWarningCheckCallback(done, []);
-
-        testEngineWithProject(after, testEngine, '2.3.0');
-
-    });
-
-    it('Test 019 : should ignore badly typed constraint entries', function(done) {
-        var testEngine = {
-            '0.0.2' : { 'cordova': 1 },
-            '0.7.0' : { 'cordova': {}},
-            '1.0.0' : { 'cordova': undefined},
-            '1.1.3' : { 8        : '5.0.0'},
-            '1.3.0' : { 'cordova': [] },
-            '1.7.1' : { 'cordova': null }
-        };
-
-        var after = getWarningCheckCallback(done, []);
-
-        testEngineWithProject(after, testEngine, '2.3.0');
-
-    });
-
-    it('Test 020 : should ignore bad semver versions', function(done) {
-        var testEngine = {
-            '0.0.0'         : { 'cordova-android': '5.0.0' },
-            'notAVersion'   : { 'cordova-android': '3.1.0' },
-            '^1.1.2'        : { 'cordova-android': '3.1.0' },
-            '<=1.3.0'       : { 'cordova-android': '3.1.0' },
-            '1.0'           : { 'cordova-android': '3.1.0' },
-            '2'               : { 'cordova-android': '3.1.0' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('5.0.0')
-        ]);
-
-        testEngineWithProject(after, testEngine, null);
-    });
-
-    it('Test 021 : should not fail if there are bad semver versions', function(done) {
-        var testEngine = {
-            'notAVersion'   : { 'cordova-android': '3.1.0' },
-            '^1.1.2'        : { 'cordova-android': '3.1.0' },
-            '<=1.3.0'       : { 'cordova-android': '3.1.0' },
-            '1.0.0'         : { 'cordova-android': '~3'    },   // Good semver
-            '2.0.0'         : { 'cordova-android': '5.1.0' },   // Good semver
-            '1.0'           : { 'cordova-android': '3.1.0' },
-            '2'               : { 'cordova-android': '3.1.0' }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('5.1.0')
-        ]);
-
-        testEngineWithProject(after, testEngine, '1.7.1');
-    });
-
-    it('Test 022 : should properly warn about multiple unmet requirements', function(done) {
-        var testEngine = {
-            '1.7.0' : {
-                'cordova-android'           : '>5.1.0',
-                'ca.filmaj.AndroidPlugin'   : '3.1.0',
-                'cordova'                   : '3.4.2'
-            }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('>5.1.0'),
-            getPluginRequirement('3.1.0')
-        ]);
-
-        testEngineWithProject(after, testEngine, '1.3.0');
-    });
-
-    it('Test 023 : should properly warn about both unmet latest and upper bound requirements', function(done) {
-        var testEngine = {
-            '1.7.0' : { 'cordova-android': '>5.1.0' },
-            '<5.0.0': {
-                'cordova-android'           : '>7.1.0',
-                'ca.filmaj.AndroidPlugin'   : '3.1.0'
-            }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('>5.1.0 AND >7.1.0'),
-            getPluginRequirement('3.1.0')
-        ]);
-
-        testEngineWithProject(after, testEngine, null);
-    });
-
-    it('Test 024 : should not warn about versions past latest', function(done) {
-        var testEngine = {
-            '1.7.0' : { 'cordova-android': '>5.1.0' },
-            '7.0.0': {
-                'cordova-android'           : '>7.1.0',
-                'ca.filmaj.AndroidPlugin'   : '3.1.0'
-            }
-        };
-
-        var after = getWarningCheckCallback(done, [
-            getPlatformRequirement('>5.1.0')
-        ]);
-
-        testEngineWithProject(after, testEngine, '1.3.0');
-    });
-
-    it('Test 025 : clean up after plugin fetch spec', function() {
-        removeTestProject();
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/04c12e2b/spec-plugman/fetch.spec.js
----------------------------------------------------------------------
diff --git a/spec-plugman/fetch.spec.js b/spec-plugman/fetch.spec.js
deleted file mode 100644
index f772822..0000000
--- a/spec-plugman/fetch.spec.js
+++ /dev/null
@@ -1,339 +0,0 @@
-/**
-    Licensed to the Apache Software Foundation (ASF) under one
-    or more contributor license agreements.  See the NOTICE file
-    distributed with this work for additional information
-    regarding copyright ownership.  The ASF licenses this file
-    to you under the Apache License, Version 2.0 (the
-    "License"); you may not use this file except in compliance
-    with the License.  You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing,
-    software distributed under the License is distributed on an
-    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-    KIND, either express or implied.  See the License for the
-    specific language governing permissions and limitations
-    under the License.
-*/
-var rewire  = require('rewire'),
-    fetch   = rewire('../src/plugman/fetch'),
-    fs      = require('fs'),
-    os      = require('os'),
-    path    = require('path'),
-    shell   = require('shelljs'),
-    realrm  = shell.rm,
-    TIMEOUT = 60 * 1000,
-    //xml_helpers = require('../src/util/xml-helpers'),
-    metadata = require('../src/plugman/util/metadata'),
-    temp    = path.join(os.tmpdir(), 'plugman', 'fetch'),
-    test_plugin = path.join(__dirname, 'plugins', 'org.test.plugins.childbrowser'),
-    test_pkgjson_plugin = path.join(__dirname, 'plugins', 'pkgjson-test-plugin'),
-    test_plugin_searchpath = path.join(test_plugin, '..'),
-    //test_plugin_with_space = path.join(__dirname, 'folder with space', 'plugins', 'org.test.plugins.childbrowser'),
-    //test_plugin_xml = xml_helpers.parseElementtreeSync(path.join(test_plugin, 'plugin.xml')),
-    test_plugin_id = 'org.test.plugins.childbrowser',
-    test_plugin_version ='0.6.0',
-    plugins = require('../src/plugman/util/plugins'),
-    Q = require('q'),
-    registry = require('../src/plugman/registry/registry');
-
-describe('fetch', function() {
-
-    function wrapper(p, done, post) {
-        p.then(post, function(err) {
-            expect(err).toBeUndefined('Unexpected exception' + err.stack);
-        }).fin(done);
-    }
-    /*
-     * Taking out the following test. Fetch has a copyPlugin method that uses existsSync to see if a plugin already exists in the plugins folder. If the plugin exists in the plugins directory for the cordova project, it won't be copied over. This test fails now due it always returning true for existsSync.
-    describe('plugin in a dir with spaces', function() {
-        it('should copy locally-available plugin to plugins directory when spaces in path', function(done) {
-            // XXX: added this because plugman tries to fetch from registry when plugin folder does not exist
-            spyOn(fs,'existsSync').andReturn(true);
-            spyOn(xml_helpers, 'parseElementtreeSync').andReturn(test_plugin_xml);
-            spyOn(shell, 'rm');
-            spyOn(metadata, 'save_fetch_metadata');
-            var cp = spyOn(shell, 'cp');
-            wrapper(fetch(test_plugin_with_space, temp), done, function() {
-                expect(cp).toHaveBeenCalledWith('-R', path.join(test_plugin_with_space, '*'), path.join(temp, test_plugin_id));
-            });
-        });
-    });
-*/
-    describe('local plugins', function() {
-        var rm, sym, cp, save_metadata, revertLocal, revertFetch, fetchCalls = 0;
-        beforeEach(function() {
-            rm = spyOn(shell, 'rm');
-            sym = spyOn(fs, 'symlinkSync');
-            cp = spyOn(shell, 'cp').and.callThrough();
-            save_metadata = spyOn(metadata, 'save_fetch_metadata');
-            realrm('-rf', temp);
-            revertLocal = fetch.__set__('localPlugins', null);
-            revertFetch = fetch.__set__('fetch', function(pluginDir) {
-                fetchCalls ++;
-                return Q(pluginDir);
-            });
-        });
-
-        afterEach(function(){
-            revertLocal();
-            revertFetch();
-            fetchCalls = 0;
-        });
-
-        it('Test 001 : should copy locally-available plugin to plugins directory', function(done) {
-            wrapper(fetch(test_plugin, temp), done, function() {
-                expect(cp).toHaveBeenCalledWith('-R', path.join(test_plugin, '*'), path.join(temp, test_plugin_id));
-            });
-        });
-        it('Test 002 : should copy locally-available plugin to plugins directory when adding a plugin with searchpath argument', function(done) {
-            wrapper(fetch(test_plugin_id, temp, { searchpath: test_plugin_searchpath }), done, function() {
-                expect(cp).toHaveBeenCalledWith('-R', path.join(test_plugin, '*'), path.join(temp, test_plugin_id));
-            });
-        });
-        it('Test 003 : should create a symlink if used with `link` param', function(done) {
-            wrapper(fetch(test_plugin, temp, { link: true }), done, function() {
-                expect(sym).toHaveBeenCalledWith(test_plugin, path.join(temp, test_plugin_id), 'dir');
-            });
-        });
-
-        it('Test 004 : should fail when the expected ID doesn\'t match', function(done) {
-            fetch(test_plugin, temp, { expected_id: 'wrongID' })
-            .then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(''+err).toContain('Expected plugin to have ID "wrongID" but got');
-            }).fin(done);
-        });
-
-        it('Test 005 : should succeed when the expected ID is correct', function(done) {
-            wrapper(fetch(test_plugin, temp, { expected_id: test_plugin_id }), done, function() {
-                expect(1).toBe(1);
-            });
-        });
-        it('Test 006 : should fail when the expected ID with version specified doesn\'t match', function(done) {
-            fetch(test_plugin, temp, { expected_id: test_plugin_id + '@wrongVersion' })
-            .then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(''+err).toContain('to satisfy version "wrongVersion" but got');
-            }).fin(done);
-        });
-        it('Test 007 : should succeed when the plugin version specified is correct', function(done) {
-            var exp_id = test_plugin_id + '@' + test_plugin_version;
-            wrapper(fetch(test_plugin, temp, { expected_id: exp_id}), done, function() {
-                expect(1).toBe(1);
-            });
-        });
-        it('Test 027 : should copy locally-available plugin to plugins directory', function(done) {
-            wrapper(fetch(test_pkgjson_plugin, temp, {fetch:true}), done, function() {
-                expect(cp).toHaveBeenCalledWith('-R', path.join(test_pkgjson_plugin, '*'), path.join(temp, 'pkgjson-test-plugin'));
-                expect(fetchCalls).toBe(1);
-            });
-        });
-        it('Test 028 : should fail when locally-available plugin is missing pacakge.json', function(done) {
-            fetch(test_plugin, temp, {fetch:true})
-            .then(function() {
-                expect(false).toBe(true);
-            }).fail(function(err) { 
-                expect(err).toBeDefined();
-                expect(err.message).toContain('needs a valid package.json');
-                done();
-            });
-        });
-    });
-    describe('git plugins', function() {
-        var clone, save_metadata, done;
-
-        beforeEach(function() {
-            clone = spyOn(plugins, 'clonePluginGitRepo').and.returnValue(Q(test_plugin));
-            save_metadata = spyOn(metadata, 'save_fetch_metadata');
-            done = false;
-        });
-        it('Test 008 : should call clonePluginGitRepo for https:// and git:// based urls', function(done) {
-            var url = 'https://github.com/bobeast/GAPlugin.git';
-                fetch(url, temp).then(function(){
-                    expect(save_metadata).toHaveBeenCalled();
-                    expect(clone).toHaveBeenCalledWith(url, temp, '.', undefined, undefined);
-                    done();
-            });
-        }, 6000);
-        
-        it('Test 009 : should call clonePluginGitRepo with subdir if applicable', function(done) {
-            var url = 'https://github.com/bobeast/GAPlugin.git';
-            var dir = 'fakeSubDir';
-            fetch(url, temp, { subdir: dir }).then(function(){
-                expect(clone).toHaveBeenCalledWith(url, temp, dir, undefined, undefined);
-                expect(save_metadata).toHaveBeenCalled();
-                done();
-            });
-        }, 6000);
-
-        it('Test 010 : should call clonePluginGitRepo with subdir and git ref if applicable', function(done) {
-            var url = 'https://github.com/bobeast/GAPlugin.git';
-            var dir = 'fakeSubDir';
-            var ref = 'fakeGitRef';
-            fetch(url, temp, { subdir: dir, git_ref: ref }).then(function(){
-                expect(clone).toHaveBeenCalledWith(url, temp, dir, ref, undefined);
-                expect(save_metadata).toHaveBeenCalled();
-                done();
-            });
-        }, 6000);
-
-        it('Test 011 : should extract the git ref from the URL hash, if provided', function(done) {
-            var url = 'https://github.com/bobeast/GAPlugin.git#fakeGitRef';
-            var baseURL = 'https://github.com/bobeast/GAPlugin.git';
-            fetch(url, temp, {}).then(function(){
-                expect(clone).toHaveBeenCalledWith(baseURL, temp, '.', 'fakeGitRef', undefined);
-                expect(save_metadata).toHaveBeenCalled();
-                done();
-            });
-        }, 6000);
-
-        it('Test 012 : should extract the subdir from the URL hash, if provided', function(done) {
-            var url = 'https://github.com/bobeast/GAPlugin.git#:fakeSubDir';
-            var baseURL = 'https://github.com/bobeast/GAPlugin.git';
-            fetch(url, temp, {}).then(function(result){
-                expect(clone).toHaveBeenCalledWith(baseURL, temp, 'fakeSubDir', undefined, undefined);
-                expect(save_metadata).toHaveBeenCalled();
-                done();
-            });
-        }, 6000);
-
-        it('Test 013 : should extract the git ref and subdir from the URL hash, if provided', function(done) {
-            var url = 'https://github.com/bobeast/GAPlugin.git#fakeGitRef:/fake/Sub/Dir/';
-            var baseURL = 'https://github.com/bobeast/GAPlugin.git';
-            fetch(url, temp, {}).then(function(result){
-                expect(clone).toHaveBeenCalledWith(baseURL, temp, 'fake/Sub/Dir', 'fakeGitRef', undefined);
-                expect(save_metadata).toHaveBeenCalled();
-                done();
-            });
-        }, 6000);
-
-        it('Test 014 : should fail when the expected ID doesn\'t match', function(done) {
-            fetch('https://github.com/bobeast/GAPlugin.git', temp, { expected_id: 'wrongID' })
-            .then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(''+err).toContain('Expected plugin to have ID "wrongID" but got');
-            }).fin(done);
-        });
-
-        it('Test 015 : should fail when the expected ID with version specified doesn\'t match', function(done) {
-            fetch('https://github.com/bobeast/GAPlugin.git', temp, { expected_id: 'id@wrongVersion' })
-            .then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(''+err).toContain('Expected plugin to have ID "id" but got');
-            }).fin(done);
-        });
-
-        it('Test 016 : should succeed when the expected ID is correct', function(done) {
-            wrapper(fetch('https://github.com/bobeast/GAPlugin.git', temp, { expected_id: test_plugin_id }), done, function() {
-                expect(1).toBe(1);
-            });
-        });
-    });
-
-    describe('github plugins', function() {
-        // these tests actually pull a plugin from github
-        beforeEach(function(){
-            realrm('-rf',temp);
-        });
-
-        // this commit uses the new id
-        it('Test 017 : should fetch from a commit-sha', function(done) {
-            wrapper(fetch('http://github.com/apache/cordova-plugin-device.git#ad5f1e7bfd05ef98c01df549a0fa98036a5625db', temp, { expected_id: 'cordova-plugin-device' }), done, function() {
-                expect(1).toBe(1);
-                done();
-            });
-        }, TIMEOUT);
-        // this branch uses the old id
-        it('Test 018 : should fetch from a branch', function(done) {
-            wrapper(fetch('http://github.com/apache/cordova-plugin-device.git#cdvtest', temp, { expected_id: 'org.apache.cordova.device' }), done, function() {
-                expect(1).toBe(1);
-                done();
-            });
-        }, TIMEOUT);
-        // this tag uses the new id
-        it('Test 019 : should fetch from a tag', function(done) {
-            wrapper(fetch('http://github.com/apache/cordova-plugin-device.git#r1.0.0', temp, { expected_id: 'cordova-plugin-device' }), done, function() {
-                expect(1).toBe(1);
-                done();
-            });
-        }, TIMEOUT);
-    });
-
-    describe('fetch recursive error CB-8809', function(){
-
-        var srcDir = path.join(__dirname, 'plugins/recursivePlug');
-        var appDir = path.join(__dirname, 'plugins/recursivePlug/demo');
-
-        if(/^win/.test(process.platform)) {
-            it('Test 020 : should copy all but the /demo/ folder',function(done) {
-                var cp = spyOn(shell, 'cp');
-                wrapper(fetch(srcDir, appDir),done, function() {
-                    expect(cp).toHaveBeenCalledWith('-R',path.join(srcDir,'asset.txt'),path.join(appDir,'test-recursive'));
-                    expect(cp).not.toHaveBeenCalledWith('-R',srcDir,path.join(appDir,'test-recursive'));
-                });
-            });
-        }
-        else {
-            it('Test 021 : should skip copy to avoid recursive error', function(done) {
-
-                var cp = spyOn(shell, 'cp').and.callFake(function(){});
-
-                wrapper(fetch(srcDir, appDir),done, function() {
-                    expect(cp).not.toHaveBeenCalled();
-                });
-            });
-        }
-
-    });
-
-    describe('registry plugins', function() {
-        var pluginId = 'dummyplugin', sFetch;
-        var rm, sym, save_metadata;
-        beforeEach(function() {
-            rm = spyOn(shell, 'rm');
-            sym = spyOn(fs, 'symlinkSync');
-            save_metadata = spyOn(metadata, 'save_fetch_metadata');
-            sFetch = spyOn(registry, 'fetch').and.returnValue(Q(test_plugin));
-            realrm('-rf', temp);
-        });
-
-        it('Test 022 : should fail when the expected ID with version specified doesn\'t match', function(done) {
-            //fetch(pluginId, temp, { expected_id: test_plugin_id + '@wrongVersion' })
-            fetch(pluginId, temp, { expected_id: 'wrongID' })
-            .then(function() {
-                expect('this call').toBe('fail');
-            }, function(err) {
-                expect(''+err).toContain('Expected plugin to have ID "wrongID" but got');
-            }).fin(done);
-        });
-        
-        it('Test 023 : should succeed when the expected ID is correct', function(done) {
-            wrapper(fetch(pluginId, temp, { expected_id: test_plugin_id }), done, function() {
-                expect(1).toBe(1);
-            });
-        });
-        it('Test 024 : should succeed when the plugin version specified is correct', function(done) {
-            wrapper(fetch(pluginId, temp, { expected_id: test_plugin_id + '@' + test_plugin_version }), done, function() {
-                expect(1).toBe(1);
-            });
-        });
-        it('Test 025 : should fetch plugins that are scoped packages', function(done) {
-            var scopedPackage = '@testcope/dummy-plugin';
-            wrapper(fetch(scopedPackage, temp, { expected_id: test_plugin_id }), done, function() {
-                expect(sFetch).toHaveBeenCalledWith([scopedPackage]);
-            });
-        });
-        it('Test 026 : should fetch plugins that are scoped packages and have versions specified', function(done) {
-            var scopedPackage = '@testcope/dummy-plugin@latest';
-            wrapper(fetch(scopedPackage, temp, { expected_id: test_plugin_id }), done, function() {
-                expect(sFetch).toHaveBeenCalledWith([scopedPackage]);
-            });
-        });
-    });
-});

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/04c12e2b/spec-plugman/uninstall.spec.js
----------------------------------------------------------------------
diff --git a/spec-plugman/uninstall.spec.js b/spec-plugman/uninstall.spec.js
deleted file mode 100644
index d1b2cbb..0000000
--- a/spec-plugman/uninstall.spec.js
+++ /dev/null
@@ -1,333 +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 uninstall = require('../src/plugman/uninstall'),
-    install = require('../src/plugman/install'),
-    actions = require('cordova-common').ActionStack,
-    PluginInfo = require('cordova-common').PluginInfo,
-    events = require('cordova-common').events,
-    plugman = require('../src/plugman/plugman'),
-    common  = require('./common'),
-    platforms = require('../src/platforms/platforms'),
-    xmlHelpers = require('cordova-common').xmlHelpers,
-    et      = require('elementtree'),
-    fs      = require('fs'),
-    path    = require('path'),
-    shell   = require('shelljs'),
-    Q       = require('q'),
-    spec    = __dirname,
-    done    = false,
-    srcProject = path.join(spec, 'projects', 'android'),
-    project = path.join(spec, 'projects', 'android_uninstall.test'),
-    project2 = path.join(spec, 'projects', 'android_uninstall.test2'),
-    project3 = path.join(spec, 'projects', 'android_uninstall.test3'),
-
-    plugins_dir = path.join(spec, 'plugins'),
-    plugins_install_dir = path.join(project, 'cordova', 'plugins'),
-    plugins_install_dir2 = path.join(project2, 'cordova', 'plugins'),
-    plugins_install_dir3 = path.join(project3, 'cordova', 'plugins'),
-
-    plugins = {
-        'org.test.plugins.dummyplugin' : path.join(plugins_dir, 'org.test.plugins.dummyplugin'),
-        'A' : path.join(plugins_dir, 'dependencies', 'A'),
-        'C' : path.join(plugins_dir, 'dependencies', 'C')
-    },
-    dummy_id = 'org.test.plugins.dummyplugin';
-
-var dummyPluginInfo = new PluginInfo(plugins['org.test.plugins.dummyplugin']);
-
-var TEST_XML = '<?xml version="1.0" encoding="UTF-8"?>\n' +
-    '<widget xmlns     = "http://www.w3.org/ns/widgets"\n' +
-    '        xmlns:cdv = "http://cordova.apache.org/ns/1.0"\n' +
-    '        id        = "io.cordova.hellocordova"\n' +
-    '        version   = "0.0.1">\n' +
-    '    <name>Hello Cordova</name>\n' +
-    '    <description>\n' +
-    '        A sample Apache Cordova application that responds to the deviceready event.\n' +
-    '    </description>\n' +
-    '    <author href="http://cordova.io" email="dev@cordova.apache.org">\n' +
-    '        Apache Cordova Team\n' +
-    '    </author>\n' +
-    '    <content src="index.html" />\n' +
-    '    <access origin="*" />\n' +
-    '</widget>\n';
-
-describe('plugman uninstall start', function() {
-    beforeEach(function () {
-        var origParseElementtreeSync = xmlHelpers.parseElementtreeSync.bind(xmlHelpers);
-        spyOn(xmlHelpers, 'parseElementtreeSync').and.callFake(function(path) {
-            if (/config.xml$/.test(path)) return new et.ElementTree(et.XML(TEST_XML));
-            return origParseElementtreeSync(path);
-        });
-    });
-
-    it('Test 001 : plugman uninstall start', function(done) {
-        shell.rm('-rf', project, project2, project3);
-        shell.cp('-R', path.join(srcProject, '*'), project);
-        shell.cp('-R', path.join(srcProject, '*'), project2);
-        shell.cp('-R', path.join(srcProject, '*'), project3);
-
-        return install('android', project, plugins['org.test.plugins.dummyplugin'])
-        .then(function(result){
-            return install('android', project, plugins['A']);
-        }).then( function(){
-            return install('android', project2, plugins['C']);
-        }).then(function(){
-            return install('android', project2, plugins['A']);
-        }).then(function(){
-            return install('android', project3, plugins['A']);
-        }).then(function(){
-            return install('android', project3, plugins['C']);
-        }).then(function(result){
-            expect(result).toEqual(true);
-            done();
-        }).fail(function(err){
-            expect(err).toBeUndefined();
-        });
-    }, 60000);
-});
-
-describe('uninstallPlatform', function() {
-    var proc, rm;
-    var fsWrite;
-
-    beforeEach(function() {
-        proc = spyOn(actions.prototype, 'process').and.returnValue(Q());
-        fsWrite = spyOn(fs, 'writeFileSync').and.returnValue(true);
-        rm = spyOn(shell, 'rm').and.returnValue(true);
-        spyOn(shell, 'cp').and.returnValue(true);
-        done = false;
-    });
-    describe('success', function() {
-
-        it('Test 002 : should get PlatformApi instance for platform and invoke its\' removePlugin method', function(done) {
-            var platformApi = { removePlugin: jasmine.createSpy('removePlugin').and.returnValue(Q()) };
-            var getPlatformApi = spyOn(platforms, 'getPlatformApi').and.returnValue(platformApi);
-
-            uninstall.uninstallPlatform('android', project, dummy_id)
-            .then(function() {
-                expect(getPlatformApi).toHaveBeenCalledWith('android', project);
-                expect(platformApi.removePlugin).toHaveBeenCalled();
-                done();
-            }).fail(function (err) {
-                expect(err).toBeUndefined();
-                done();
-            });
-        }, 6000);
-
-        it('Test 003 : should return propagate value returned by PlatformApi removePlugin method', function(done) {
-            var platformApi = { removePlugin: jasmine.createSpy('removePlugin') };
-            spyOn(platforms, 'getPlatformApi').and.returnValue(platformApi);
-
-            var existsSyncOrig = fs.existsSync;
-            spyOn(fs, 'existsSync').and.callFake(function (file) {
-                if (file.indexOf(dummy_id) >= 0) return true;
-                return existsSyncOrig.call(fs, file);
-            });
-
-            var fakeProvider = jasmine.createSpyObj('fakeProvider', ['get']);
-            fakeProvider.get.and.returnValue(dummyPluginInfo);
-
-            function validateReturnedResultFor(values, expectedResult) {
-                return values.reduce(function (promise, value) {
-                    return promise
-                    .then(function () {
-                        platformApi.removePlugin.and.returnValue(Q(value));
-                        return uninstall.uninstallPlatform('android', project, dummy_id, null,
-                            { pluginInfoProvider: fakeProvider, platformVersion: '9.9.9' });
-                    })
-                    .then(function(result) {
-                        expect(!!result).toEqual(expectedResult);
-                    }, function(err) {
-                        expect(err).toBeUndefined();
-                    });
-                }, Q());
-            }
-
-            validateReturnedResultFor([ true, {}, [], 'foo', function(){} ], true)
-            .then(function () {
-                return validateReturnedResultFor([ false, null, undefined, '' ], false);
-            })
-            .fin(done);
-        });
-
-        describe('with dependencies', function() {
-            var emit;
-            beforeEach(function() {
-                emit = spyOn(events, 'emit');
-            });
-            uninstall.uninstallPlatform('android', project, 'A')
-            .then(function(result) {
-                expect(emit).toHaveBeenCalledWith('log', 'Uninstalling 2 dependent plugins.');
-                done();
-            });
-        });
-    });
-
-    describe('failure ', function() {
-        it('Test 004 : should throw if platform is unrecognized', function(done) {
-            uninstall.uninstallPlatform('atari', project, 'SomePlugin')
-            .then(function(result){
-                expect(false).toBe(true);
-                done();
-            }).fail(function err (errMsg) {
-                expect(errMsg.toString()).toContain('atari not supported.');
-                done();
-            });
-        }, 6000);
-
-        it('Test 005 : should throw if plugin is missing', function(done) {
-            uninstall.uninstallPlatform('android', project, 'SomePluginThatDoesntExist')
-            .then(function(result){
-                expect(false).toBe(true);
-                done();
-            }).fail(function err (errMsg) {
-                expect(errMsg.toString()).toContain('Plugin "SomePluginThatDoesntExist" not found. Already uninstalled?');
-                done();
-            });
-        }, 6000);
-    });
-});
-
-describe('uninstallPlugin', function() {
-    var rm, fsWrite, rmstack = [], emit;
-
-    beforeEach(function() {
-        fsWrite = spyOn(fs, 'writeFileSync').and.returnValue(true);
-        rm = spyOn(shell, 'rm').and.callFake(function(f,p) { rmstack.push(p); return true; });
-        rmstack = [];
-        emit = spyOn(events, 'emit');
-        done = false;
-    });
-    describe('with dependencies', function() {
-
-        it('Test 006 : should delete all dependent plugins', function(done) {
-            uninstall.uninstallPlugin('A', plugins_install_dir)
-            .then(function(result) {
-                var del = common.spy.getDeleted(emit);
-                expect(del).toEqual([
-                    'Deleted "C"',
-                    'Deleted "D"',
-                    'Deleted "A"'
-                ]);
-                done();
-            });
-        });
-
-        it('Test 007 : should fail if plugin is a required dependency', function(done) {
-            uninstall.uninstallPlugin('C', plugins_install_dir)
-            .then(function(result){
-                expect(false).toBe(true);
-                done();
-            }).fail(function err (errMsg) {
-                expect(errMsg.toString()).toEqual('"C" is required by (A) and cannot be removed (hint: use -f or --force)');
-                done();
-            });
-        }, 6000);
-
-        it('Test 008 : allow forcefully removing a plugin', function(done) {
-            uninstall.uninstallPlugin('C', plugins_install_dir, {force: true}) 
-            .then(function() {
-                var del = common.spy.getDeleted(emit);
-                expect(del).toEqual(['Deleted "C"']);
-                done();
-            });
-        });
-
-        it('Test 009 : never remove top level plugins if they are a dependency', function(done) {
-            uninstall.uninstallPlugin('A', plugins_install_dir2)
-            .then(function() {
-                var del = common.spy.getDeleted(emit);
-                expect(del).toEqual([
-                    'Deleted "D"',
-                    'Deleted "A"'
-                ]);
-                done();
-            });
-        });
-
-        it('Test 010 : should not remove dependent plugin if it was installed after as top-level', function(done) {
-            uninstall.uninstallPlugin('A', plugins_install_dir3)
-            .then(function() {
-                var del = common.spy.getDeleted(emit);
-                expect(del).toEqual([
-                    'Deleted "D"',
-                    'Deleted "A"'
-                ]);
-                done();
-            });
-        });
-    });
-});
-
-describe('uninstall', function() {
-    var fsWrite, rm;
-
-    beforeEach(function() {
-        fsWrite = spyOn(fs, 'writeFileSync').and.returnValue(true);
-        rm = spyOn(shell, 'rm').and.returnValue(true);
-        done = false;
-    });
-    
-    describe('failure', function() {
-        it('Test 011 : should throw if platform is unrecognized', function(done) {
-            return uninstall('atari', project, 'SomePlugin')
-            .then(function(result){
-                expect(false).toBe(true);
-                done();
-            }).fail(function err (errMsg) {
-                expect(errMsg.toString()).toContain('atari not supported.');
-                done();
-            });
-        }, 6000);
-
-        it('Test 012 : should throw if plugin is missing', function(done) {
-            uninstall('android', project, 'SomePluginThatDoesntExist')
-            .then(function(result){
-                expect(false).toBe(true);
-                done();
-            }).fail(function err (errMsg) {
-                expect(errMsg.toString()).toContain('Plugin "SomePluginThatDoesntExist" not found. Already uninstalled?');
-                done();
-            });
-        }, 6000);
-    });
-});
-
-describe('end', function() {
-    it('Test 013 : end', function(done) {
-        return uninstall('android', project, plugins['org.test.plugins.dummyplugin'])
-        .then(function(){
-            // Fails... A depends on
-            return uninstall('android', project, plugins['C']);
-        }).fail(function(err) {
-            expect(err.stack).toMatch(/The plugin 'C' is required by \(A\), skipping uninstallation./);
-        }).then(function(){
-            // dependencies on C,D ... should this only work with --recursive? prompt user..?
-            return uninstall('android', project, plugins['A']);
-        }).fin(function(err){
-            if(err)
-                plugman.emit('error', err);
-            shell.rm('-rf', project, project2, project3);
-            done();
-        });
-    });
-});


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