cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mwbro...@apache.org
Subject [32/37] git commit: Add WP7 and WP8 support to cordova-cli.
Date Wed, 15 May 2013 20:36:11 GMT
Add WP7 and WP8 support to cordova-cli.


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

Branch: refs/heads/master
Commit: ddfa08371e1ecc84d667a682a14dd9ac7ce72ee6
Parents: f59ddbb
Author: Benn Mapes <benn.mapes@gmail.com>
Authored: Tue May 14 15:27:19 2013 -0700
Committer: Michael Brooks <michael@michaelbrooks.ca>
Committed: Wed May 15 10:21:35 2013 -0700

----------------------------------------------------------------------
 bootstrap.js                                       |   13 +-
 package.json                                       |    1 +
 platforms.js                                       |    2 +-
 spec/cordova-cli/compile.spec.js                   |  106 +++----
 spec/cordova-cli/config_parser.spec.js             |    9 +-
 spec/cordova-cli/create.spec.js                    |    9 +-
 spec/cordova-cli/emulate.spec.js                   |  106 ++-----
 spec/cordova-cli/hooker.spec.js                    |   54 +++-
 spec/cordova-cli/platform.spec.js                  |  139 ++-------
 spec/cordova-cli/plugin.spec.js                    |    8 +-
 spec/cordova-cli/plugin_parser.spec.js             |    4 +-
 spec/cordova-cli/prepare.spec.js                   |   44 +--
 spec/cordova-cli/serve.spec.js                     |   16 +-
 spec/cordova-cli/util.spec.js                      |   34 ++
 spec/platform-script/android/android.spec.js       |   98 ++++++
 .../platform-script/android/android_parser.spec.js |   10 +-
 spec/platform-script/blackberry/blackberry.spec.js |  105 ++++++
 .../blackberry/blackberry_parser.spec.js           |   10 +-
 spec/platform-script/ios/ios.spec.js               |   99 ++++++
 spec/platform-script/ios/ios_parser.spec.js        |   13 +-
 spec/platform-script/wp7/wp7.spec.js               |   99 ++++++
 spec/platform-script/wp7/wp7_parser.spec.js        |  249 +++++++++++++++
 spec/platform-script/wp8/wp8.spec.js               |   99 ++++++
 spec/platform-script/wp8/wp8_parser.spec.js        |  249 +++++++++++++++
 src/compile.js                                     |    5 +-
 src/create.js                                      |    2 +-
 src/emulate.js                                     |   10 +-
 src/metadata/wp7_parser.js                         |  160 +++++++++
 src/metadata/wp8_parser.js                         |  158 +++++++++
 src/platform.js                                    |    6 +-
 src/plugin.js                                      |    1 +
 src/plugin_loader.js                               |    9 +
 src/util.js                                        |    6 +
 33 files changed, 1578 insertions(+), 355 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/bootstrap.js
----------------------------------------------------------------------
diff --git a/bootstrap.js b/bootstrap.js
index f96df76..8cf0135 100644
--- a/bootstrap.js
+++ b/bootstrap.js
@@ -25,6 +25,8 @@ var util      = require('./src/util'),
     a_parser  = require('./src/metadata/android_parser'),
     b_parser  = require('./src/metadata/blackberry_parser'),
     i_parser  = require('./src/metadata/ios_parser'),
+    wp7_parser= require('./src/metadata/wp7_parser'),
+    wp8_parser= require('./src/metadata/wp8_parser'),
     n         = require('ncallbacks'),
     path      = require('path'),
     fs        = require('fs'),
@@ -35,7 +37,9 @@ var util      = require('./src/util'),
 var min_reqs = {
     "android":a_parser.check_requirements,
     "ios":i_parser.check_requirements,
-    "blackberry":b_parser.check_requirements
+    "blackberry":b_parser.check_requirements,
+    "wp7":wp7_parser.check_requirements,
+    "wp8":wp7_parser.check_requirements
 }
 
 // Create native projects using bin/create
@@ -68,16 +72,15 @@ var end = n(platforms.length, function() {
 platforms.forEach(function(platform) {
     min_reqs[platform](function(err) {
         if (err) {
-            console.error('WARNING: Your system does not meet requirements to create ' + platform + 'projects. See error output below.');
+            console.error('WARNING: Your system does not meet requirements to create ' + platform + ' projects. See error output below.');
             console.error(err);
             console.error('SKIPPING ' + platform + ' bootstrap.');
         } else {
             console.log('SUCCESS: Minimum requirements for ' + platform + ' met.');
             var fix_path = path.join(tempDir, platform + '_fixture');
-            var create = path.join(util.libDirectory, 'cordova-' + platform, 'bin', 'create'); 
+            var create = path.join(util.libDirectory, 'cordova-' + platform, 'bin', 'create');
             console.log('BOOTSTRAPPING ' + platform + '...');
             var cmd = create + ' "' + fix_path + '" org.apache.cordova.cordovaExample cordovaExample';
-            if (platform == 'blackberry') cmd = create + ' "' + fix_path + '" cordovaExample';
             shell.exec(cmd, {silent:true, async:true}, function(code, output) {
                 if (code > 0) {
                     console.error('ERROR! Could not create a native ' + platform + ' project test fixture. See below for error output.');
@@ -109,4 +112,4 @@ platforms.forEach(function(platform) {
             });
         }
     });
-});
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 96e53bd..b706c93 100644
--- a/package.json
+++ b/package.json
@@ -48,6 +48,7 @@
     {"name": "Braden Shepherdson", "email":"braden@chromium.org"},
     {"name": "Gord Tanner", "email":"gtanner@gmail.com"},
     {"name": "Tim Kim", "email": "timk@adobe.com"},
+    {"name": "Benn Mapes", "email": "Benn.Mapes@gmail.com"},
     {"name": "Michael Wolf", "email": "Michael.Wolf@Cynergy.com"}
   ],
   "license": "Apache version 2.0"

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/platforms.js
----------------------------------------------------------------------
diff --git a/platforms.js b/platforms.js
index be295a8..542f734 100644
--- a/platforms.js
+++ b/platforms.js
@@ -17,4 +17,4 @@
     under the License.
 */
 
-module.exports = ['ios', 'android', 'blackberry'];
+module.exports = ['ios', 'android', 'blackberry', 'wp7', 'wp8'];

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/cordova-cli/compile.spec.js
----------------------------------------------------------------------
diff --git a/spec/cordova-cli/compile.spec.js b/spec/cordova-cli/compile.spec.js
index f13792a..814d2ab 100644
--- a/spec/cordova-cli/compile.spec.js
+++ b/spec/cordova-cli/compile.spec.js
@@ -16,22 +16,19 @@
     specific language governing permissions and limitations
     under the License.
 */
-var cordova = require('../cordova'),
-    et = require('elementtree'),
+var cordova = require('../../cordova'),
     shell = require('shelljs'),
     path = require('path'),
     fs = require('fs'),
-    config_parser = require('../src/config_parser'),
-    android_parser = require('../src/metadata/android_parser'),
-    ios_parser = require('../src/metadata/ios_parser'),
-    blackberry_parser = require('../src/metadata/blackberry_parser'),
-    hooker = require('../src/hooker'),
-    fixtures = path.join(__dirname, 'fixtures'),
+    events = require('../../src/events'),
+    hooker = require('../../src/hooker'),
+    fixtures = path.join(__dirname, '..', 'fixtures'),
     hooks = path.join(fixtures, 'hooks'),
-    tempDir = path.join(__dirname, '..', 'temp'),
+    tempDir = path.join(__dirname, '..', '..', 'temp'),
     cordova_project = path.join(fixtures, 'projects', 'cordova');
 
 var cwd = process.cwd();
+
 describe('compile command', function() {
     beforeEach(function() {
         shell.rm('-rf', tempDir);
@@ -53,12 +50,12 @@ describe('compile command', function() {
     it('should run inside a Cordova-based project with at least one added platform', function() {
         // move platform project fixtures over to fake cordova into thinking platforms were added
         // TODO: possibly add this to helper?
-        shell.mv('-f', path.join(cordova_project, 'platforms', 'blackberry'), path.join(tempDir));
-        shell.mv('-f', path.join(cordova_project, 'platforms', 'ios'), path.join(tempDir));
+        // Just make a folder instead of moving the whole platform? 
+        shell.mkdir('-p', tempDir);
+        shell.mv('-f', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir));
         this.after(function() {
             process.chdir(cwd);
-            shell.mv('-f', path.join(tempDir, 'blackberry'), path.join(cordova_project, 'platforms', 'blackberry'));
-            shell.mv('-f', path.join(tempDir, 'ios'), path.join(cordova_project, 'platforms', 'ios'));
+            shell.mv('-f', path.join(tempDir, 'android'), path.join(cordova_project, 'platforms', 'android'));
         });
 
         process.chdir(cordova_project);
@@ -78,10 +75,29 @@ describe('compile command', function() {
         shell.mkdir('-p', tempDir);
         process.chdir(tempDir);
 
+        // we don't actually want it building the project (if it does somehow exist)
+        var sh_spy = spyOn(shell, 'exec');
+
         expect(function() {
             cordova.compile();
         }).toThrow();
     });
+    /* Is this a repeat of the util.spec.js test? */
+    it('should not treat a .gitignore file as a platform', function() {
+        var gitignore = path.join(cordova_project, 'platforms', '.gitignore');
+        fs.writeFileSync(gitignore, 'somethinghere', 'utf-8');
+        this.after(function() {
+            shell.rm('-f', gitignore);
+            process.chdir(cwd);
+        });
+
+        var s = spyOn(shell, 'exec');
+        process.chdir(cordova_project);
+        cordova.compile();
+        for (call in s.calls) {
+            expect(s.calls[call].args[0]).not.toMatch(/\.gitignore/);
+        }
+    });
 
     describe('hooks', function() {
         var s;
@@ -91,13 +107,11 @@ describe('compile command', function() {
 
         describe('when platforms are added', function() {
             beforeEach(function() {
-                shell.mv('-f', path.join(cordova_project, 'platforms', 'blackberry'), path.join(tempDir));
-                shell.mv('-f', path.join(cordova_project, 'platforms', 'ios'), path.join(tempDir));
+                shell.mv('-f', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir));
                 process.chdir(cordova_project);
             });
             afterEach(function() {
-                shell.mv('-f', path.join(tempDir, 'blackberry'), path.join(cordova_project, 'platforms', 'blackberry'));
-                shell.mv('-f', path.join(tempDir, 'ios'), path.join(cordova_project, 'platforms', 'ios'));
+                shell.mv('-f', path.join(tempDir, 'android'), path.join(cordova_project, 'platforms', 'android'));
                 process.chdir(cwd);
             });
 
@@ -106,11 +120,14 @@ describe('compile command', function() {
                 cordova.compile();
                 expect(s).toHaveBeenCalledWith('before_compile');
             });
-            it('should fire after hooks through the hooker module', function() {
-                var sh_spy = spyOn(shell, 'exec');
-                cordova.compile();
-                sh_spy.mostRecentCall.args[2](0); // shell cb
-                expect(s).toHaveBeenCalledWith('after_compile');
+            it('should fire after hooks through the hooker module', function(done) {
+                spyOn(shell, 'exec').andCallFake(function(cmd, options, callback) {
+                    callback(0, 'fucking eh');
+                });
+                cordova.compile('android', function() {
+                     expect(hooker.prototype.fire).toHaveBeenCalledWith('after_compile');
+                     done();
+                });
             });
         });
 
@@ -131,49 +148,4 @@ describe('compile command', function() {
             });
         });
     });
-    describe('per platform', function() {
-        beforeEach(function() {
-            process.chdir(cordova_project);
-        });
-
-        afterEach(function() {
-            process.chdir(cwd);
-        });
-       
-        describe('Android', function() {
-            it('should shell out to build command on Android', function() {
-                var s = spyOn(require('shelljs'), 'exec').andReturn({code:0});
-                cordova.compile('android');
-                expect(s.mostRecentCall.args[0].match(/\/cordova\/build/)).not.toBeNull();
-            });
-        });
-        describe('iOS', function() {
-            it('should shell out to build command on iOS', function() {
-                var s = spyOn(require('shelljs'), 'exec');
-                cordova.compile('ios');
-                expect(s).toHaveBeenCalled();
-                expect(s.mostRecentCall.args[0].match(/\/cordova\/build/)).not.toBeNull();
-            });
-        });
-        describe('BlackBerry', function() {
-            it('should shell out to ant command on blackberry', function() {
-                var s = spyOn(shell, 'exec');
-                cordova.compile('blackberry');
-                expect(s).toHaveBeenCalled();
-                expect(s.mostRecentCall.args[0]).toMatch(/ant -f .*build\.xml" qnx load-device/);
-            });
-        });
-        it('should not treat a .gitignore file as a platform', function() {
-            var gitignore = path.join(cordova_project, 'platforms', '.gitignore');
-            fs.writeFileSync(gitignore, 'somethinghere', 'utf-8');
-            this.after(function() {
-                shell.rm('-f', gitignore);
-            });
-            var s = spyOn(shell, 'exec');
-            cordova.compile();
-            expect(s.calls[0].args[0]).not.toMatch(/\.gitignore/);
-            expect(s.calls[1].args[0]).not.toMatch(/\.gitignore/);
-            expect(s.calls[1].args[0]).not.toMatch(/\.gitignore/);
-        });
-    });
 });

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/cordova-cli/config_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/cordova-cli/config_parser.spec.js b/spec/cordova-cli/config_parser.spec.js
index 99bc717..77658fb 100644
--- a/spec/cordova-cli/config_parser.spec.js
+++ b/spec/cordova-cli/config_parser.spec.js
@@ -17,14 +17,15 @@
     specific language governing permissions and limitations
     under the License.
 */
-var cordova = require('../cordova'),
+var cordova = require('../../cordova'),
     path = require('path'),
     fs = require('fs'),
     shell = require('shelljs'),
-    config_parser = require('../src/config_parser'),
-    tempDir = path.join(__dirname, '..', 'temp'),
+    config_parser = require('../../src/config_parser'),
+    tempDir = path.join(__dirname, '..', '..', 'temp'),
     et = require('elementtree'),
-    xml = path.join(tempDir, 'www', 'config.xml');
+    util = require('../../src/util'),
+    xml = util.projectConfig(tempDir);
 
 
 describe('config.xml parser', function () {

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/cordova-cli/create.spec.js
----------------------------------------------------------------------
diff --git a/spec/cordova-cli/create.spec.js b/spec/cordova-cli/create.spec.js
index fcb3e76..8a31ed6 100644
--- a/spec/cordova-cli/create.spec.js
+++ b/spec/cordova-cli/create.spec.js
@@ -1,8 +1,9 @@
-var cordova = require('../cordova'),
+var cordova = require('../../cordova'),
     path    = require('path'),
     shell   = require('shelljs'),
     fs      = require('fs'),
-    tempDir = path.join(__dirname, '..', 'temp');
+    util    = require('../../src/util'),
+    tempDir = path.join(__dirname, '..', '..', 'temp');
 
 describe('create command', function () {
     beforeEach(function() {
@@ -54,14 +55,14 @@ describe('create command', function () {
 
         expect(fs.lstatSync(path.join(tempDir, '.cordova', 'config.json')).isFile()).toBe(true);
 
-        expect(fs.readFileSync(path.join(tempDir, 'www', 'config.xml')).toString('utf8')).toMatch(/<name>balls<\/name>/);
+        expect(fs.readFileSync(util.projectConfig(tempDir)).toString('utf8')).toMatch(/<name>balls<\/name>/);
     });
     it('should create a cordova project in the specified dir with specified name and id if provided', function() {
         cordova.create(tempDir, "birdy.nam.nam", "numnum");
 
         expect(fs.lstatSync(path.join(tempDir, '.cordova', 'config.json')).isFile()).toBe(true);
 
-        var config = fs.readFileSync(path.join(tempDir, 'www', 'config.xml')).toString('utf8');
+        var config = fs.readFileSync(util.projectConfig(tempDir)).toString('utf8');
         expect(config).toMatch(/<name>numnum<\/name>/);
         expect(config).toMatch(/id="birdy\.nam\.nam"/);
     });

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/cordova-cli/emulate.spec.js
----------------------------------------------------------------------
diff --git a/spec/cordova-cli/emulate.spec.js b/spec/cordova-cli/emulate.spec.js
index 3a4d1a4..a3e5136 100644
--- a/spec/cordova-cli/emulate.spec.js
+++ b/spec/cordova-cli/emulate.spec.js
@@ -16,19 +16,17 @@
     specific language governing permissions and limitations
     under the License.
 */
-var cordova = require('../cordova'),
+var cordova = require('../../cordova'),
     et = require('elementtree'),
     shell = require('shelljs'),
     path = require('path'),
     fs = require('fs'),
-    config_parser = require('../src/config_parser'),
-    android_parser = require('../src/metadata/android_parser'),
-    ios_parser = require('../src/metadata/ios_parser'),
-    blackberry_parser = require('../src/metadata/blackberry_parser'),
-    hooker = require('../src/hooker'),
-    fixtures = path.join(__dirname, 'fixtures'),
+    config_parser = require('../../src/config_parser'),
+    android_parser = require('../../src/metadata/android_parser'),
+    hooker = require('../../src/hooker'),
+    fixtures = path.join(__dirname, '..', 'fixtures'),
     hooks = path.join(fixtures, 'hooks'),
-    tempDir = path.join(__dirname, '..', 'temp'),
+    tempDir = path.join(__dirname, '..', '..', 'temp'),
     cordova_project = path.join(fixtures, 'projects', 'cordova');
 
 var cwd = process.cwd();
@@ -36,7 +34,7 @@ var cwd = process.cwd();
 describe('emulate command', function() {
     beforeEach(function() {
         shell.rm('-rf', tempDir);
-        shell.mkdir('-p', tempDir);
+        cordova.create(tempDir);
     });
 
     it('should not run inside a Cordova-based project with no added platforms', function() {
@@ -44,7 +42,6 @@ describe('emulate command', function() {
             process.chdir(cwd);
         });
 
-        cordova.create(tempDir);
         process.chdir(tempDir);
         expect(function() {
             cordova.emulate();
@@ -52,19 +49,15 @@ describe('emulate command', function() {
     });
     
     it('should run inside a Cordova-based project with at least one added platform', function() {
-        shell.mv('-f', path.join(cordova_project, 'platforms', 'blackberry'), path.join(tempDir));
-        shell.mv('-f', path.join(cordova_project, 'platforms', 'ios'), path.join(tempDir));
         this.after(function() {
             process.chdir(cwd);
-            shell.mv('-f', path.join(tempDir, 'blackberry'), path.join(cordova_project, 'platforms', 'blackberry'));
-            shell.mv('-f', path.join(tempDir, 'ios'), path.join(cordova_project, 'platforms', 'ios'));
         });
 
-        process.chdir(cordova_project);
-
         var s = spyOn(shell, 'exec');
         var a_spy = spyOn(android_parser.prototype, 'update_project');
         expect(function() {
+            shell.cp('-Rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms'));
+            process.chdir(tempDir);
             cordova.emulate();
             a_spy.mostRecentCall.args[1](); // fake out android parser
             expect(s).toHaveBeenCalled();
@@ -82,97 +75,40 @@ describe('emulate command', function() {
             cordova.emulate();
         }).toThrow();
     });
-    describe('per platform', function() {
-        beforeEach(function() {
-            process.chdir(cordova_project);
-        });
-
-        afterEach(function() {
-            process.chdir(cwd);
-        });
-       
-        describe('Android', function() {
-            var s;
-            beforeEach(function() {
-                s = spyOn(require('shelljs'), 'exec');
-            });
-            it('should shell out to run command on Android', function() {
-                cordova.emulate('android');
-                expect(s.mostRecentCall.args[0].match(/\/cordova\/run/)).not.toBeNull();
-            });
-            it('should call android_parser\'s update_project', function() {
-                var spy = spyOn(android_parser.prototype, 'update_project');
-                cordova.emulate('android');
-                expect(spy).toHaveBeenCalled();
-            });
-        });
-        describe('iOS', function() {
-            it('should shell out to emulate command on iOS', function() {
-                var s = spyOn(require('shelljs'), 'exec');
-                var proj_spy = spyOn(ios_parser.prototype, 'update_project');
-                cordova.emulate('ios');
-                proj_spy.mostRecentCall.args[1]();
-                expect(s).toHaveBeenCalled();
-                expect(s.mostRecentCall.args[0].match(/\/cordova\/emulate/)).not.toBeNull();
-            });
-            it('should call ios_parser\'s update_project', function() {
-                var s = spyOn(ios_parser.prototype, 'update_project');
-                cordova.emulate('ios');
-                expect(s).toHaveBeenCalled();
-            });
-        });
-        describe('BlackBerry', function() {
-            it('should shell out to ant command on blackberry', function() {
-                var proj_spy = spyOn(blackberry_parser.prototype, 'update_project');
-                var s = spyOn(require('shelljs'), 'exec');
-                cordova.emulate('blackberry');
-                proj_spy.mostRecentCall.args[1](); // update_project fake
-                expect(s).toHaveBeenCalled();
-                expect(s.mostRecentCall.args[0]).toMatch(/ant -f .*build\.xml" qnx load-simulator/);
-            });
-            it('should call blackberry_parser\'s update_project', function() {
-                var s = spyOn(blackberry_parser.prototype, 'update_project');
-                cordova.emulate('blackberry');
-                expect(s).toHaveBeenCalled();
-            });
-        });
-    });
 
     describe('hooks', function() {
-        var s, sh, ap;
+        var s;
         beforeEach(function() {
             s = spyOn(hooker.prototype, 'fire').andReturn(true);
         });
 
         describe('when platforms are added', function() {
             beforeEach(function() {
-                shell.mv('-f', path.join(cordova_project, 'platforms', 'blackberry'), path.join(tempDir));
-                shell.mv('-f', path.join(cordova_project, 'platforms', 'ios'), path.join(tempDir));
-                sh = spyOn(shell, 'exec');
-                ap = spyOn(android_parser.prototype, 'update_project');
-                process.chdir(cordova_project);
+                shell.cp('-Rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms'));
+                process.chdir(tempDir);
             });
             afterEach(function() {
-                shell.mv('-f', path.join(tempDir, 'blackberry'), path.join(cordova_project, 'platforms', 'blackberry'));
-                shell.mv('-f', path.join(tempDir, 'ios'), path.join(cordova_project, 'platforms', 'ios'));
                 process.chdir(cwd);
             });
 
             it('should fire before hooks through the hooker module', function() {
+
+                spyOn(shell, 'exec');
                 cordova.emulate();
-                expect(s).toHaveBeenCalledWith('before_emulate');
+                expect(hooker.prototype.fire).toHaveBeenCalledWith('before_emulate');
             });
             it('should fire after hooks through the hooker module', function() {
-                cordova.emulate();
-                ap.mostRecentCall.args[1](); // fake parser call
-                sh.mostRecentCall.args[2](0); //fake shell call
-                expect(s).toHaveBeenCalledWith('after_emulate');
+                spyOn(shell, 'exec').andCallFake(function(cmd, options, callback) {
+                    callback(0, 'fucking eh');
+                });
+                cordova.emulate('android', function() {
+                     expect(hooker.prototype.fire).toHaveBeenCalledWith('after_emulate');
+                });
             });
         });
 
         describe('with no platforms added', function() {
             beforeEach(function() {
-                cordova.create(tempDir);
                 process.chdir(tempDir);
             });
             afterEach(function() {

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/cordova-cli/hooker.spec.js
----------------------------------------------------------------------
diff --git a/spec/cordova-cli/hooker.spec.js b/spec/cordova-cli/hooker.spec.js
index 4a0ca7d..ff92f43 100644
--- a/spec/cordova-cli/hooker.spec.js
+++ b/spec/cordova-cli/hooker.spec.js
@@ -1,4 +1,4 @@
-/**
+ /**
     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
@@ -16,14 +16,16 @@
     specific language governing permissions and limitations
     under the License.
 */
-var hooker = require('../src/hooker'),
+var hooker = require('../../src/hooker'),
     shell  = require('shelljs'),
     path   = require('path'),
     fs     = require('fs'),
-    tempDir= path.join(__dirname, '..', 'temp'),
-    hooks  = path.join(__dirname, 'fixtures', 'hooks'),
-    cordova= require('../cordova');
+    os     = require('os'),
+    tempDir= path.join(__dirname, '..', '..', 'temp'),
+    hooks  = path.join(__dirname, '..', 'fixtures', 'hooks'),
+    cordova= require('../../cordova');
 
+var platform = os.platform();
 var cwd = process.cwd();
 
 describe('hooker', function() {
@@ -67,8 +69,14 @@ describe('hooker', function() {
                 }).not.toThrow();
             });
             it('should throw if any script exits with non-zero code', function() {
-                var script = path.join(tempDir, '.cordova', 'hooks', 'before_build', 'fail.sh');
-                shell.cp(path.join(hooks, 'fail', 'fail.sh'), script);
+                var script;
+                if (platform.match(/(win32|win64)/)) {
+                    script = path.join(tempDir, '.cordova', 'hooks', 'before_build', 'fail.bat');
+                    shell.cp(path.join(hooks, 'fail', 'fail.bat'), script);
+                } else {
+                    script = path.join(tempDir, '.cordova', 'hooks', 'before_build', 'fail.sh');
+                    shell.cp(path.join(hooks, 'fail', 'fail.sh'), script);
+                }
                 fs.chmodSync(script, '754');
                 expect(function() {
                     h.fire('before_build');
@@ -79,7 +87,13 @@ describe('hooker', function() {
         describe('success', function() {
             it('should execute all scripts in order and return true', function() {
                 var hook = path.join(tempDir, '.cordova', 'hooks', 'before_build');
-                shell.cp(path.join(hooks, 'test', '*'), path.join(hook, '.'));
+                if (platform.match(/(win32|win64)/)) {
+                    shell.cp(path.join(hooks, 'test', '0.bat'), hook);
+                    shell.cp(path.join(hooks, 'test', '1.bat'), hook);
+                } else {
+                    shell.cp(path.join(hooks, 'test', '0.sh'), hook);
+                    shell.cp(path.join(hooks, 'test', '1.sh'), hook);
+                }
                 fs.readdirSync(hook).forEach(function(script) {
                     fs.chmodSync(path.join(hook, script), '754');
                 });
@@ -89,12 +103,21 @@ describe('hooker', function() {
                     returnValue = h.fire('before_build');
                 }).not.toThrow();
                 expect(returnValue).toBe(true);
-                expect(s.calls[0].args[0]).toMatch(/0.sh/);
-                expect(s.calls[1].args[0]).toMatch(/1.sh/);
+                if (platform.match(/(win32|win64)/)) {
+                    expect(s.calls[0].args[0]).toMatch(/0.bat/);
+                    expect(s.calls[1].args[0]).toMatch(/1.bat/);
+                } else {
+                    expect(s.calls[0].args[0]).toMatch(/0.sh/);
+                    expect(s.calls[1].args[0]).toMatch(/1.sh/);
+                }
             });
             it('should pass the project root folder as parameter into the project-level hooks', function() {
                 var hook = path.join(tempDir, '.cordova', 'hooks', 'before_build');
-                shell.cp(path.join(hooks, 'test', '0.sh'), path.join(hook, '.'));
+                if (platform.match(/(win32|win64)/)) {
+                    shell.cp(path.join(hooks, 'test', '0.bat'), hook);
+                } else {
+                    shell.cp(path.join(hooks, 'test', '0.sh'), hook);
+                }
                 fs.readdirSync(hook).forEach(function(script) {
                     fs.chmodSync(path.join(hook, script), '754');
                 });
@@ -104,8 +127,13 @@ describe('hooker', function() {
                     returnValue = h.fire('before_build');
                 }).not.toThrow();
                 expect(returnValue).toBe(true);
-                var paramRegex = new RegExp('0.sh "'+tempDir+'"$');
-                expect(s.calls[0].args[0]).toMatch(paramRegex);
+                var param_str;
+                if (platform.match(/(win32|win64)/)) {
+                    param_str = '0.bat "'+tempDir+'"';
+                } else { 
+                    param_str = '0.sh "'+tempDir+'"'; 
+                }
+                expect(s.calls[0].args[0].indexOf(param_str)).not.toEqual(-1);
             });
             describe('module-level hooks', function() {
                 var handler = jasmine.createSpy();

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/cordova-cli/platform.spec.js
----------------------------------------------------------------------
diff --git a/spec/cordova-cli/platform.spec.js b/spec/cordova-cli/platform.spec.js
index 7138c7e..bbf3959 100644
--- a/spec/cordova-cli/platform.spec.js
+++ b/spec/cordova-cli/platform.spec.js
@@ -16,22 +16,21 @@
     specific language governing permissions and limitations
     under the License.
 */
-var cordova = require('../cordova'),
+var cordova = require('../../cordova'),
     path = require('path'),
     shell = require('shelljs'),
     request = require('request'),
     fs = require('fs'),
     et = require('elementtree'),
-    config_parser = require('../src/config_parser'),
+    config_parser = require('../../src/config_parser'),
     helper = require('./helper'),
-    util = require('../src/util'),
-    hooker = require('../src/hooker'),
-    platforms = require('../platforms'),
-    tempDir = path.join(__dirname, '..', 'temp');
-    android_parser = require('../src/metadata/android_parser'),
-    ios_parser = require('../src/metadata/ios_parser'),
-    cordova_project = path.join(__dirname, 'fixtures', 'projects', 'cordova'),
-    blackberry_parser = require('../src/metadata/blackberry_parser');
+    util = require('../../src/util'),
+    hooker = require('../../src/hooker'),
+    platforms = require('../../platforms'),
+    tempDir = path.join(__dirname, '..', '..', 'temp');
+    android_parser = require('../../src/metadata/android_parser'),
+    blackberry_parser = require('../../src/metadata/blackberry_parser'),
+    cordova_project = path.join(__dirname, '..', 'fixtures', 'projects', 'cordova');
 
 var cwd = process.cwd();
 
@@ -84,7 +83,11 @@ describe('platform command', function() {
         });
 
         it('should list out added platforms in a project', function() {
-            expect(cordova.platform('list').length).toEqual(3);
+            process.chdir(tempDir);
+            cordova.create(tempDir);
+            shell.cp('-Rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms'));
+            shell.cp('-Rf', path.join(cordova_project, 'platforms', 'blackberry'), path.join(tempDir, 'platforms'));
+            expect(cordova.platform('list').length).toEqual(2);
         });
     });
 
@@ -97,109 +100,23 @@ describe('platform command', function() {
         afterEach(function() {
             process.chdir(cwd);
         });
-
-        describe('android', function() {
-            var sh, cr;
-            var fake_reqs_check = function() {
-                cr.mostRecentCall.args[0](false);
-            };
-            var fake_create = function(a_path) {
-                shell.mkdir('-p', a_path);
-                fs.writeFileSync(path.join(a_path, 'AndroidManifest.xml'), 'hi', 'utf-8');
-                sh.mostRecentCall.args[2](0, '');
-            };
-            beforeEach(function() {
-                sh = spyOn(shell, 'exec');
-                cr = spyOn(android_parser, 'check_requirements');
-            });
-
-            it('should shell out to android ./bin/create', function() {
-                cordova.platform('add', 'android');
-                fake_reqs_check();
-                var shell_cmd = sh.mostRecentCall.args[0];
-                expect(shell_cmd).toMatch(/android\/bin\/create/);
-            });
-            it('should call android_parser\'s update_project', function() {
-                var s = spyOn(android_parser.prototype, 'update_project');
-                cordova.platform('add', 'android');
-                fake_reqs_check();
-                fake_create(path.join(tempDir, 'platforms', 'android'));
-                expect(s).toHaveBeenCalled();
-            });
-        });
-        describe('ios', function() {
-            var sh, cr;
-            var fake_reqs_check = function() {
-                cr.mostRecentCall.args[0](false);
-            };
-            var fake_create = function(a_path) {
-                shell.mkdir('-p', a_path);
-                fs.writeFileSync(path.join(a_path, 'poo.xcodeproj'), 'hi', 'utf-8');
-                shell.mkdir('-p', path.join(a_path, 'poo'));
-                shell.cp(path.join(cordova_project, 'www', 'config.xml'), path.join(a_path, 'poo', 'config.xml'));
-                sh.mostRecentCall.args[2](0, '');
-            };
-            beforeEach(function() {
-                sh = spyOn(shell, 'exec');
-                cr = spyOn(ios_parser, 'check_requirements');
-            });
-            it('should shell out to ios ./bin/create', function() {
-                cordova.platform('add', 'ios');
-                fake_reqs_check();
-                var shell_cmd = sh.mostRecentCall.args[0];
-                expect(shell_cmd).toMatch(/ios\/bin\/create/);
-            });
-            it('should call ios_parser\'s update_project', function() {
-                var s = spyOn(ios_parser.prototype, 'update_project');
-                cordova.platform('add', 'ios');
-                fake_reqs_check();
-                fake_create(path.join(tempDir, 'platforms', 'ios'));
-                expect(s).toHaveBeenCalled();
-            });
-        });
-        describe('blackberry', function() {
-            var sh, cr;
-            var fake_reqs_check = function() {
-                cr.mostRecentCall.args[0](false);
-            };
-            var fake_create = function(a_path) {
-                shell.mkdir('-p', path.join(a_path, 'www'));
-                fs.writeFileSync(path.join(a_path, 'project.properties'), 'hi', 'utf-8');
-                fs.writeFileSync(path.join(a_path, 'build.xml'), 'hi', 'utf-8');
-                shell.cp(path.join(cordova_project, 'www', 'config.xml'), path.join(a_path, 'www', 'config.xml'));
-                sh.mostRecentCall.args[2](0, '');
-            };
-            beforeEach(function() {
-                sh = spyOn(shell, 'exec');
-                cr = spyOn(blackberry_parser, 'check_requirements');
-            });
-            it('should shell out to blackberry bin/create', function() {
-                cordova.platform('add', 'blackberry');
-                fake_reqs_check();
-                var shell_cmd = sh.mostRecentCall.args[0];
-                expect(shell_cmd).toMatch(/blackberry\/bin\/create/);
-            });
-            it('should call blackberry_parser\'s update_project', function() {
-                var s = spyOn(blackberry_parser.prototype, 'update_project');
-                cordova.platform('add', 'blackberry');
-                fake_reqs_check();
-                fake_create(path.join(tempDir, 'platforms', 'blackberry'));
-                expect(s).toHaveBeenCalled();
-            });
-        });
+        
         it('should handle multiple platforms', function() {
             var arc = spyOn(android_parser, 'check_requirements');
-            var irc = spyOn(ios_parser, 'check_requirements');
+            var brc = spyOn(blackberry_parser, 'check_requirements');
             var sh = spyOn(shell, 'exec');
-            cordova.platform('add', ['android', 'ios']);
+            cordova.platform('add', ['android', 'blackberry']);
             arc.mostRecentCall.args[0](false);
-            irc.mostRecentCall.args[0](false);
-            expect(sh.argsForCall[0][0]).toMatch(/android\/bin\/create/);
-            expect(sh.argsForCall[1][0]).toMatch(/ios\/bin\/create/);
+            brc.mostRecentCall.args[0](false);
+            var android_create = path.join('android', 'bin', 'create');
+            var bb_create      = path.join('blackberry', 'bin', 'create');
+            expect(sh.argsForCall[0][0]).toContain(android_create);
+            expect(sh.argsForCall[1][0]).toContain(bb_create);
         });
     });
 
-    describe('`remove`',function() { 
+    describe('`remove`',function() {
+        var num_platforms = fs.readdirSync(path.join(cordova_project, 'platforms')).length; 
         beforeEach(function() {
             process.chdir(cordova_project);
             shell.cp('-rf', path.join(cordova_project, 'platforms' ,'*'), tempDir);
@@ -212,11 +129,11 @@ describe('platform command', function() {
 
         it('should remove a supported and added platform', function() {
             cordova.platform('remove', 'android');
-            expect(cordova.platform('ls').length).toEqual(2);
+            expect(cordova.platform('ls').length).toEqual(num_platforms - 1);
         });
         it('should be able to remove multiple platforms', function() {
-            cordova.platform('remove', ['android','ios']);
-            expect(cordova.platform('ls').length).toEqual(1);
+            cordova.platform('remove', ['android','blackberry']);
+            expect(cordova.platform('ls').length).toEqual(num_platforms - 2);
         });
     });
 
@@ -280,7 +197,7 @@ describe('platform command', function() {
 });
 
 describe('platform.supports(name, callback)', function() {
-    var androidParser = require('../src/metadata/android_parser');
+    var androidParser = require('../../src/metadata/android_parser');
 
     beforeEach(function() {
         spyOn(androidParser, 'check_requirements');

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/cordova-cli/plugin.spec.js
----------------------------------------------------------------------
diff --git a/spec/cordova-cli/plugin.spec.js b/spec/cordova-cli/plugin.spec.js
index 3d370e7..061738f 100644
--- a/spec/cordova-cli/plugin.spec.js
+++ b/spec/cordova-cli/plugin.spec.js
@@ -16,13 +16,13 @@
     specific language governing permissions and limitations
     under the License.
 */
-var cordova = require('../cordova'),
+var cordova = require('../../cordova'),
     path = require('path'),
     shell = require('shelljs'),
     fs = require('fs'),
-    hooker = require('../src/hooker'),
-    tempDir = path.join(__dirname, '..', 'temp'),
-    fixturesDir = path.join(__dirname, 'fixtures'),
+    hooker = require('../../src/hooker'),
+    tempDir = path.join(__dirname, '..', '..', 'temp'),
+    fixturesDir = path.join(__dirname, '..', 'fixtures'),
     testPlugin = path.join(fixturesDir, 'plugins', 'test'),
     cordova_project = path.join(fixturesDir, 'projects', 'cordova'),
     androidPlugin = path.join(fixturesDir, 'plugins', 'android');

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/cordova-cli/plugin_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/cordova-cli/plugin_parser.spec.js b/spec/cordova-cli/plugin_parser.spec.js
index 4391003..15b5993 100644
--- a/spec/cordova-cli/plugin_parser.spec.js
+++ b/spec/cordova-cli/plugin_parser.spec.js
@@ -17,10 +17,10 @@
     specific language governing permissions and limitations
     under the License.
 */
-var cordova = require('../cordova'),
+var cordova = require('../../cordova'),
     path = require('path'),
     fs = require('fs'),
-    plugin_parser = require('../src/plugin_parser'),
+    plugin_parser = require('../../src/plugin_parser'),
     et = require('elementtree'),
     xml = path.join(__dirname, '..', 'fixtures', 'plugins', 'test', 'plugin.xml');
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/cordova-cli/prepare.spec.js
----------------------------------------------------------------------
diff --git a/spec/cordova-cli/prepare.spec.js b/spec/cordova-cli/prepare.spec.js
index f232b3e..da77935 100644
--- a/spec/cordova-cli/prepare.spec.js
+++ b/spec/cordova-cli/prepare.spec.js
@@ -16,19 +16,16 @@
     specific language governing permissions and limitations
     under the License.
 */
-var cordova = require('../cordova'),
+var cordova = require('../../cordova'),
     et = require('elementtree'),
     shell = require('shelljs'),
     path = require('path'),
     fs = require('fs'),
-    config_parser = require('../src/config_parser'),
-    android_parser = require('../src/metadata/android_parser'),
-    ios_parser = require('../src/metadata/ios_parser'),
-    blackberry_parser = require('../src/metadata/blackberry_parser'),
-    hooker = require('../src/hooker'),
-    fixtures = path.join(__dirname, 'fixtures'),
+    config_parser = require('../../src/config_parser'),
+    hooker = require('../../src/hooker'),
+    fixtures = path.join(__dirname, '..', 'fixtures'),
     hooks = path.join(fixtures, 'hooks'),
-    tempDir = path.join(__dirname, '..', 'temp'),
+    tempDir = path.join(__dirname, '..', '..', 'temp'),
     cordova_project = path.join(fixtures, 'projects', 'cordova');
 
 var cwd = process.cwd();
@@ -36,7 +33,7 @@ var cwd = process.cwd();
 describe('prepare command', function() {
     beforeEach(function() {
         shell.rm('-rf', tempDir);
-        shell.mkdir('-p', tempDir);
+        cordova.create(tempDir);
     });
 
     it('should not run inside a Cordova-based project with no added platforms', function() {
@@ -44,7 +41,6 @@ describe('prepare command', function() {
             process.chdir(cwd);
         });
 
-        cordova.create(tempDir);
         process.chdir(tempDir);
         expect(function() {
             cordova.prepare();
@@ -54,20 +50,17 @@ describe('prepare command', function() {
     it('should run inside a Cordova-based project with at least one added platform', function() {
         // move platform project fixtures over to fake cordova into thinking platforms were added
         // TODO: possibly add this to helper?
-        shell.mv('-f', path.join(cordova_project, 'platforms', 'blackberry'), path.join(tempDir));
         this.after(function() {
             process.chdir(cwd);
-            shell.mv('-f', path.join(tempDir, 'blackberry'), path.join(cordova_project, 'platforms', 'blackberry'));
         });
 
-        process.chdir(cordova_project);
-
-        var a_parser_spy = spyOn(android_parser.prototype, 'update_project');
-        var i_parser_spy = spyOn(ios_parser.prototype, 'update_project');
+        spyOn(shell, 'exec');
         expect(function() {
+            shell.cp('-Rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms'));
+            process.chdir(tempDir);
+            var a_parser_spy = spyOn(android_parser.prototype, 'update_project');
             cordova.prepare();
             expect(a_parser_spy).toHaveBeenCalled();
-            expect(i_parser_spy).toHaveBeenCalled();
         }).not.toThrow();
     });
     it('should not run outside of a Cordova-based project', function() {
@@ -91,13 +84,11 @@ describe('prepare command', function() {
 
         describe('when platforms are added', function() {
             beforeEach(function() {
-                shell.mv('-f', path.join(cordova_project, 'platforms', 'blackberry'), path.join(tempDir));
-                shell.mv('-f', path.join(cordova_project, 'platforms', 'ios'), path.join(tempDir));
-                process.chdir(cordova_project);
+                shell.cp('-rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms'));
+                process.chdir(tempDir);
             });
             afterEach(function() {
-                shell.mv('-f', path.join(tempDir, 'blackberry'), path.join(cordova_project, 'platforms', 'blackberry'));
-                shell.mv('-f', path.join(tempDir, 'ios'), path.join(cordova_project, 'platforms', 'ios'));
+                shell.rm('-rf', path.join(tempDir, 'platforms', 'android'));
                 process.chdir(cwd);
             });
 
@@ -106,15 +97,16 @@ describe('prepare command', function() {
                 expect(s).toHaveBeenCalledWith('before_prepare');
             });
             it('should fire after hooks through the hooker module', function() {
-                var parser_spy = spyOn(android_parser.prototype, 'update_project');
-                cordova.prepare();
-                parser_spy.mostRecentCall.args[1](); // parser cb
-                expect(s).toHaveBeenCalledWith('after_prepare');
+                spyOn(shell, 'exec');
+                cordova.prepare('android', function() {
+                     expect(hooker.prototype.fire).toHaveBeenCalledWith('after_prepare');
+                });
             });
         });
 
         describe('with no platforms added', function() {
             beforeEach(function() {
+                shell.rm('-rf', tempDir);
                 cordova.create(tempDir);
                 process.chdir(tempDir);
             });

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/cordova-cli/serve.spec.js
----------------------------------------------------------------------
diff --git a/spec/cordova-cli/serve.spec.js b/spec/cordova-cli/serve.spec.js
index 8d00cab..2e61212 100644
--- a/spec/cordova-cli/serve.spec.js
+++ b/spec/cordova-cli/serve.spec.js
@@ -17,18 +17,20 @@
     specific language governing permissions and limitations
     under the License.
 */
-var cordova = require('../cordova'),
+var cordova = require('../../cordova'),
     path = require('path'),
     shell = require('shelljs'),
     request = require('request'),
     fs = require('fs'),
-    util = require('../src/util'),
-    hooker = require('../src/hooker'),
-    tempDir = path.join(__dirname, '..', 'temp'),
+    util = require('../../src/util'),
+    hooker = require('../../src/hooker'),
+    tempDir = path.join(__dirname, '..', '..', 'temp'),
     http = require('http'),
-    android_parser = require('../src/metadata/android_parser'),
-    ios_parser = require('../src/metadata/ios_parser'),
-    blackberry_parser = require('../src/metadata/blackberry_parser');
+    android_parser = require('../../src/metadata/android_parser'),
+    ios_parser = require('../../src/metadata/ios_parser'),
+    blackberry_parser = require('../../src/metadata/blackberry_parser'),
+    wp7_parser        = require('../../src/metadata/wp7_parser'),
+    wp8_parser        = require('../../src/metadata/wp8_parser');
 
 var cwd = process.cwd();
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/cordova-cli/util.spec.js
----------------------------------------------------------------------
diff --git a/spec/cordova-cli/util.spec.js b/spec/cordova-cli/util.spec.js
new file mode 100644
index 0000000..787b00f
--- /dev/null
+++ b/spec/cordova-cli/util.spec.js
@@ -0,0 +1,34 @@
+var cordova = require('../../cordova'),
+    shell = require('shelljs'),
+    path = require('path'),
+    fs = require('fs'),
+    cordova_util = require('../../src/util'),
+    fixtures = path.join(__dirname, '..', 'fixtures'),
+    cordova_project = path.join(fixtures, 'projects', 'cordova');
+
+
+var cwd = process.cwd();
+
+describe('util command', function() {
+    beforeEach(function() {
+        process.chdir(cordova_project);
+    });
+    afterEach(function() {
+        process.chdir(cwd);
+    });
+    describe('listPlatforms', function() {
+        it('should not treat a .gitignore file as a platform', function() {
+            var gitignore = path.join(cordova_project, 'platforms', '.gitignore');
+            fs.writeFileSync(gitignore, 'somethinghere', 'utf-8');
+            this.after(function() {
+                shell.rm('-f', gitignore);
+            });
+
+            var s = spyOn(shell, 'exec');
+            var platforms = cordova_util.listPlatforms(cordova_project);
+            platforms.forEach(function(platform) {
+                expect(platform).not.toMatch(/\.gitignore/);
+            }); 
+        });
+    });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/platform-script/android/android.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform-script/android/android.spec.js b/spec/platform-script/android/android.spec.js
new file mode 100644
index 0000000..8c39af0
--- /dev/null
+++ b/spec/platform-script/android/android.spec.js
@@ -0,0 +1,98 @@
+var cordova = require('../../../cordova'),
+    shell = require('shelljs'),
+    path = require('path'),
+    fs = require('fs'),
+    android_parser = require('../../../src/metadata/android_parser'),
+    tempDir = path.join(__dirname, '..', '..', '..', 'temp'),
+    fixtures = path.join(__dirname, '..', '..', 'fixtures'),
+    cordova_project = path.join(fixtures, 'projects', 'cordova');
+
+var cwd = process.cwd();
+
+describe('Test:', function() {
+    afterEach(function() {
+        process.chdir(cwd);
+    });
+
+    describe('\'platform add android\'', function() {
+        var sh, cr;
+        var fake_reqs_check = function() {
+            expect(cr.mostRecentCall.args).toBeDefined();
+            cr.mostRecentCall.args[0](false);
+        };
+        var fake_create = function(a_path) {
+            shell.mkdir('-p', a_path);
+            fs.writeFileSync(path.join(a_path, 'AndroidManifest.xml'), 'hi', 'utf-8');
+            sh.mostRecentCall.args[2](0, '');
+        };
+        beforeEach(function() {
+            sh = spyOn(shell, 'exec');
+            cr = spyOn(android_parser, 'check_requirements');
+            shell.rm('-rf', tempDir);
+            cordova.create(tempDir);
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        it('should shell out to android /bin/create', function() {
+            cordova.platform('add', 'android');
+            fake_reqs_check();
+            var shell_cmd = sh.mostRecentCall.args[0];
+            var create_cmd = path.join('android', 'bin', 'create');
+            expect(shell_cmd).toContain(create_cmd);
+        });
+        it('should call android_parser\'s update_project', function() {
+            spyOn(android_parser.prototype, 'update_project');
+            cordova.platform('add', 'android');
+            fake_reqs_check();
+            fake_create(path.join(tempDir, 'platforms', 'android'));
+            expect(android_parser.prototype.update_project).toHaveBeenCalled();
+        });
+    });
+
+    describe('\'emulate android\'', function() {
+        beforeEach(function() {
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        shell.rm('-rf', tempDir);
+        cordova.create(tempDir);
+        shell.cp('-rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms'));
+        it('should shell out to run command on Android', function() {
+            var proj_spy = spyOn(android_parser.prototype, 'update_project');
+            var s = spyOn(require('shelljs'), 'exec');
+            cordova.emulate('android');
+            proj_spy.mostRecentCall.args[1](); // update_project fake
+            expect(s).toHaveBeenCalled();
+            var emulate_cmd = path.join('android', 'cordova', 'run');
+            expect(s.mostRecentCall.args[0]).toContain(emulate_cmd);
+        });
+        it('should call android_parser\'s update_project', function() {
+            spyOn(require('shelljs'), 'exec');
+            spyOn(android_parser.prototype, 'update_project');
+            cordova.emulate('android');
+            expect(android_parser.prototype.update_project).toHaveBeenCalled();
+        });
+    });
+
+    describe('\'compile android\'', function() {
+        beforeEach(function() {
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        shell.rm('-rf', tempDir);
+        cordova.create(tempDir);
+        shell.cp('-rf', path.join(cordova_project, 'platforms', 'android'), path.join(tempDir, 'platforms'));
+        it('should shell out to build command', function() {
+            var build_cmd = path.join('android', 'cordova', 'build');
+            var s = spyOn(require('shelljs'), 'exec').andReturn({code:0});
+            cordova.compile('android');
+            expect(s.mostRecentCall.args[0]).toContain(build_cmd);
+        });
+    });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/platform-script/android/android_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform-script/android/android_parser.spec.js b/spec/platform-script/android/android_parser.spec.js
index d051c6f..84c7903 100644
--- a/spec/platform-script/android/android_parser.spec.js
+++ b/spec/platform-script/android/android_parser.spec.js
@@ -17,15 +17,15 @@
     specific language governing permissions and limitations
     under the License.
 */
-var android_parser = require('../../src/metadata/android_parser'),
-    config_parser = require('../../src/config_parser'),
-    util = require('../../src/util'),
+var android_parser = require('../../../src/metadata/android_parser'),
+    config_parser = require('../../../src/config_parser'),
+    util = require('../../../src/util'),
     path = require('path'),
     shell = require('shelljs'),
     fs = require('fs'),
     et = require('elementtree'),
-    cordova = require('../../cordova'),
-    projects_path = path.join(__dirname, '..', 'fixtures', 'projects'),
+    cordova = require('../../../cordova'),
+    projects_path = path.join(__dirname, '..', '..', 'fixtures', 'projects'),
     android_path = path.join(projects_path, 'native', 'android_fixture'),
     project_path = path.join(projects_path, 'cordova'),
     android_project_path = path.join(project_path, 'platforms', 'android');

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/platform-script/blackberry/blackberry.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform-script/blackberry/blackberry.spec.js b/spec/platform-script/blackberry/blackberry.spec.js
new file mode 100644
index 0000000..ff997c1
--- /dev/null
+++ b/spec/platform-script/blackberry/blackberry.spec.js
@@ -0,0 +1,105 @@
+var cordova = require('../../../cordova'),
+    shell = require('shelljs'),
+    path = require('path'),
+    fs = require('fs'),
+    blackberry_parser = require('../../../src/metadata/blackberry_parser'),
+    tempDir = path.join(__dirname, '..', '..', '..', 'temp'),
+    fixtures = path.join(__dirname, '..', '..', 'fixtures'),
+    cordova_project = path.join(fixtures, 'projects', 'cordova');
+
+var cwd = process.cwd();
+
+describe('Test:', function() {
+
+    afterEach(function() {
+        process.chdir(cwd);
+    });
+
+    describe('\'platform add blackberry\'', function() {
+        var sh, cr;
+        var fake_reqs_check = function() {
+            expect(cr.mostRecentCall.args).toBeDefined();
+            cr.mostRecentCall.args[0](false);
+        };
+        var fake_create = function(a_path) {
+            shell.mkdir('-p', path.join(a_path, 'www'));
+            fs.writeFileSync(path.join(a_path, 'project.properties'), 'hi', 'utf-8');
+            fs.writeFileSync(path.join(a_path, 'build.xml'), 'hi', 'utf-8');
+            shell.cp('-rf', path.join(cordova_project, 'platforms', 'blackberry', 'www', 'config.xml'), path.join(a_path, 'www'));
+            sh.mostRecentCall.args[2](0, '');
+        };
+        beforeEach(function() {
+            sh = spyOn(shell, 'exec');
+            cr = spyOn(blackberry_parser, 'check_requirements');
+            shell.rm('-rf', tempDir);
+            cordova.create(tempDir);
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        it('should check requirements when adding', function() {
+            cordova.platform('add', 'blackberry');
+            expect(blackberry_parser.check_requirements).toHaveBeenCalled();
+        });
+        it('should shell out to blackberry bin/create', function() {
+            cordova.platform('add', 'blackberry');
+            fake_reqs_check();
+            var shell_cmd = sh.mostRecentCall.args[0];
+            var create_cmd = path.join('blackberry', 'bin', 'create');
+            expect(shell_cmd).toContain(create_cmd);
+        });
+        it('should call blackberry_parser\'s update_project', function() {
+            spyOn(blackberry_parser.prototype, 'update_project');
+            cordova.platform('add', 'blackberry');
+            fake_reqs_check();
+            fake_create(path.join(tempDir, 'platforms', 'blackberry'));
+            expect(blackberry_parser.prototype.update_project).toHaveBeenCalled();
+        });
+    });
+
+    describe('\'emulate blackberry\'', function() {
+        beforeEach(function() {
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        shell.rm('-rf', tempDir);
+        cordova.create(tempDir);
+        shell.cp('-rf', path.join(cordova_project, 'platforms', 'blackberry'), path.join(tempDir, 'platforms'));
+        it('should shell out to ant command on blackberry', function() {
+            var proj_spy = spyOn(blackberry_parser.prototype, 'update_project');
+            var s = spyOn(require('shelljs'), 'exec');
+            cordova.emulate('blackberry');
+            proj_spy.mostRecentCall.args[1](); // update_project fake
+            expect(s).toHaveBeenCalled();
+            var emulate_cmd = 'ant -f .*build\.xml" qnx load-simulator';
+            expect(s.mostRecentCall.args[0]).toMatch(emulate_cmd);
+        });
+        it('should call blackberry_parser\'s update_project', function() {
+            spyOn(require('shelljs'), 'exec');
+            spyOn(blackberry_parser.prototype, 'update_project');
+            cordova.emulate('blackberry');
+            expect(blackberry_parser.prototype.update_project).toHaveBeenCalled();
+        });
+    });
+
+    describe('\'compile blackberry\'', function() {
+        beforeEach(function() {
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        shell.rm('-rf', tempDir);
+        cordova.create(tempDir);
+        shell.cp('-rf', path.join(cordova_project, 'platforms', 'blackberry'), path.join(tempDir, 'platforms'));
+        it('should shell out to build command', function() {
+            var build_cmd = 'build.xml" qnx load-device';
+            var s = spyOn(require('shelljs'), 'exec').andReturn({code:0});
+            cordova.compile('blackberry');
+            expect(s.mostRecentCall.args[0]).toContain(build_cmd);
+        });
+    });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/platform-script/blackberry/blackberry_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform-script/blackberry/blackberry_parser.spec.js b/spec/platform-script/blackberry/blackberry_parser.spec.js
index 12d5294..d183f7f 100644
--- a/spec/platform-script/blackberry/blackberry_parser.spec.js
+++ b/spec/platform-script/blackberry/blackberry_parser.spec.js
@@ -17,15 +17,15 @@
     specific language governing permissions and limitations
     under the License.
 */
-var blackberry_parser = require('../../src/metadata/blackberry_parser'),
-    config_parser = require('../../src/config_parser'),
+var blackberry_parser = require('../../../src/metadata/blackberry_parser'),
+    config_parser = require('../../../src/config_parser'),
     path = require('path'),
-    util = require('../../src/util'),
+    util = require('../../../src/util'),
     et = require('elementtree'),
     shell = require('shelljs'),
-    cordova = require('../../cordova'),
+    cordova = require('../../../cordova'),
     fs = require('fs'),
-    projects_path = path.join(__dirname, '..', 'fixtures', 'projects'),
+    projects_path = path.join(__dirname, '..', '..', 'fixtures', 'projects'),
     blackberry_path = path.join(projects_path, 'native', 'blackberry_fixture'),
     project_path = path.join(projects_path, 'cordova'),
     blackberry_project_path = path.join(project_path, 'platforms', 'blackberry');

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/platform-script/ios/ios.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform-script/ios/ios.spec.js b/spec/platform-script/ios/ios.spec.js
new file mode 100644
index 0000000..0fecd75
--- /dev/null
+++ b/spec/platform-script/ios/ios.spec.js
@@ -0,0 +1,99 @@
+var cordova = require('../../../cordova'),
+    shell = require('shelljs'),
+    path = require('path'),
+    fs = require('fs'),
+    ios_parser = require('../../../src/metadata/ios_parser'),
+    tempDir = path.join(__dirname, '..', '..', '..', 'temp'),
+    fixtures = path.join(__dirname, '..', '..', 'fixtures'),
+    cordova_project = path.join(fixtures, 'projects', 'cordova');
+
+var cwd = process.cwd();
+
+describe('Test:', function() {
+    afterEach(function() {
+        process.chdir(cwd);
+    });
+
+    describe('\'platform add ios\'', function() {
+        var sh, cr;
+        var fake_reqs_check = function() {
+            cr.mostRecentCall.args[0](false);
+        };
+        var fake_create = function(a_path) {
+            shell.mkdir('-p', a_path);
+            fs.writeFileSync(path.join(a_path, 'poo.xcodeproj'), 'hi', 'utf-8');
+            shell.mkdir('-p', path.join(a_path, 'poo'));
+            shell.cp(path.join(cordova_project, 'www', 'config.xml'), path.join(a_path, 'poo', 'config.xml'));
+            sh.mostRecentCall.args[2](0, '');
+        };
+        beforeEach(function() {
+            sh = spyOn(shell, 'exec');
+            cr = spyOn(ios_parser, 'check_requirements');
+            shell.rm('-rf', tempDir);
+            cordova.create(tempDir);
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        it('should shell out to ios /bin/create', function() {
+            cordova.platform('add', 'ios');
+            fake_reqs_check();
+            var shell_cmd = sh.mostRecentCall.args[0];
+            var create_cmd = path.join('ios', 'bin', 'create');
+            expect(shell_cmd).toContain(create_cmd);
+        });
+        it('should call ios_parser\'s update_project', function() {
+            spyOn(ios_parser.prototype, 'update_project');
+            cordova.platform('add', 'ios');
+            fake_reqs_check();
+            fake_create(path.join(tempDir, 'platforms', 'ios'));
+            expect(ios_parser.prototype.update_project).toHaveBeenCalled();
+        });
+    });
+
+    describe('\'emulate ios\'', function() {
+        beforeEach(function() {
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        shell.rm('-rf', tempDir);
+        cordova.create(tempDir);
+        shell.cp('-rf', path.join(cordova_project, 'platforms', 'ios'), path.join(tempDir, 'platforms'));
+        it('should shell out to run command on ios', function() {
+            var proj_spy = spyOn(ios_parser.prototype, 'update_project');
+            var s = spyOn(require('shelljs'), 'exec');
+            cordova.emulate('ios');
+            proj_spy.mostRecentCall.args[1](); // update_project fake
+            expect(s).toHaveBeenCalled();
+            var emulate_cmd = path.join('ios', 'cordova', 'run');
+            expect(s.mostRecentCall.args[0]).toContain(emulate_cmd);
+        });
+        it('should call ios_parser\'s update_project', function() {
+            spyOn(require('shelljs'), 'exec');
+            spyOn(ios_parser.prototype, 'update_project');
+            cordova.emulate('ios');
+            expect(ios_parser.prototype.update_project).toHaveBeenCalled();
+        });
+    });
+
+    describe('\'compile ios\'', function() {
+        beforeEach(function() {
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        shell.rm('-rf', tempDir);
+        cordova.create(tempDir);
+        shell.cp('-rf', path.join(cordova_project, 'platforms', 'ios'), path.join(tempDir, 'platforms'));
+        it('should shell out to build command', function() {
+            var build_cmd = path.join('ios', 'cordova', 'build');
+            var s = spyOn(require('shelljs'), 'exec').andReturn({code:0});
+            cordova.compile('ios');
+            expect(s.mostRecentCall.args[0]).toContain(build_cmd);
+        });
+    });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/platform-script/ios/ios_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform-script/ios/ios_parser.spec.js b/spec/platform-script/ios/ios_parser.spec.js
index dbd4816..b0c2aeb 100644
--- a/spec/platform-script/ios/ios_parser.spec.js
+++ b/spec/platform-script/ios/ios_parser.spec.js
@@ -17,16 +17,17 @@
  under the License.
  */
 
-var ios_parser = require('../../src/metadata/ios_parser'),
-    config_parser = require('../../src/config_parser'),
-    cordova = require('../../cordova'),
-    util = require('../../src/util'),
+var ios_parser = require('../../../src/metadata/ios_parser'),
+    config_parser = require('../../../src/config_parser'),
+    cordova = require('../../../cordova'),
+    util = require('../../../src/util'),
     path = require('path'),
     shell = require('shelljs'),
     fs = require('fs'),
+    os = require('os'),
     et = require('elementtree'),
-    projects_path = path.join(__dirname, '..', 'fixtures', 'projects')
-ios_path = path.join(projects_path, 'native', 'ios_fixture'),
+    projects_path = path.join(__dirname, '..', '..', 'fixtures', 'projects')
+    ios_path = path.join(projects_path, 'native', 'ios_fixture'),
     project_path = path.join(projects_path, 'cordova'),
     ios_project_path = path.join(project_path, 'platforms', 'ios');
 

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/platform-script/wp7/wp7.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform-script/wp7/wp7.spec.js b/spec/platform-script/wp7/wp7.spec.js
new file mode 100644
index 0000000..6b7f3b4
--- /dev/null
+++ b/spec/platform-script/wp7/wp7.spec.js
@@ -0,0 +1,99 @@
+var cordova = require('../../../cordova'),
+    shell = require('shelljs'),
+    path = require('path'),
+    fs = require('fs'),
+    wp7_parser = require('../../../src/metadata/wp7_parser'),
+    tempDir = path.join(__dirname, '..', '..', '..', 'temp'),
+    fixtures = path.join(__dirname, '..', '..', 'fixtures'),
+    cordova_project = path.join(fixtures, 'projects', 'cordova');
+
+var cwd = process.cwd();
+
+describe('Test:', function() {
+    afterEach(function() {
+        process.chdir(cwd);
+    });
+
+    describe('\'platform add wp7\'', function() {
+        var sh, cr;
+        var fake_reqs_check = function() {
+            expect(cr.mostRecentCall.args).toBeDefined();
+            cr.mostRecentCall.args[0](false);
+        };
+        var fake_create = function(a_path) {
+            shell.mkdir('-p', a_path);
+            fs.writeFileSync(path.join(a_path, 'wp7Project.csproj'), 'hi', 'utf-8');
+            fs.writeFileSync(path.join(a_path, 'wp7Project.sln'), 'hi', 'utf-8');
+            sh.mostRecentCall.args[2](0, '');
+        };
+        beforeEach(function() {
+            sh = spyOn(shell, 'exec');
+            cr = spyOn(wp7_parser, 'check_requirements');
+            shell.rm('-rf', tempDir);
+            cordova.create(tempDir);
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        it('should shell out to wp7 /bin/create', function() {
+            cordova.platform('add', 'wp7');
+            fake_reqs_check();
+            var shell_cmd = sh.mostRecentCall.args[0];
+            var create_cmd = path.join('wp7', 'bin', 'create');
+            expect(shell_cmd).toContain(create_cmd);
+        });
+        it('should call wp7_parser\'s update_project', function() {
+            spyOn(wp7_parser.prototype, 'update_project');
+            cordova.platform('add', 'wp7');
+            fake_reqs_check();
+            fake_create(path.join(tempDir, 'platforms', 'wp7'));
+            expect(wp7_parser.prototype.update_project).toHaveBeenCalled();
+        });
+    });
+
+    describe('\'emulate wp7\'', function() {
+        beforeEach(function() {
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        shell.rm('-rf', tempDir);
+        cordova.create(tempDir);
+        shell.cp('-rf', path.join(cordova_project, 'platforms', 'wp7'), path.join(tempDir, 'platforms'));
+        it('should shell out to run command on wp7', function() {
+            var proj_spy = spyOn(wp7_parser.prototype, 'update_project');
+            var s = spyOn(require('shelljs'), 'exec');
+            cordova.emulate('wp7');
+            proj_spy.mostRecentCall.args[1](); // update_project fake
+            expect(s).toHaveBeenCalled();
+            var emulate_cmd = path.join('wp7', 'cordova', 'run');
+            expect(s.mostRecentCall.args[0]).toContain(emulate_cmd);
+        });
+        it('should call wp7_parser\'s update_project', function() {
+            spyOn(require('shelljs'), 'exec');
+            spyOn(wp7_parser.prototype, 'update_project');
+            cordova.emulate('wp7');
+            expect(wp7_parser.prototype.update_project).toHaveBeenCalled();
+        });
+    });
+
+    describe('\'compile wp7\'', function() {
+        beforeEach(function() {
+            process.chdir(tempDir);
+        });
+        afterEach(function() {
+            process.chdir(cwd);
+        });
+        shell.rm('-rf', tempDir);
+        cordova.create(tempDir);
+        shell.cp('-rf', path.join(cordova_project, 'platforms', 'wp7'), path.join(tempDir, 'platforms'));
+        it('should shell out to build command', function() {
+            var build_cmd = path.join('wp7', 'cordova', 'build');
+            var s = spyOn(require('shelljs'), 'exec').andReturn({code:0});
+            cordova.compile('wp7');
+            expect(s.mostRecentCall.args[0]).toContain(build_cmd);
+        });
+    });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-cli/blob/ddfa0837/spec/platform-script/wp7/wp7_parser.spec.js
----------------------------------------------------------------------
diff --git a/spec/platform-script/wp7/wp7_parser.spec.js b/spec/platform-script/wp7/wp7_parser.spec.js
new file mode 100644
index 0000000..7840bff
--- /dev/null
+++ b/spec/platform-script/wp7/wp7_parser.spec.js
@@ -0,0 +1,249 @@
+
+/**
+    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 wp7_parser = require('../../../src/metadata/wp7_parser'),
+    config_parser = require('../../../src/config_parser'),
+    util = require('../../../src/util'),
+    path = require('path'),
+    shell = require('shelljs'),
+    fs = require('fs'),
+    os = require('os'),
+    et = require('elementtree'),
+    cordova = require('../../../cordova'),
+    projects_path = path.join(__dirname, '..', '..', 'fixtures', 'projects'),
+    wp7_path = path.join(projects_path, 'native', 'wp7_fixture'),
+    project_path = path.join(projects_path, 'cordova'),
+    wp7_project_path = path.join(project_path, 'platforms', 'wp7');
+
+var www_config = util.projectConfig(project_path);
+var original_www_config = fs.readFileSync(www_config, 'utf-8');
+
+describe('wp7 project parser', function() {
+    it('should throw an exception with a path that is not a native wp7 project', function() {
+        expect(function() {
+            var project = new wp7_parser(process.cwd());
+        }).toThrow();
+    });
+    it('should accept a proper native wp7 project path as construction parameter', function() {
+        expect(function() {
+            var project = new wp7_parser(wp7_path);
+            expect(project).toBeDefined();
+        }).not.toThrow();
+    });
+
+    describe('update_from_config method', function() {
+        var config;
+        var project = new wp7_parser(wp7_path);
+
+        var manifest_path  = path.join(wp7_path, 'Properties', 'WMAppManifest.xml');
+        var csproj_path    = project.csproj_path;
+        var sln_path       = project.sln_path;
+        var app_xaml_path  = path.join(wp7_path, 'App.xaml');
+        var app_cs_path    = path.join(wp7_path, 'App.xaml.cs');
+        var main_xaml_path = path.join(wp7_path, 'MainPage.xaml');
+        var main_cs_path   = path.join(wp7_path, 'MainPage.xaml.cs');
+
+
+        var original_manifest  = fs.readFileSync(manifest_path, 'utf-8');
+        var original_csproj    = fs.readFileSync(csproj_path, 'utf-8');
+        var original_sln       = fs.readFileSync(sln_path, 'utf-8');
+        var original_app_xaml  = fs.readFileSync(app_xaml_path, 'utf-8');
+        var original_app_cs    = fs.readFileSync(app_cs_path, 'utf-8');
+        var original_main_xaml = fs.readFileSync(main_xaml_path, 'utf-8');
+        var original_main_cs   = fs.readFileSync(main_cs_path, 'utf-8');
+
+        beforeEach(function() {
+            project = new wp7_parser(wp7_path);
+            config = new config_parser(www_config);
+        });
+        afterEach(function() {
+            fs.writeFileSync(manifest_path, original_manifest, 'utf-8');
+            // csproj file changes name if app changes name
+            fs.unlinkSync(project.csproj_path);
+            fs.unlinkSync(project.sln_path);
+            fs.writeFileSync(csproj_path, original_csproj, 'utf-8');
+            fs.writeFileSync(sln_path, original_sln, 'utf-8');
+            fs.writeFileSync(app_xaml_path, original_app_xaml, 'utf-8');
+            fs.writeFileSync(app_cs_path, original_app_cs, 'utf-8');
+            fs.writeFileSync(main_xaml_path, original_main_xaml, 'utf-8');
+            fs.writeFileSync(main_cs_path, original_main_cs, 'utf-8');
+        });
+        it('should throw an exception if a non config_parser object is passed into it', function() {
+            expect(function() {
+                project.update_from_config({});
+            }).toThrow();
+        });
+        it('should update the application name properly', function() {
+            var test_name = 'bond. james bond.';
+            config.name(test_name);
+            project.update_from_config(config);
+            var raw_manifest = fs.readFileSync(manifest_path, 'utf-8');
+            //Strip three bytes that windows adds (http://www.multiasking.com/2012/11/851)
+            var cleaned_manifest = raw_manifest.replace('\ufeff', '');
+            var manifest = new et.ElementTree(et.XML(cleaned_manifest));
+            var app_name = manifest.find('.//App[@Title]')['attrib']['Title'];
+            expect(app_name).toBe(test_name);
+
+            //check for the proper name of csproj and solution files
+            test_name = test_name.replace(/(\.\s|\s\.|\s+|\.+)/g, '_'); //make it a ligitamate name
+            expect(project.csproj_path).toContain(test_name);
+            expect(project.sln_path).toContain(test_name);
+        });
+        it('should update the application package name properly', function() {
+            var test_package = 'ca.filmaj.dewd'
+            config.packageName(test_package);
+            project.update_from_config(config);
+
+            // check csproj file (use regex instead of elementtree?)
+            var raw_csproj = fs.readFileSync(project.csproj_path, 'utf-8');
+            var cleaned_csproj = raw_csproj.replace(/^\uFEFF/i, '');
+            var csproj = new et.ElementTree(et.XML(cleaned_csproj));
+            expect(csproj.find('.//RootNamespace').text).toEqual(test_package);
+            expect(csproj.find('.//AssemblyName').text).toEqual(test_package);
+            expect(csproj.find('.//XapFilename').text).toEqual(test_package + '.xap');
+            expect(csproj.find('.//SilverlightAppEntry').text).toEqual(test_package + '.App');
+
+            // check app.xaml (use regex instead of elementtree?)
+            var new_app_xaml = fs.readFileSync(app_xaml_path, 'utf-8');
+            var cleaned_app_xaml = new_app_xaml.replace(/^\uFEFF/i, '');
+            var app_xaml = new et.ElementTree(et.XML(cleaned_app_xaml));
+            expect(app_xaml._root.attrib['x:Class']).toEqual(test_package + '.App');
+
+            // check app.xaml.cs
+            var new_app_cs = fs.readFileSync(app_cs_path, 'utf-8');
+            expect(new_app_cs).toContain('namespace ' + test_package);
+
+            // check MainPage.xaml (use regex instead of elementtree?)
+            var new_main_xaml = fs.readFileSync(main_xaml_path, 'utf-8');
+            var cleaned_main_xaml = new_main_xaml.replace(/^\uFEFF/i, '');
+            var main_xaml = new et.ElementTree(et.XML(cleaned_main_xaml));
+            expect(main_xaml._root.attrib['x:Class']).toEqual(test_package + '.MainPage');
+
+            //check MainPage.xaml.cs
+            var new_main_cs = fs.readFileSync(main_cs_path, 'utf-8');
+            expect(new_main_cs).toContain('namespace ' + test_package);
+        });
+        xdescribe('preferences', function() {
+            it('should not change default project preferences and copy over additional project preferences to platform-level config.xml', function() {
+                /*config.preference.add({name:'henrik',value:'sedin'});
+                project.update_from_config(config);
+
+                var native_config = new et.ElementTree(et.XML(fs.readFileSync(android_config, 'utf-8')));
+                var ps = native_config.findall('preference');
+                expect(ps.length).toEqual(7);
+                expect(ps[0].attrib.name).toEqual('useBrowserHistory');
+                expect(ps[0].attrib.value).toEqual('true');
+                expect(ps[6].attrib.name).toEqual('henrik');
+                expect(ps[6].attrib.value).toEqual('sedin');*/
+
+                // TODO : figure out if this is supported
+                //expect(true).toBe(false);
+            });
+            it('should override a default project preference if applicable', function() {
+                /*config.preference.add({name:'useBrowserHistory',value:'false'});
+                project.update_from_config(config);
+
+                var native_config = new et.ElementTree(et.XML(fs.readFileSync(android_config, 'utf-8')));
+                var ps = native_config.findall('preference');
+                expect(ps.length).toEqual(6);
+                expect(ps[0].attrib.name).toEqual('useBrowserHistory');
+                expect(ps[0].attrib.value).toEqual('false');*/
+
+                // TODO : figure out if this is supported
+                //expect(true).toBe(false);
+            });
+        });
+    });
+
+    describe('cross-platform project level methods', function() {
+        var parser, config;
+
+        beforeEach(function() {
+            parser = new wp7_parser(wp7_project_path);
+            config = new config_parser(www_config);
+        });
+        afterEach(function() {
+        });
+        describe('update_www method', function() {
+            it('should update all www assets', function() {
+                var newFile = path.join(util.projectWww(project_path), 'somescript.js');
+                this.after(function() {
+                    shell.rm('-f', newFile);
+                });
+                fs.writeFileSync(newFile, 'alert("sup");', 'utf-8');
+                parser.update_www();
+                expect(fs.existsSync(path.join(wp7_project_path, 'www', 'somescript.js'))).toBe(true);
+            });
+            it('should write out windows-phone js to cordova.js', function() {
+                parser.update_www();
+                var raw_version = fs.readFileSync(path.join(util.libDirectory, 'cordova-wp7', 'VERSION'), 'utf-8');
+                var wp7_version = raw_version.replace(/\r\n/,'').replace(/\n/,'');
+                expect(fs.readFileSync(path.join(wp7_project_path, 'www', 'cordova.js'),'utf-8')).toEqual(fs.readFileSync(path.join(util.libDirectory, 'cordova-wp7', 'templates', 'standalone', 'www', 'cordova-' + wp7_version + '.js'), 'utf-8'));
+            });
+        });
+
+        xdescribe('update_overrides method',function() {
+            /*var mergesPath = path.join(util.appDir(project_path), 'merges', 'android');
+            var newFile = path.join(mergesPath, 'merge.js');
+            beforeEach(function() {
+                shell.mkdir('-p', mergesPath);
+                fs.writeFileSync(newFile, 'alert("sup");', 'utf-8');
+            });
+            afterEach(function() {
+                shell.rm('-rf', mergesPath);
+            });
+            it('should copy a new file from merges into www', function() {
+                parser.update_overrides();
+                expect(fs.existsSync(path.join(wp7_project_path, 'assets', 'www', 'merge.js'))).toBe(true);
+            });
+
+            it('should copy a file from merges over a file in www', function() {
+                var newFileWWW = path.join(util.projectWww(project_path), 'merge.js');
+                fs.writeFileSync(newFileWWW, 'var foo=1;', 'utf-8');
+                this.after(function() {
+                    shell.rm('-rf', newFileWWW);
+                });
+                parser.update_overrides();
+                expect(fs.existsSync(path.join(wp7_project_path, 'assets', 'www', 'merge.js'))).toBe(true);
+                expect(fs.readFileSync(path.join(wp7_project_path, 'assets', 'www', 'merge.js'),'utf-8')).toEqual('alert("sup");');
+            });*/
+
+            // TODO : figure out if this is supported
+            //expect(true).toBe(false);
+        });
+
+        describe('update_project method', function() {
+            it('should invoke update_www', function() {
+                var spyWww = spyOn(parser, 'update_www');
+                parser.update_project(config);
+                expect(spyWww).toHaveBeenCalled();
+            });
+            it('should invoke update_from_config', function() {
+                var spyConfig = spyOn(parser, 'update_from_config');
+                parser.update_project(config);
+                expect(spyConfig).toHaveBeenCalled();
+            });
+            it('should call out to util.deleteSvnFolders', function() {
+                var spy = spyOn(util, 'deleteSvnFolders');
+                parser.update_project(config);
+                expect(spy).toHaveBeenCalled();
+            });
+        });
+    });
+});
\ No newline at end of file


Mime
View raw message