You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by js...@apache.org on 2014/07/01 00:47:12 UTC

git commit: CB-7056 serve: return promise of server

Repository: cordova-lib
Updated Branches:
  refs/heads/master 56276ef3e -> b2f79a67b


CB-7056 serve: return promise of server

+ restore serve tests

This fixes a regression from:

    Update "cordova serve" to work with promises refactoring
    apache/cordova-cli@d3b329277209d8863507f3b8bf0bad11e73736ef
    Oct 3 14:27:53 2013 -0400


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

Branch: refs/heads/master
Commit: b2f79a67b5d1a0574e8fb74915442f02b2e3831c
Parents: 56276ef
Author: Josh Soref <js...@blackberry.com>
Authored: Mon Jun 30 09:50:47 2014 -0400
Committer: Josh Soref <js...@blackberry.com>
Committed: Mon Jun 30 16:25:31 2014 -0400

----------------------------------------------------------------------
 cordova-lib/spec-cordova/serve.spec.js | 135 ++++++++++++++++++++--------
 cordova-lib/src/cordova/serve.js       | 107 ++++++++++++----------
 2 files changed, 156 insertions(+), 86 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/b2f79a67/cordova-lib/spec-cordova/serve.spec.js
----------------------------------------------------------------------
diff --git a/cordova-lib/spec-cordova/serve.spec.js b/cordova-lib/spec-cordova/serve.spec.js
index 1a1c96a..4572913 100644
--- a/cordova-lib/spec-cordova/serve.spec.js
+++ b/cordova-lib/spec-cordova/serve.spec.js
@@ -17,13 +17,16 @@
     under the License.
 */
 var cordova = require('../src/cordova/cordova'),
+    console = require('console'),
     path = require('path'),
     shell = require('shelljs'),
     fs = require('fs'),
+    Q = require('q'),
     util = require('../src/cordova/util'),
     hooker = require('../src/cordova/hooker'),
     tempDir = path.join(__dirname, '..', 'temp'),
     http = require('http'),
+    firefoxos_parser = require('../src/cordova/metadata/firefoxos_parser'),
     android_parser = require('../src/cordova/metadata/android_parser'),
     ios_parser = require('../src/cordova/metadata/ios_parser'),
     blackberry_parser = require('../src/cordova/metadata/blackberry10_parser'),
@@ -32,63 +35,94 @@ var cordova = require('../src/cordova/cordova'),
 var cwd = process.cwd();
 
 describe('serve command', function() {
+    var payloads = {},
+        consoleSpy;
     beforeEach(function() {
         // Make a temp directory
         shell.rm('-rf', tempDir);
         shell.mkdir('-p', tempDir);
+        consoleSpy = spyOn(console, 'log');
     });
+    afterEach(function() {
+        process.chdir(cwd);
+        process.env.PWD = cwd;
+        shell.rm('-rf', tempDir);
+    })
     it('should not run outside of a Cordova-based project', function() {
-        this.after(function() {
-            process.chdir(cwd);
-        });
-
         process.chdir(tempDir);
 
         expect(function() {
-            cordova.serve('android');
+            cordova.serve().then(function(server) {
+                expect(server).toBe(null);
+                server.close();
+            });
         }).toThrow("Current working directory is not a Cordova-based project.");
     });
 
-    xdescribe('`serve`', function() {
-        var payloads = {
-            android: 'This is the Android test file.',
-            ios: 'This is the iOS test file.'
-        };
-
+    describe('`serve`', function() {
+        var done = false, failed = false;
         beforeEach(function() {
-            cordova.raw.create(tempDir);
-            process.chdir(tempDir);
-            cordova.raw.platform('add', 'android');
-            cordova.raw.platform('add', 'ios');
-
-            // Write testing HTML files into the directory.
-            fs.writeFileSync(path.join(tempDir, 'platforms', 'android', 'assets', 'www', 'test.html'), payloads.android);
-            fs.writeFileSync(path.join(tempDir, 'platforms', 'ios', 'www', 'test.html'), payloads.ios);
+            done = false;
+            failed = false;
         });
 
         afterEach(function() {
-            process.chdir(cwd);
+            payloads = {};
         });
 
-        function test_serve(platform, path, expectedContents, port) {
+        function test_serve(platform, ref, expectedContents, opts) {
             return function() {
-                var ret;
+                var server;
                 runs(function() {
-                    ret = port ? cordova.serve(platform, port) : cordova.serve(platform);
+                    cordova.raw.create(tempDir).then(function () {
+                        process.chdir(tempDir);
+                        process.env.PWD = tempDir;
+                        var plats = [];
+                        Object.getOwnPropertyNames(payloads).forEach(function(plat) {
+                            var d = Q.defer();
+                            plats.push(d.promise);
+                            cordova.raw.platform('add', plat, {spawnoutput:'ignore'}).then(function () {
+                                var dir = path.join(tempDir, 'merges', plat, plat == 'android' ? 'assets' : '');
+                                shell.mkdir('-p', dir);
+                                // Write testing HTML files into the directory.
+                                fs.writeFileSync(path.join(dir, 'test.html'), payloads[plat]);
+                                d.resolve();
+                            }).catch(function (e) {
+                                expect(e).toBeUndefined();
+                                failed = true;
+                            });
+                        });
+                        Q.allSettled(plats).then(function () {
+                            opts && 'setup' in opts && opts.setup();
+                            cordova.serve(opts && 'port' in opts && opts.port).then(function (srv) {
+                                server = srv;
+                            });
+                        }).catch(function (e) {
+                            expect(e).toBeUndefined();
+                            failed = true;
+                        });
+                    }).catch(function (e) {
+                        expect(e).toBeUndefined();
+                        failed = true;
+                    });
                 });
 
                 waitsFor(function() {
-                    return ret.server;
+                    return server || failed;
                 }, 'the server should start', 1000);
 
                 var done, errorCB;
                 runs(function() {
-                    expect(ret.server).toBeDefined();
+                    if (failed) {
+                        return;
+                    }
+                    expect(server).toBeDefined();
                     errorCB = jasmine.createSpy();
                     http.get({
                         host: 'localhost',
-                        port: port || 8000,
-                        path: path
+                        port: opts && 'port' in opts ? opts.port : 8000,
+                        path: '/' + platform + '/www' + ref,
+                        connection: 'Close'
                     }).on('response', function(res) {
                         var response = '';
                         res.on('data', function(data) {
@@ -103,28 +137,55 @@ describe('serve command', function() {
                 });
 
                 waitsFor(function() {
-                    return done;
+                    return done || failed;
                 }, 'the HTTP request should complete', 1000);
 
                 runs(function() {
-                    expect(done).toBeTruthy();
-                    expect(errorCB).not.toHaveBeenCalled();
-
-                    ret.server.close();
+                    if (!failed) {
+                        expect(done).toBeTruthy();
+                        expect(errorCB).not.toHaveBeenCalled();
+                    }
+                    opts && 'cleanup' in opts && opts.cleanup();
+                    server && server.close();
                 });
             };
         };
 
         it('should serve from top-level www if the file exists there', function() {
             var payload = 'This is test file.';
-            fs.writeFileSync(path.join(util.projectWww(tempDir), 'test.html'), payload);
-            test_serve('android', '/test.html', payload)();
+            payloads.firefoxos = 'This is the firefoxos test file.'
+            test_serve('firefoxos', '/basictest.html', payload, {
+                setup: function (){
+                    fs.writeFileSync(path.join(util.projectWww(tempDir), 'basictest.html'), payload);
+                }
+            })();
         });
 
-        it('should fall back to assets/www on Android', test_serve('android', '/test.html', payloads.android));
-        it('should fall back to www on iOS', test_serve('ios', '/test.html', payloads.ios));
+        it('should honour a custom port setting', function() {
+            var payload = 'This is test file.';
+            payloads.firefoxos = 'This is the firefoxos test file.'
+            test_serve('firefoxos', '/basictest.html', payload, {
+                port: 9001,
+                setup: function (){
+                    fs.writeFileSync(path.join(util.projectWww(tempDir), 'basictest.html'), payload);
+                }
+            })();
+        });
+
+        it('should fall back to assets/www on Android', function() {
+            payloads.android = 'This is the Android test file.';
+            test_serve('android', '/test.html', payloads.android)();
+        });
 
-        it('should honour a custom port setting', test_serve('android', '/test.html', payloads.android, 9001));
+        it('should fall back to www on iOS', function() {
+            payloads.ios = 'This is the iOS test file.';
+            test_serve('ios', '/test.html', payloads.ios)();
+        });
+
+        it('should fall back to www on firefoxos', function() {
+            payloads.firefoxos = 'This is the firefoxos test file.';
+            test_serve('firefoxos', '/test.html', payloads.firefoxos)();
+        });
     });
 });
 

http://git-wip-us.apache.org/repos/asf/cordova-lib/blob/b2f79a67/cordova-lib/src/cordova/serve.js
----------------------------------------------------------------------
diff --git a/cordova-lib/src/cordova/serve.js b/cordova-lib/src/cordova/serve.js
index 6d2cab2..4d65421 100644
--- a/cordova-lib/src/cordova/serve.js
+++ b/cordova-lib/src/cordova/serve.js
@@ -28,6 +28,7 @@ var cordova_util = require('./util'),
     platforms     = require('./platforms'),
     ConfigParser = require('../configparser/ConfigParser'),
     hooker        = require('./hooker'),
+    Q = require('q'),
     fs = require('fs'),
     http = require('http'),
     url = require('url'),
@@ -35,18 +36,21 @@ var cordova_util = require('./util'),
     zlib = require('zlib');
 
 function launchServer(projectRoot, port) {
-    var server = http.createServer(function(request, response) {
+    var server = http.createServer(
+    function(request, response) {
         function do404() {
             console.log('404 ' + request.url);
             response.writeHead(404, {'Content-Type': 'text/plain'});
             response.write('404 Not Found\n');
             response.end();
+            return '';
         }
         function do302(where) {
             console.log('302 ' + request.url);
             response.setHeader('Location', where);
             response.writeHead(302, {'Content-Type': 'text/plain'});
             response.end();
+            return '';
         }
         function doRoot() {
             var p;
@@ -77,6 +81,7 @@ function launchServer(projectRoot, port) {
             response.write('</ul>');
             response.write('</body></html>');
             response.end();
+            return '';
         }
 
         var urlPath = url.parse(request.url).pathname;
@@ -104,7 +109,7 @@ function launchServer(projectRoot, port) {
             filePath = parser.config_xml();
         } else if (urlPath == '/project.json') {
             processAddRequest(request, response, platformId, projectRoot);
-            return;
+            return '';
         } else if (/^\/www\//.test(urlPath)) {
             filePath = path.join(parser.www_dir(), urlPath.slice(5));
         } else if (/^\/+[^\/]*$/.test(urlPath)) {
@@ -114,55 +119,55 @@ function launchServer(projectRoot, port) {
         }
 
         fs.exists(filePath, function(exists) {
-            if (exists) {
-                if (fs.statSync(filePath).isDirectory()) {
-                    var index = path.join(filePath, 'index.html');
-                    try {
-                        if (fs.statSync(index)) {
-                            filePath = index;
-                        }
-                    } catch (e) {}
-                }
-                if (fs.statSync(filePath).isDirectory()) {
-                    if (!/\/$/.test(urlPath)) {
-                        return do302('/' + platformId + urlPath + '/');
-                    }
-                    console.log('200 ' + request.url);
-                    response.writeHead(200, {'Content-Type': 'text/html'});
-                    response.write('<html><head><title>Directory listing of '+ urlPath + '</title></head>');
-                    response.write('<h3>Items in this directory</h3>');
-                    var items = fs.readdirSync(filePath);
-                    response.write('<ul>');
-                    for (var i in items) {
-                        var file = items[i];
-                        if (file) {
-                            response.write('<li><a href="'+file+'">'+file+'</a></li>\n');
-                        }
+            if (!exists) {
+                return do404();
+            }
+            if (fs.statSync(filePath).isDirectory()) {
+                var index = path.join(filePath, 'index.html');
+                try {
+                    if (fs.statSync(index)) {
+                        filePath = index;
                     }
-                    response.write('</ul>');
-                    response.end();
-                } else {
-                    var mimeType = mime.lookup(filePath);
-                    var respHeaders = {
-                        'Content-Type': mimeType
-                    };
-                    var readStream = fs.createReadStream(filePath);
-
-                    var acceptEncoding = request.headers['accept-encoding'] || '';
-                    if (acceptEncoding.match(/\bgzip\b/)) {
-                        respHeaders['content-encoding'] = 'gzip';
-                        readStream = readStream.pipe(zlib.createGzip());
-                    } else if (acceptEncoding.match(/\bdeflate\b/)) {
-                        respHeaders['content-encoding'] = 'deflate';
-                        readStream = readStream.pipe(zlib.createDeflate());
+                } catch (e) {}
+            }
+            if (fs.statSync(filePath).isDirectory()) {
+                if (!/\/$/.test(urlPath)) {
+                    return do302('/' + platformId + urlPath + '/');
+                }
+                console.log('200 ' + request.url);
+                response.writeHead(200, {'Content-Type': 'text/html'});
+                response.write('<html><head><title>Directory listing of '+ urlPath + '</title></head>');
+                response.write('<h3>Items in this directory</h3>');
+                var items = fs.readdirSync(filePath);
+                response.write('<ul>');
+                for (var i in items) {
+                    var file = items[i];
+                    if (file) {
+                        response.write('<li><a href="'+file+'">'+file+'</a></li>\n');
                     }
-                    console.log('200 ' + request.url);
-                    response.writeHead(200, respHeaders);
-                    readStream.pipe(response);
                 }
+                response.write('</ul>');
+                response.end();
             } else {
-                return do404();
+                var mimeType = mime.lookup(filePath);
+                var respHeaders = {
+                    'Content-Type': mimeType
+                };
+                var readStream = fs.createReadStream(filePath);
+
+                var acceptEncoding = request.headers['accept-encoding'] || '';
+                if (acceptEncoding.match(/\bgzip\b/)) {
+                    respHeaders['content-encoding'] = 'gzip';
+                    readStream = readStream.pipe(zlib.createGzip());
+                } else if (acceptEncoding.match(/\bdeflate\b/)) {
+                    respHeaders['content-encoding'] = 'deflate';
+                    readStream = readStream.pipe(zlib.createDeflate());
+                }
+                console.log('200 ' + request.url);
+                response.writeHead(200, respHeaders);
+                readStream.pipe(response);
             }
+            return '';
         });
     }).on('listening', function () {
         console.log('Static file server running on port ' + port + ' (i.e. http://localhost:' + port + ')\nCTRL + C to shut down');
@@ -218,17 +223,21 @@ function processAddRequest(request, response, platformId, projectRoot) {
 }
 
 module.exports = function server(port) {
+    var d = Q.defer();
     var projectRoot = cordova_util.cdProjectRoot();
     port = +port || 8000;
 
     var hooks = new hooker(projectRoot);
-    return hooks.fire('before_serve')
+    hooks.fire('before_serve')
     .then(function() {
         // Run a prepare first!
         return require('./cordova').raw.prepare([]);
     }).then(function() {
-        launchServer(projectRoot, port);
-        return hooks.fire('after_serve');
+        var server = launchServer(projectRoot, port);
+        hooks.fire('after_serve').then(function () {
+            d.resolve(server);
+        });
     });
+    return d.promise;
 };