Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

New 'stache + handlebars CRUD scaffolding, and tests #395

Merged
merged 6 commits into from

1 participant

This page is out of date. Refresh to see the latest.
View
1  .gitignore
@@ -15,3 +15,4 @@ site/log/*
.log
npm-debug.log
doc/
+test/tmp
View
8 .travis.yml
@@ -2,3 +2,11 @@ language: node_js
node_js:
- "0.10"
- "0.8"
+
+before_script:
+ - rm -R node_modules/model
+ - rm -R node_modules/utilities
+ - npm install https://github.com/mde/model/archive/master.tar.gz
+ - npm install https://github.com/mde/utilities/archive/master.tar.gz
+
+script: node_modules/jake/bin/cli.js test
View
10 Jakefile
@@ -2,6 +2,8 @@
require('./lib/geddy')
var fs = require('fs')
+ , path = require('path')
+ , utils = require('utilities')
, createPackageTask
, JSPAT = /\.js$/
, testTask;
@@ -61,7 +63,7 @@ testTask = new jake.TestTask('Geddy', function () {
});
desc('Run the Geddy tests');
-task('test', function () {
+task('test', ['clean'], function () {
var t = jake.Task.testBase;
t.addListener('error', function (err) {
var module
@@ -89,3 +91,9 @@ task('test', function () {
t.invoke.apply(t, arguments);
}, {async: true});
+desc('Clears the test temp dir');
+task('clean', function () {
+ tmpDir = path.join(__dirname, 'test', 'tmp');
+ utils.file.rmRf(tmpDir, {silent:true});
+ fs.mkdirSync(tmpDir);
+});
View
24 gen/scaffold/views/handlebars/add.html.hbs.ejs
@@ -1,6 +1,22 @@
<div class="hero-unit">
- <h3>Params</h3>
- {{#params}}
- <p>{{action}} action on {{controller}} controller.</p>
- {{/params}}
+ <form id="<%= names.property.singular %>-form" class="form-horizontal" action="/<%= names.filename.plural %>" method="POST">
+ <fieldset>
+ <legend>Create a new <%= names.constructor.singular %></legend>
+ {{#if params.errors }}
+ <div class="control-group">
+ <ul>
+ {{#each params.errors}}
+ <li>{{this}}</li>
+ {{/each}}
+ </ul>
+ </div>
+ {{/if}}
+
+ {{{partial "form" this}}}
+
+ <div class="form-actions">
+ <input type="submit" class="btn btn-primary" value="Add" />
+ </div>
+ </fieldset>
+ </form>
</div>
View
27 gen/scaffold/views/handlebars/edit.html.hbs.ejs
@@ -1,6 +1,23 @@
<div class="hero-unit">
- <h3>Params</h3>
- {{#params}}
- <p>{{action}} action on {{controller}} controller.</p>
- {{/params}}
-</div>
+ <form id="<%= names.property.singular %>-form" class="form-horizontal" action="/<%= names.filename.plural %>/{{params.id}}?_method=PUT" method="POST">
+ <fieldset>
+ <legend>Update this <%= names.constructor.singular %></legend>
+ {{#if params.errors}}
+ <div class="control-group">
+ <ul>
+ {{#each params.errors }}
+ <li>{{this}}</li>
+ {{/each}}
+ </ul>
+ </div>
+ {{/if}}
+
+ {{{partial "form" this}}}
+
+ <div class="form-actions">
+ <input type="submit" class="btn btn-primary" value="Save" />
+ <input type="submit" class="btn btn-danger" value="Delete" formaction="/<%= names.filename.plural %>/{{params.id}}?_method=DELETE" />
+ </div>
+ </fieldset>
+ </form>
+</div>
View
36 gen/scaffold/views/handlebars/form.html.hbs.ejs
@@ -0,0 +1,36 @@
+ <% for(var i in properties) { -%>
+ <% if(properties[i].name && properties[i].name !== 'id') { -%>
+ <div class="control-group">
+ <label for="<%= properties[i].name %>" class="control-label"><%= properties[i].name %></label>
+ <div class="controls">
+ <% if(properties[i].type === 'string') { -%>
+ <% if(properties[i].name === 'password') { -%>
+ <input type="password" class="span6" name="<%= properties[i].name %>" value="{{<%= names.property.singular %>.<%= properties[i].name %>}}" />
+ <% } else { -%>
+ <input type="text" class="span6" name="<%= properties[i].name %>" value="{{<%= names.property.singular %>.<%= properties[i].name %>}}" />
+ <% } -%>
+ <% } else if(properties[i].type === 'text') { -%>
+ <textarea rows="10" class="span6" name="<%= properties[i].name %>"></textarea>
+ <% } else if(properties[i].type === 'number' || properties[i].type === 'int') { -%>
+ <input type="number" class="span2" name="<%= properties[i].name %>" value="{{<%= names.property.singular %>.<%= properties[i].name %>}}" />
+ <% } else if(properties[i].type === 'boolean') { -%>
+ <select name="<%= properties[i].name %>", class="span1">
+ {% if <%= names.property.singular %>.<%= properties[i].name %> %}
+ <option>false</option>
+ <option selected>true</option>
+ {% else %}
+ <option selected>false</option>
+ <option>true</option>
+ {% endif %}
+ </select>
+ <% } else if(properties[i].type === 'datetime') { -%>
+ <input type="datetime" class="span3" name="<%= properties[i].name %>" value="{{<%= names.property.singular %>.<%= properties[i].name %>}}" />
+ <% } else if(properties[i].type === 'date') { -%>
+ <input type="date" class="span2" name="<%= properties[i].name %>" value="{{<%= names.property.singular %>.<%= properties[i].name %>}}" />
+ <% } else { -%>
+ <%= properties[i].type %>
+ <% } -%>
+ </div>
+ </div>
+ <% } -%>
+ <% } -%>
View
19 gen/scaffold/views/handlebars/index.html.hbs.ejs
@@ -1,6 +1,17 @@
<div class="hero-unit">
- <h3>Params</h3>
- {{#params}}
- <p>{{action}} action on {{controller}} controller.</p>
- {{/params}}
+ <h2>All <%= names.constructor.plural %></h2>
+ <a href="/<%= names.property.plural %>/add" class="btn pull-right">Create a new <%= names.constructor.singular %></a>
+</div>
+
+<div id="<%= names.property.plural %>-list">
+{{#each <%= names.property.plural %> }}
+ <div class="row list-item" id="<%= names.property.singular %>-{{id}}">
+ <div class="span8">
+ <h3><a href="/<%= names.property.plural %>/{{id}}">{{id}}</a></h3>
+ </div>
+ <div class="span4">
+ <h3><i class="icon-list-alt"></i>{{id}}</h3>
+ </div>
+ </div>
+{{/each}}
</div>
View
18 gen/scaffold/views/handlebars/show.html.hbs.ejs
@@ -1,6 +1,16 @@
<div class="hero-unit">
- <h3>Params</h3>
- {{#params}}
- <p>{{action}} action on {{controller}} controller.</p>
- {{/params}}
+ <h2 class="<%= properties['default'].name || "id" %>">{{ <%= names.property.singular %>.<%= properties['default'].name || "id" %> }}</h2>
+ <a href="/<%= names.property.plural %>/{{params.id}}/edit" class="btn pull-right">Edit this <%= names.property.singular %></a>
</div>
+
+<h2><%= names.constructor.singular %> Properties</h2>
+{{#each <%= names.property.singular %> }}
+<div class="row list-item">
+ <div class="span4">
+ <h3>{{@key}}</h3>
+ </div>
+ <div class="span8">
+ <h3><i class="icon-list-alt"></i><span class="{{ @key }}">{{ this }}</span></h3>
+ </div>
+</div>
+{{/each}}
View
22 gen/scaffold/views/mustache/add.html.ms.ejs
@@ -1,6 +1,20 @@
<div class="hero-unit">
- <h3>Params</h3>
- {{#params}}
- <p>{{action}} action on {{controller}} controller.</p>
- {{/params}}
+ <form id="<%= names.property.singular %>-form" class="form-horizontal" action="/<%= names.filename.plural %>" method="POST">
+ <fieldset>
+ <legend>Create a new <%= names.constructor.singular %></legend>
+ <div class="control-group">
+ <ul>
+ {{#params.errors}}
+ <li>{{.}}</li>
+ {{/params.errors}}
+ </ul>
+ </div>
+
+ {{{partial "form" this}}}
+
+ <div class="form-actions">
+ <input type="submit" class="btn btn-primary" value="Add" />
+ </div>
+ </fieldset>
+ </form>
</div>
View
25 gen/scaffold/views/mustache/edit.html.ms.ejs
@@ -1,6 +1,21 @@
<div class="hero-unit">
- <h3>Params</h3>
- {{#params}}
- <p>{{action}} action on {{controller}} controller.</p>
- {{/params}}
-</div>
+ <form id="<%= names.property.singular %>-form" class="form-horizontal" action="/<%= names.filename.plural %>/{{params.id}}?_method=PUT" method="POST">
+ <fieldset>
+ <legend>Update this <%= names.constructor.singular %></legend>
+ <div class="control-group">
+ <ul>
+ {{#params.errors}}
+ <li>{{.}}</li>
+ {{/params.errors}}
+ </ul>
+ </div>
+
+ {{{partial "form" this}}}
+
+ <div class="form-actions">
+ <input type="submit" class="btn btn-primary" value="Save" />
+ <input type="submit" class="btn btn-danger" value="Delete" formaction="/<%= names.filename.plural %>/{{params.id}}?_method=DELETE" />
+ </div>
+ </fieldset>
+ </form>
+</div>
View
36 gen/scaffold/views/mustache/form.html.ms.ejs
@@ -0,0 +1,36 @@
+ <% for(var i in properties) { -%>
+ <% if(properties[i].name && properties[i].name !== 'id') { -%>
+ <div class="control-group">
+ <label for="<%= properties[i].name %>" class="control-label"><%= properties[i].name %></label>
+ <div class="controls">
+ <% if(properties[i].type === 'string') { -%>
+ <% if(properties[i].name === 'password') { -%>
+ <input type="password" class="span6" name="<%= properties[i].name %>" value="{{<%= names.property.singular %>.<%= properties[i].name %>}}" />
+ <% } else { -%>
+ <input type="text" class="span6" name="<%= properties[i].name %>" value="{{<%= names.property.singular %>.<%= properties[i].name %>}}" />
+ <% } -%>
+ <% } else if(properties[i].type === 'text') { -%>
+ <textarea rows="10" class="span6" name="<%= properties[i].name %>"></textarea>
+ <% } else if(properties[i].type === 'number' || properties[i].type === 'int') { -%>
+ <input type="number" class="span2" name="<%= properties[i].name %>" value="{{<%= names.property.singular %>.<%= properties[i].name %>}}" />
+ <% } else if(properties[i].type === 'boolean') { -%>
+ <select name="<%= properties[i].name %>", class="span1">
+ {% if <%= names.property.singular %>.<%= properties[i].name %> %}
+ <option>false</option>
+ <option selected>true</option>
+ {% else %}
+ <option selected>false</option>
+ <option>true</option>
+ {% endif %}
+ </select>
+ <% } else if(properties[i].type === 'datetime') { -%>
+ <input type="datetime" class="span3" name="<%= properties[i].name %>" value="{{<%= names.property.singular %>.<%= properties[i].name %>}}" />
+ <% } else if(properties[i].type === 'date') { -%>
+ <input type="date" class="span2" name="<%= properties[i].name %>" value="{{<%= names.property.singular %>.<%= properties[i].name %>}}" />
+ <% } else { -%>
+ <%= properties[i].type %>
+ <% } -%>
+ </div>
+ </div>
+ <% } -%>
+ <% } -%>
View
19 gen/scaffold/views/mustache/index.html.ms.ejs
@@ -1,6 +1,17 @@
<div class="hero-unit">
- <h3>Params</h3>
- {{#params}}
- <p>{{action}} action on {{controller}} controller.</p>
- {{/params}}
+ <h2>All <%= names.constructor.plural %></h2>
+ <a href="/<%= names.property.plural %>/add" class="btn pull-right">Create a new <%= names.constructor.singular %></a>
+</div>
+
+<div id="<%= names.property.plural %>-list">
+{{#<%= names.property.plural %>}}
+ <div class="row list-item" id="<%= names.property.singular %>-{{id}}">
+ <div class="span8">
+ <h3><a href="/<%= names.property.plural %>/{{id}}">{{id}}</a></h3>
+ </div>
+ <div class="span4">
+ <h3><i class="icon-list-alt"></i>{{id}}</h3>
+ </div>
+ </div>
+{{/<%= names.property.plural %>}}
</div>
View
19 gen/scaffold/views/mustache/show.html.ms.ejs
@@ -1,6 +1,17 @@
<div class="hero-unit">
- <h3>Params</h3>
- {{#params}}
- <p>{{action}} action on {{controller}} controller.</p>
- {{/params}}
+ <h2 class="<%= properties['default'].name || "id" %>">{{ <%= names.property.singular %>.<%= properties['default'].name || "id" %> }}</h2>
+ <a href="/<%= names.property.plural %>/{{params.id}}/edit" class="btn pull-right">Edit this <%= names.property.singular %></a>
</div>
+
+<h2><%= names.constructor.singular %> Properties</h2>
+<% for(var i in properties) { -%>
+ <div class="row list-item">
+ <div class="span4">
+ <h3><%= properties[i].name %></h3>
+ </div>
+ <div class="span8">
+ <h3><i class="icon-list-alt"></i>
+ <span class="<%= properties[i].name %>"><% if(properties[i].name === 'id') { %>{{ params.id }}<% } else { %>{{ <%= names.property.singular %>.<%= properties[i].name %> }}<% } %></span></h3>
+ </div>
+ </div>
+<% } -%>
View
2  gen/scaffold/views/swig/show.html.swig.ejs
@@ -10,7 +10,7 @@
<h3>{{loop.key}}</h3>
</div>
<div class="span8">
- <h3><i class="icon-list-alt"></i><span class="">{{ prop }}</span></h3>
+ <h3><i class="icon-list-alt"></i><span class="{{ loop.key }}">{{ prop }}</span></h3>
</div>
</div>
{% endfor %}
View
6 package.json
@@ -31,7 +31,11 @@
"preferGlobal": true,
"devDependencies": {
"browserify": "1.16.x",
- "socket.io-client": "0.9.x"
+ "socket.io-client": "0.9.x",
+ "handlebars": "latest",
+ "jade": "latest",
+ "swig": "latest",
+ "ejs": "latest"
},
"engines": {
"node": "*"
View
2  test/cmd.js → test/cli/cmd.js
@@ -1,5 +1,5 @@
var assert = require('assert')
- , cmd = require('../lib/cmd')
+ , cmd = require('../../lib/cmd')
, Cmd = cmd.Cmd
, tests;
View
365 test/scaffolding/standard.js
@@ -0,0 +1,365 @@
+(function () {
+ var utils = require('utilities')
+ , assert = require('assert')
+ , request = require('request')
+ , path = require('path')
+ , fs = require('fs')
+ , cmd = require('../../lib/cmd').Cmd
+ , geddyCli = path.join(__dirname,'../','../','bin','cli')+'.js'
+ , tmpDir = path.join(__dirname, '../', 'tmp')
+ , staticId = utils.string.uuid(10)
+ , engines = {
+ ejs: null
+ , jade: '-j'
+ , swig: '-s'
+ , handlebars: '-H'
+ , mustache: '-m'
+ }
+ /*
+ * Runs `geddy gen app` with the specified template engine
+ */
+ , scaffoldApp = function (engine, flag, cb) {
+ var spawn = require('child_process').spawn
+ , testDir = tmpDir
+ , cmd = geddyCli
+ , opts = ['gen', 'app', engine + 'App']
+ , srcModules = path.join(__dirname, '..', '..', 'node_modules')
+ , appDir = path.join(testDir, engine + 'App')
+ , proc;
+
+ if(flag) {
+ opts.push(flag);
+ }
+
+ proc = spawn(cmd, opts, {cwd:testDir});
+
+ proc.stderr.setEncoding('utf8');
+
+ proc.stderr.on('data', function (data) {
+ console.error(data);
+ if (/^execvp\(\)/.test(data)) {
+ assert.ok(false, 'Failed to generate scaffolding for ' + engine);
+ }
+ });
+
+ proc.on('close', function (code) {
+ // Create a copy of node_modules so the generated apps don't need to
+ // do an `npm install`
+ utils.file.cpR(srcModules, appDir, {silent: true});
+ cb();
+ });
+ }
+ /*
+ * Runs `geddy gen scaffold zoobies foo:string bar:number`
+ * with the specified template engine
+ */
+ , scaffoldResource = function (engine, flag, cb) {
+ var spawn = require('child_process').spawn
+ , testAppDir = path.join(tmpDir, engine + 'App')
+ , cmd = geddyCli
+ , opts = ['gen', 'scaffold']
+ , proc;
+
+ if(flag) {
+ opts.push(flag);
+ }
+
+ opts = opts.concat(['zoobies', 'foo:string', 'bar:number']);
+
+ proc = spawn(cmd, opts, {cwd:testAppDir});
+
+ proc.stderr.setEncoding('utf8');
+
+ proc.stderr.on('data', function (data) {
+ console.error(data);
+ if (/^execvp\(\)/.test(data)) {
+ assert.ok(false, 'Failed to generate scaffolding for ' + engine);
+ }
+ });
+
+ proc.on('close', function (code) {
+ cb();
+ });
+ }
+ /*
+ * Starts a geddy server
+ */
+ , startServer = function (engine, port, cb) {
+ var spawn = require('child_process').spawn
+ , testAppDir = path.join(tmpDir, engine + 'App')
+ , cmd = geddyCli
+ , opts = ['--port', port]
+ , server
+ , notified = false
+ , failed = false;
+
+ server = spawn(cmd, opts, {cwd:testAppDir});
+
+ server.stderr.setEncoding('utf8');
+
+ server.stderr.on('data', function (data) {
+ console.log(data);
+ });
+
+ console.log("Starting " + engine + " app on port " + port);
+
+ server.stdout.on('data', function (data) {
+ var ready = data.toString().match(/Server worker running in [a-z]+? on port [0-9]+? with a PID of: [0-9]+?/)?true:false;
+
+ if(!notified && ready) {
+ notified = true;
+ cb(server);
+ }
+ });
+ }
+ /*
+ * Kills a geddy server
+ */
+ , killServer = function (server, cb) {
+ server.on('close', function (code) {
+ cb();
+ });
+
+ server.kill("SIGHUP");
+ }
+ , tests = {}
+ , servers = []
+ , port = 8080
+ , base = 'http://127.0.0.1:'
+ , baseUrl
+ , reqOpts = {
+ timeout: 1000
+ };
+
+ /*
+ * CRUD Tests
+ */
+ for(var engine in engines) {
+ (function (baseUrl) {
+ tests["test " + engine + " shows site index"] = function(next) {
+ //Request index
+ request(baseUrl, reqOpts, function(err, res, body) {
+ assert.strictEqual(err, null, err);
+ assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when requesting ' + baseUrl);
+ assert.notStrictEqual(body.match(/Hello, World!/), null, 'Hello world text is missing')
+ next();
+ });
+ };
+
+ tests["test " + engine + " index when empty"] = function(next) {
+ //Request index
+ request(baseUrl + '/zoobies', reqOpts, function(err, res, body) {
+ assert.strictEqual(err, null, err);
+ assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when requesting /zoobies: ' + body);
+ assert.notStrictEqual(body.match(/<div id="zoobies-list">\s*<\/div>/gi), null, 'There should be an empty zoobies list')
+ next();
+ });
+ };
+
+ tests["test " + engine + " create entry"] = function(next) {
+ //Request index
+ request({
+ method: 'POST'
+ , uri: baseUrl + '/zoobies'
+ , form: {
+ foo: 'zerb'
+ , bar: '2112'
+ , id: staticId // Just use a static ID to keep tests cleaner
+ }
+ , timeout: 1000
+ , followAllRedirects: true
+ }
+ , function(err, res, body) {
+ assert.strictEqual(err, null, err);
+ assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when creating zoobies');
+ assert.notStrictEqual(body.match(/id="zooby-[a-z0-9\-]+"/gi), null, 'There should be a zooby in the list')
+ assert.strictEqual(body.match(/id="zooby-[a-z0-9\-]+"/gi).length, 1, 'There should be exactly one zooby in the list')
+ assert.strictEqual(body.indexOf('id="zooby-' + staticId + '"')>=0, true, 'The zooby should have the expected ID')
+ next();
+ });
+ };
+
+ tests["test " + engine + " show initial values"] = function(next) {
+ //Request index
+ request({
+ method: 'GET'
+ , uri: baseUrl + '/zoobies/' + staticId
+ , timeout: 1000
+ }
+ , function(err, res, body) {
+ assert.strictEqual(err, null, err);
+ assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when showing zoobies');
+ assert.strictEqual(body.indexOf('<span class="foo">zerb</span>') >= 0 , true , 'Foo was persisted correctly')
+ assert.strictEqual(body.indexOf('<span class="bar">2112</span>') >= 0 , true , 'Bar was persisted correctly')
+ next();
+ });
+ };
+
+ tests["test " + engine + " update form persists values"] = function(next) {
+ //Request index
+ request({
+ method: 'GET'
+ , uri: baseUrl + '/zoobies/' + staticId + '/edit'
+ , timeout: 1000
+ }
+ , function(err, res, body) {
+ assert.strictEqual(err, null, err);
+ assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when updating zooby');
+
+ // FIXME: Is there a less stupid way of asserting this?
+
+ assert.strictEqual(
+ body.indexOf('input type="text" class="span6" name="foo" value="zerb"') >= 0 // ms
+ ||body.indexOf('input class="span6" name="foo" type="text" value="zerb"') >= 0 // ejs
+ , true , 'Foo was persisted correctly')
+
+ assert.strictEqual(
+ body.indexOf('input type="number" class="span2" name="bar" value="2112"') >= 0 // ms
+ ||body.indexOf('input class="span2" name="bar" type="number" value="2112"') >= 0 // ejs
+ , true , 'Bar was persisted correctly')
+
+ next();
+ });
+ };
+
+ tests["test " + engine + " update values"] = function(next) {
+ //Request index
+ request({
+ method: 'PUT'
+ , uri: baseUrl + '/zoobies/' + staticId
+ , form: {
+ foo: 'overture'
+ , bar: '1984'
+ }
+ , timeout: 1000
+ , followAllRedirects: true
+ }
+ , function(err, res, body) {
+ assert.strictEqual(err, null, err);
+ assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when updating zooby');
+ assert.notStrictEqual(body.match(/id="zooby-[a-z0-9\-]+"/gi), null, 'There should be a zooby in the list')
+ assert.strictEqual(body.match(/id="zooby-[a-z0-9\-]+"/gi).length, 1, 'There should be exactly one zooby in the list')
+ assert.strictEqual(body.indexOf('id="zooby-' + staticId + '"')>=0, true, 'The zooby should have the expected ID')
+ next();
+ });
+ };
+
+ tests["test " + engine + " show updated values"] = function(next) {
+ //Request index
+ request({
+ method: 'GET'
+ , uri: baseUrl + '/zoobies/' + staticId
+ , timeout: 1000
+ }
+ , function(err, res, body) {
+ assert.strictEqual(err, null, err);
+ assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when showing zoobies');
+ assert.strictEqual(body.indexOf('<span class="foo">overture</span>') >= 0 , true , 'Foo was updated correctly')
+ assert.strictEqual(body.indexOf('<span class="bar">1984</span>') >= 0 , true , 'Bar was updated correctly')
+ next();
+ });
+ };
+
+ tests["test " + engine + " delete entry"] = function(next) {
+ //Request index
+ request({
+ method: 'DELETE'
+ , uri: baseUrl + '/zoobies/' + staticId
+ , timeout: 1000
+ , followAllRedirects: true
+ }
+ , function(err, res, body) {
+ assert.strictEqual(err, null, err);
+ assert.strictEqual(res.statusCode, 200, 'Error '+res.statusCode+' when deleting zooby');
+ assert.strictEqual(body.match(/id="zooby-[a-z0-9\-]+"/gi), null, 'There should be no zoobies in the list')
+ next();
+ });
+ };
+
+ tests["test " + engine + " 404"] = function(next) {
+ //Request index
+ request({
+ method: 'GET'
+ , uri: baseUrl + '/zoobies/' + staticId
+ , timeout: 1000
+ }
+ , function(err, res, body) {
+ assert.strictEqual(err, null, err);
+ assert.strictEqual(res.statusCode, 404, 'Should get error 404 viewing nonexistant zooby');
+ next();
+ });
+ };
+
+ }(base + port));
+
+ // Increment Port Number
+ port++;
+ }
+
+ /*
+ * The before action will generate the scaffolded apps
+ */
+ tests.before = function (next) {
+ var generators = []
+ , chain
+ , port = 8080;
+
+ // Generate a new app for each engine
+ for(var engine in engines) {
+ (function (serverPort) {
+ generators.push({
+ func: scaffoldApp
+ , args: [engine, engines[engine]]
+ , callback: null
+ });
+ generators.push({
+ func: scaffoldResource
+ , args: [engine, engines[engine]]
+ , callback: null
+ });
+ generators.push({
+ func: startServer
+ , args: [engine, serverPort]
+ , callback: function (server) {
+ servers.push(server);
+ }
+ });
+ }(port));
+
+ // Increment port number
+ port++;
+ }
+
+ chain = new utils.async.AsyncChain(generators);
+
+ chain.last = next;
+
+ chain.run();
+ };
+
+ /*
+ * The after action cleans the temporary directory
+ */
+ tests.after = function (next) {
+ //Kill all the servers
+ var killers = [];
+ for(var key in servers) {
+ killers.push({
+ func: killServer
+ , args: [servers[key]]
+ , callback: null
+ });
+ }
+
+ chain = new utils.async.AsyncChain(killers);
+
+ chain.last = function () {
+ //utils.file.rmRf(tmpDir, {silent:true});
+ next();
+ };
+
+ chain.run();
+ };
+
+ module.exports = tests;
+}());
Something went wrong with that request. Please try again.