├── .gitignore ├── README.md └── code-examples ├── .gitignore ├── code-sharing ├── browserbuild │ ├── basic │ │ ├── a.js │ │ ├── b.js │ │ └── dist │ │ │ └── hello.js │ └── nodeonly │ │ ├── dist │ │ └── nodeonly.js │ │ └── nodeonly.js ├── exposing-modules │ └── add.js └── inheritance │ └── inherits.js ├── connect ├── basic-auth │ ├── package.json │ └── server.js ├── body-parser │ ├── Hello.txt │ ├── package.json │ ├── server.js │ └── static │ │ └── index.html ├── introduction │ ├── connect │ │ ├── package.json │ │ ├── server.js │ │ └── website │ │ │ ├── images │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── 3.jpg │ │ │ ├── 4.jpg │ │ │ └── LICENSE │ │ │ └── index.html │ └── http │ │ ├── images │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ └── LICENSE │ │ ├── index.html │ │ └── server.js ├── logger │ ├── package.json │ ├── server.js │ └── website │ │ ├── images │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ └── LICENSE │ │ └── index.html ├── method-override │ ├── package.json │ ├── server-swapped.js │ └── server.js ├── own-middleware │ ├── package.json │ ├── request-time.js │ └── server.js └── session │ ├── package.json │ ├── server.js │ └── users.json ├── express └── simple-app │ ├── step-1 │ └── package.json │ ├── step-2 │ └── views │ │ ├── index.ejs │ │ └── search.ejs │ ├── step-3 │ ├── server.js │ └── views │ │ ├── index.ejs │ │ └── search.ejs │ ├── step-4 │ ├── server.js │ └── views │ │ ├── index.ejs │ │ └── search.ejs │ └── step-5 │ ├── search.js │ ├── server.js │ └── views │ ├── index.ejs │ └── search.ejs ├── file-explorer ├── argv │ ├── example-2.js │ └── example.js ├── package.json ├── step-1 │ ├── npm-debug.log │ └── package.json ├── step-2 │ ├── index.js │ └── package.json ├── step-3 │ ├── example-1.js │ └── example-2.js ├── step-4 │ ├── index.js │ └── package.json ├── step-5 │ ├── index.js │ └── package.json └── step-6 │ ├── index.js │ ├── package.json │ └── test │ ├── a.txt │ └── b.txt ├── http ├── example-1 │ └── server.js ├── example-2 │ └── server.js ├── example-3 │ └── server.js ├── example-4 │ └── server.js ├── form-processor │ ├── step-1 │ │ └── package.json │ ├── step-2 │ │ ├── package.json │ │ └── server.js │ ├── step-3 │ │ ├── package.json │ │ └── server.js │ ├── step-4 │ │ ├── package.json │ │ ├── qs-example.js │ │ └── server.js │ ├── step-5 │ │ ├── package.json │ │ └── server.js │ └── step-6 │ │ ├── package.json │ │ └── server.js └── tweets │ ├── step-1 │ └── package.json │ ├── step-2 │ ├── client.js │ ├── package.json │ └── server.js │ ├── step-3 │ ├── client.js │ ├── package.json │ └── server.js │ └── step-4 │ └── tweets.js ├── introduction ├── index.js └── my-web-server.js ├── io ├── timeouts.js └── uncaught-http.js ├── mongodb ├── auth │ ├── step-1 │ │ └── package.json │ ├── step-2 │ │ ├── package.json │ │ ├── server.js │ │ └── views │ │ │ ├── index.jade │ │ │ ├── layout.jade │ │ │ ├── login.jade │ │ │ └── signup.jade │ ├── step-3 │ │ ├── package.json │ │ ├── server.js │ │ └── views │ │ │ ├── index.jade │ │ │ ├── layout.jade │ │ │ ├── login.jade │ │ │ └── signup.jade │ ├── step-4 │ │ ├── package.json │ │ ├── server.js │ │ └── views │ │ │ ├── index.jade │ │ │ ├── layout.jade │ │ │ ├── login.jade │ │ │ └── signup.jade │ ├── step-5 │ │ ├── package.json │ │ ├── server.js │ │ └── views │ │ │ ├── index.jade │ │ │ ├── layout.jade │ │ │ ├── login.jade │ │ │ └── signup.jade │ └── step-6 │ │ ├── package.json │ │ ├── server.js │ │ └── views │ │ ├── index.jade │ │ ├── layout.jade │ │ ├── login.jade │ │ └── signup.jade └── blog │ ├── package.json │ ├── server.js │ ├── step-final │ ├── blogpost.js │ ├── package.json │ └── server.js │ └── views │ ├── index.jade │ ├── layout.jade │ ├── login.jade │ └── signup.jade ├── mysql ├── node-mysql │ ├── step-1 │ │ └── package.json │ ├── step-2 │ │ ├── package.json │ │ └── server.js │ ├── step-3 │ │ ├── package.json │ │ └── server.js │ ├── step-4 │ │ ├── config.json │ │ ├── package.json │ │ ├── server.js │ │ └── setup.js │ ├── step-5 │ │ ├── config.json │ │ ├── package.json │ │ ├── server.js │ │ ├── setup.js │ │ └── views │ │ │ ├── index.jade │ │ │ ├── item.jade │ │ │ └── layout.jade │ └── step-6 │ │ ├── config.json │ │ ├── package.json │ │ ├── server.js │ │ ├── setup.js │ │ └── views │ │ ├── index.jade │ │ ├── item.jade │ │ └── layout.jade └── sequelize │ ├── step-1 │ └── package.json │ ├── step-2 │ ├── package.json │ ├── public │ │ └── js │ │ │ └── main.js │ ├── server.js │ └── views │ │ ├── index.jade │ │ ├── layout.jade │ │ └── tasks.jade │ ├── step-3 │ ├── package.json │ ├── public │ │ └── js │ │ │ └── main.js │ ├── server.js │ └── views │ │ ├── index.jade │ │ ├── layout.jade │ │ └── tasks.jade │ ├── step-4 │ ├── package.json │ ├── public │ │ └── js │ │ │ └── main.js │ ├── server.js │ └── views │ │ ├── index.jade │ │ ├── layout.jade │ │ └── tasks.jade │ └── step-5 │ ├── package.json │ ├── public │ └── js │ │ └── main.js │ ├── server.js │ └── views │ ├── index.jade │ ├── layout.jade │ └── tasks.jade ├── nodejs ├── 1 │ ├── main.js │ ├── module_a.js │ └── module_b.js ├── 2 │ ├── index.js │ └── module_a.js ├── 3 │ ├── index.js │ └── person.js └── 4 │ ├── index.js │ └── logo.png ├── redis ├── social-graph │ ├── step-1 │ │ └── package.json │ ├── step-2 │ │ ├── app.js │ │ └── package.json │ ├── step-3 │ │ ├── app.js │ │ └── package.json │ └── step-4 │ │ ├── model.js │ │ ├── package.json │ │ └── test.js └── test │ ├── model.js │ └── test.js ├── socket.io ├── public │ ├── chat.js │ └── index.html └── server.js ├── tcp ├── chat │ ├── step-1 │ │ ├── index.js │ │ └── package.json │ ├── step-2 │ │ ├── index.js │ │ └── package.json │ ├── step-3 │ │ ├── index.js │ │ └── package.json │ ├── step-4 │ │ ├── index.js │ │ └── package.json │ └── step-5 │ │ ├── index.js │ │ └── package.json ├── introduction │ └── web-server.js └── irc │ └── index.js ├── testing ├── mocha │ ├── bdd │ │ └── bdd.js │ ├── browser │ │ ├── expect.js │ │ ├── index.html │ │ ├── jquery.js │ │ ├── mocha.css │ │ ├── mocha.js │ │ └── my-test.js │ ├── tdd │ │ └── tdd.js │ └── test.js └── simple-testing │ ├── assert-example.js │ └── test-program │ ├── express-app │ ├── search.js │ ├── server.js │ └── views │ │ ├── index.ejs │ │ └── search.ejs │ └── test.js └── websocket ├── cursors ├── step-1 │ └── package.json ├── step-2 │ ├── package.json │ └── server.js └── step-3 │ ├── package.json │ ├── public │ └── index.html │ └── server.js └── echo ├── step-1 └── package.json ├── step-2 ├── package.json └── server.js └── step-3 ├── package.json ├── public ├── cursor.png └── index.html └── server.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | smashingnode 2 | ============ 3 | 4 | Repository for my book "Smashing Node". 5 | It will host: 6 | 7 | - The website http://smashingnode.com 8 | - Code examples 9 | - Interaction area 10 | - and more! -------------------------------------------------------------------------------- /code-examples/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /code-examples/code-sharing/browserbuild/basic/a.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = require('./b')('world'); 3 | -------------------------------------------------------------------------------- /code-examples/code-sharing/browserbuild/basic/b.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function (str) { 3 | return str; 4 | } 5 | -------------------------------------------------------------------------------- /code-examples/code-sharing/browserbuild/basic/dist/hello.js: -------------------------------------------------------------------------------- 1 | (function () { function require(p){ var path = require.resolve(p) , mod = require.modules[path]; if (!mod) throw new Error('failed to require "' + p + '"'); if (!mod.exports) { mod.exports = {}; mod.call(mod.exports, mod, mod.exports, require.relative(path)); } return mod.exports;}require.modules = {};require.resolve = function(path){ var orig = path , reg = path + '.js' , index = path + '/index.js'; return require.modules[reg] && reg || require.modules[index] && index || orig;};require.register = function(path, fn){ require.modules[path] = fn;};require.relative = function(parent) { return function(p){ if ('.' != p.charAt(0)) return require(p); var path = parent.split('/') , segs = p.split('/'); path.pop(); for (var i = 0; i < segs.length; i++) { var seg = segs[i]; if ('..' == seg) path.pop(); else if ('.' != seg) path.push(seg); } return require(path.join('/')); };};require.register("a.js", function(module, exports, require){ 2 | 3 | module.exports = require('./b')('world'); 4 | 5 | });require.register("b.js", function(module, exports, require){ 6 | 7 | module.exports = function (str) { 8 | return str; 9 | } 10 | 11 | });require.register("dist/basic.js", function(module, exports, require){ 12 | (function () { function require(p){ var path = require.resolve(p) , mod = require.modules[path]; if (!mod) throw new Error('failed to require "' + p + '"'); if (!mod.exports) { mod.exports = {}; mod.call(mod.exports, mod, mod.exports, require.relative(path)); } return mod.exports;}require.modules = {};require.resolve = function(path){ var orig = path , reg = path + '.js' , index = path + '/index.js'; return require.modules[reg] && reg || require.modules[index] && index || orig;};require.register = function(path, fn){ require.modules[path] = fn;};require.relative = function(parent) { return function(p){ if ('.' != p.charAt(0)) return require(p); var path = parent.split('/') , segs = p.split('/'); path.pop(); for (var i = 0; i < segs.length; i++) { var seg = segs[i]; if ('..' == seg) path.pop(); else if ('.' != seg) path.push(seg); } return require(path.join('/')); };};require.register("a.js", function(module, exports, require){ 13 | 14 | exports.hello = require('./b')('world'); 15 | 16 | });require.register("b.js", function(module, exports, require){ 17 | 18 | module.exports = function (str) { 19 | return str; 20 | } 21 | 22 | });hello = require('a.js'); 23 | })(); 24 | });hello = require('a.js'); 25 | })(); -------------------------------------------------------------------------------- /code-examples/code-sharing/browserbuild/nodeonly/dist/nodeonly.js: -------------------------------------------------------------------------------- 1 | (function () { function require(p){ var path = require.resolve(p) , mod = require.modules[path]; if (!mod) throw new Error('failed to require "' + p + '"'); if (!mod.exports) { mod.exports = {}; mod.call(mod.exports, mod, mod.exports, require.relative(path)); } return mod.exports;}require.modules = {};require.resolve = function(path){ var orig = path , reg = path + '.js' , index = path + '/index.js'; return require.modules[reg] && reg || require.modules[index] && index || orig;};require.register = function(path, fn){ require.modules[path] = fn;};require.relative = function(parent) { return function(p){ if ('.' != p.charAt(0)) return require(p); var path = parent.split('/') , segs = p.split('/'); path.pop(); for (var i = 0; i < segs.length; i++) { var seg = segs[i]; if ('..' == seg) path.pop(); else if ('.' != seg) path.push(seg); } return require(path.join('/')); };};require.register("nodeonly.js", function(module, exports, require){ 2 | 3 | 4 | 5 | 6 | 7 | console.log('browser and node'); 8 | 9 | });nodeonly = require('nodeonly'); 10 | })(); -------------------------------------------------------------------------------- /code-examples/code-sharing/browserbuild/nodeonly/nodeonly.js: -------------------------------------------------------------------------------- 1 | 2 | // if node 3 | process.exit(1); 4 | // end 5 | 6 | console.log('browser and node'); 7 | -------------------------------------------------------------------------------- /code-examples/code-sharing/exposing-modules/add.js: -------------------------------------------------------------------------------- 1 | (function (module) { 2 | if ('undefined' == typeof module) { 3 | module = { exports: {} }; 4 | } 5 | 6 | module.exports = function (a, b) { 7 | return a + b; 8 | } 9 | 10 | if ('undefined' != typeof window) { 11 | window.add = module.exports; 12 | } 13 | })(module); 14 | -------------------------------------------------------------------------------- /code-examples/code-sharing/inheritance/inherits.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Inheritance utility. 4 | * 5 | * @param {Function} constructor 6 | * @param {Function} constructor we inherit from 7 | * @api private 8 | */ 9 | 10 | function inherits (a, b) { 11 | function c () {}; 12 | c.prototype = b.prototype; 13 | a.prototype = new c; 14 | }; 15 | -------------------------------------------------------------------------------- /code-examples/connect/basic-auth/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "method-override" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "connect": "1.8.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/connect/basic-auth/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var connect = require('connect') 7 | 8 | /** 9 | * Create server 10 | */ 11 | 12 | process.stdin.resume(); 13 | process.stdin.setEncoding('ascii'); 14 | 15 | var server = connect( 16 | connect.basicAuth(function (user, pass, fn) { 17 | process.stdout.write('Allow user \033[96m' + user + '\033[39m ' 18 | + 'with pass \033[90m' + pass + '\033[39m ? [y/n]: '); 19 | process.stdin.once('data', function (data) { 20 | if (data[0] == 'y') { 21 | fn(null, { username: user }); 22 | } 23 | else fn(new Error('Unauthorized')); 24 | }); 25 | }) 26 | , function (req, res) { 27 | res.writeHead(200); 28 | res.end('Welcome to the protected area, ' + req.remoteUser.username); 29 | } 30 | ); 31 | 32 | /** 33 | * Listen 34 | */ 35 | 36 | server.listen(3000); 37 | -------------------------------------------------------------------------------- /code-examples/connect/body-parser/Hello.txt: -------------------------------------------------------------------------------- 1 | This file is Hello.txt 2 | -------------------------------------------------------------------------------- /code-examples/connect/body-parser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "body-parser" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "connect": "1.8.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/connect/body-parser/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module requirements. 4 | */ 5 | 6 | var connect = require('connect') 7 | , fs = require('fs') 8 | 9 | /** 10 | * Create server 11 | */ 12 | 13 | var server = connect( 14 | connect.bodyParser() 15 | , connect.static('static') 16 | , function (req, res, next) { 17 | if ('POST' == req.method && req.body.file) { 18 | fs.readFile(req.body.file.path, 'utf8', function (err, data) { 19 | if (err) { 20 | res.writeHead(500); 21 | res.end('Error!'); 22 | return; 23 | } 24 | 25 | res.writeHead(200, { 'Content-Type': 'text/html' }); 26 | res.end([ 27 | '
' + data + '' 30 | ].join('')); 31 | }); 32 | } else { 33 | next(); 34 | } 35 | } 36 | ); 37 | 38 | /** 39 | * Listen. 40 | */ 41 | 42 | server.listen(3000); 43 | -------------------------------------------------------------------------------- /code-examples/connect/body-parser/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-website" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "connect": "1.8.1" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var connect = require('connect') 7 | 8 | /** 9 | * Create server. 10 | */ 11 | 12 | var server = connect.createServer(); 13 | 14 | /** 15 | * Handle static files. 16 | */ 17 | 18 | server.use(connect.static(__dirname + '/website')); 19 | 20 | /** 21 | * Listen. 22 | */ 23 | 24 | server.listen(3000); 25 | -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/connect/website/images/1.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/connect/website/images/2.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/connect/website/images/3.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/connect/introduction/connect/website/images/4.jpg -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/images/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The images used in this example were released under "CC Attribution 2.0 Generic" 3 | license, and are part of the public domain [1] 4 | 5 | 1.jpg: http://www.flickr.com/photos/fritography/4524444398/ 6 | 2.jpg: http://www.flickr.com/photos/pargon/2461131176/ 7 | 3.jpg: http://www.flickr.com/photos/usnavy/6219970385/ 8 | 4.jpg: http://www.flickr.com/photos/butlerphotography/4201634265/ 9 | 10 | [1] http://creativecommons.org/licenses/by/2.0/deed.en 11 | -------------------------------------------------------------------------------- /code-examples/connect/introduction/connect/website/index.html: -------------------------------------------------------------------------------- 1 | 2 |
Please enter your search term:
5 | 9 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-2/views/search.ejs: -------------------------------------------------------------------------------- 1 | 2 |No results
12 | <% } %> 13 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-3/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module requirements. 4 | */ 5 | 6 | var express = require('express') 7 | , search = require('./search') 8 | 9 | /** 10 | * Create app. 11 | */ 12 | 13 | var app = express.createServer() // NOTE: express3 is express() 14 | 15 | /** 16 | * Configuration 17 | */ 18 | 19 | app.set('view engine', 'ejs'); 20 | app.set('views', __dirname + '/views'); 21 | app.set('view options', { layout: false }); // NOTE: express3 remove 22 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-3/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 |Please enter your search term:
5 | 9 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-3/views/search.ejs: -------------------------------------------------------------------------------- 1 | 2 |No results
12 | <% } %> 13 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-4/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module requirements. 4 | */ 5 | 6 | var express = require('express') 7 | , search = require('./search') 8 | 9 | /** 10 | * Create app. 11 | */ 12 | 13 | var app = express.createServer() // NOTE: express3 is express() 14 | 15 | /** 16 | * Configuration 17 | */ 18 | 19 | app.set('view engine', 'ejs'); 20 | app.set('views', __dirname + '/views'); 21 | app.set('view options', { layout: false }); // NOTE: express3 remove 22 | 23 | /** 24 | * Routes 25 | */ 26 | 27 | app.get('/', function (req, res) { 28 | res.render('index'); 29 | }); 30 | 31 | app.get('/search', function (req, res, next) { 32 | search(req.query.q, function (err, tweets) { 33 | if (err) return next(err); 34 | res.render('search', { results: tweets, search: req.query.q }); 35 | }); 36 | }); 37 | 38 | /** 39 | * Listen 40 | */ 41 | 42 | app.listen(3000); 43 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-4/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 |Please enter your search term:
5 | 9 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-4/views/search.ejs: -------------------------------------------------------------------------------- 1 | 2 |No results
12 | <% } %> 13 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-5/search.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var qs = require('querystring') 7 | , http = require('http') 8 | 9 | /** 10 | * Search function. 11 | * 12 | * @param {String} search query 13 | * @param {Function} callback 14 | * @api public 15 | */ 16 | 17 | module.exports = function search (query, fn) { 18 | http.request({ 19 | host: 'search.twitter.com' 20 | , path: '/search.json?' + qs.stringify({ q: query }) 21 | }, function (res) { 22 | res.setEncoding('utf8'); 23 | 24 | var body = ''; 25 | 26 | res.on('data', function (chunk) { 27 | body += chunk; 28 | }); 29 | 30 | res.on('end', function () { 31 | try { 32 | var obj = JSON.parse(body); 33 | } catch (e) { 34 | return fn(new Error('Bad twitter response')); 35 | } 36 | 37 | fn(null, obj.results); 38 | }); 39 | }).end() 40 | }; 41 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-5/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module requirements. 4 | */ 5 | 6 | var express = require('express') 7 | , search = require('./search') 8 | 9 | /** 10 | * Create app. 11 | */ 12 | 13 | var app = express.createServer(); 14 | 15 | /** 16 | * Configuration 17 | */ 18 | 19 | app.set('view engine', 'ejs'); 20 | app.set('views', __dirname + '/views'); 21 | app.set('view options', { layout: false }); 22 | 23 | /** 24 | * Routes 25 | */ 26 | 27 | app.get('/', function (req, res) { 28 | res.render('index'); 29 | }); 30 | 31 | app.get('/search', function (req, res, next) { 32 | search(req.query.q, function (err, tweets) { 33 | if (err) return next(err); 34 | res.render('search', { results: tweets, search: req.query.q }); 35 | }); 36 | }); 37 | 38 | /** 39 | * Listen 40 | */ 41 | 42 | app.listen(3000); 43 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-5/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 |Please enter your search term:
5 | 9 | -------------------------------------------------------------------------------- /code-examples/express/simple-app/step-5/views/search.ejs: -------------------------------------------------------------------------------- 1 | 2 |No results
12 | <% } %> 13 | -------------------------------------------------------------------------------- /code-examples/file-explorer/argv/example-2.js: -------------------------------------------------------------------------------- 1 | console.log(process.argv.slice(2)); 2 | -------------------------------------------------------------------------------- /code-examples/file-explorer/argv/example.js: -------------------------------------------------------------------------------- 1 | console.log(process.argv); 2 | -------------------------------------------------------------------------------- /code-examples/file-explorer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer" 3 | , "version": "0.0.1" 4 | , "description": "A command-file file explorer!" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-1/npm-debug.log: -------------------------------------------------------------------------------- 1 | info it worked if it ends with ok 2 | verbose cli [ 'node', '/usr/local/bin/npm', 'install' ] 3 | info using npm@1.1.1 4 | info using node@v0.6.13 5 | verbose config file /Users/guillermorauch/.npmrc 6 | verbose config file /usr/local/etc/npmrc 7 | verbose config file /usr/local/lib/node_modules/npm/npmrc 8 | ERR! Couldn't read dependencies. 9 | ERR! Failed to parse json 10 | ERR! Unexpected token ' 11 | ERR! File: /Users/guillermorauch/Projects/book/code-examples/file-explorer/step-1/package.json 12 | ERR! JSON.parse Failed to parse package.json data. 13 | ERR! JSON.parse package.json must be actual JSON, not just JavaScript. 14 | ERR! JSON.parse This is not a bug in npm. 15 | ERR! JSON.parse Tell the package author to fix their package.json file. 16 | ERR! 17 | ERR! System Darwin 12.0.0 18 | ERR! command "node" "/usr/local/bin/npm" "install" 19 | ERR! cwd /Users/guillermorauch/Projects/book/code-examples/file-explorer/step-1 20 | ERR! node -v v0.6.13 21 | ERR! npm -v 1.1.1 22 | ERR! file /Users/guillermorauch/Projects/book/code-examples/file-explorer/step-1/package.json 23 | ERR! code EJSONPARSE 24 | ERR! message Failed to parse json 25 | ERR! message Unexpected token ' 26 | ERR! errno {} 27 | verbose exit [ 1, true ] 28 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | 'name': "file-explorer" 3 | , "version": "0.0.1 4 | , "description": "A command-file file explorer!" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-2/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var fs = require('fs'); 7 | 8 | fs.readdir(__dirname, function (err, files) { 9 | console.log(files); 10 | }); 11 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer" 3 | , "version": "0.0.1" 4 | , "description": "A command-file file explorer!" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-3/example-1.js: -------------------------------------------------------------------------------- 1 | console.log('Hello world'); 2 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-3/example-2.js: -------------------------------------------------------------------------------- 1 | process.stdout.write('Hello world'); 2 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-4/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var fs = require('fs'); 7 | 8 | fs.readdir(__dirname, function (err, files) { 9 | console.log(''); 10 | 11 | if (!files.length) { 12 | return console.log(' \033[31m No files to show!\033[39m\n'); 13 | } 14 | 15 | console.log(' Select which file or directory you want to see\n'); 16 | 17 | function file(i) { 18 | var filename = files[i]; 19 | 20 | fs.stat(__dirname + '/' + filename, function (err, stat) { 21 | if (stat.isDirectory()) { 22 | console.log(' '+i+' \033[36m' + filename + '/\033[39m'); 23 | } else { 24 | console.log(' '+i+' \033[90m' + filename + '\033[39m'); 25 | } 26 | 27 | if (++i == files.length) { 28 | console.log(''); 29 | process.stdout.write(' \033[33mEnter your choice: \033[39m'); 30 | process.stdin.resume(); 31 | process.stdin.setEncoding('utf8'); 32 | } else { 33 | file(i); 34 | } 35 | }); 36 | } 37 | 38 | file(0); 39 | 40 | }); 41 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer" 3 | , "version": "0.0.1" 4 | , "description": "A command-file file explorer!" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-5/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var fs = require('fs') 7 | , stdin = process.stdin 8 | , stdout = process.stdout 9 | 10 | /** 11 | * Read the current directory. 12 | */ 13 | 14 | fs.readdir(__dirname, function (err, files) { 15 | console.log(''); 16 | 17 | if (!files.length) { 18 | return console.log(' \033[31m No files to show!\033[39m\n'); 19 | } 20 | 21 | console.log(' Select which file or directory you want to see\n'); 22 | 23 | // called for each file walked in the directory 24 | function file(i) { 25 | var filename = files[i]; 26 | 27 | fs.stat(__dirname + '/' + filename, function (err, stat) { 28 | if (stat.isDirectory()) { 29 | console.log(' '+i+' \033[36m' + filename + '/\033[39m'); 30 | } else { 31 | console.log(' '+i+' \033[90m' + filename + '\033[39m'); 32 | } 33 | 34 | if (++i == files.length) { 35 | read(); 36 | } else { 37 | file(i); 38 | } 39 | }); 40 | } 41 | 42 | // read user input when files are shown 43 | function read () { 44 | console.log(''); 45 | stdout.write(' \033[33mEnter your choice: \033[39m'); 46 | 47 | stdin.resume(); 48 | stdin.setEncoding('utf8'); 49 | stdin.on('data', option); 50 | } 51 | 52 | // called with the option supplied by the user 53 | function option (data) { 54 | if (!files[Number(data)]) { 55 | stdout.write(' \033[31mEnter your choice: \033[39m'); 56 | } else { 57 | stdin.removeListener('data', option); 58 | } 59 | } 60 | 61 | // start by walking the first file 62 | file(0); 63 | }); 64 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer" 3 | , "version": "0.0.1" 4 | , "description": "A command-file file explorer!" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-6/index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var fs = require('fs') 7 | , stdin = process.stdin 8 | , stdout = process.stdout 9 | 10 | /** 11 | * Read the current directory. 12 | */ 13 | 14 | fs.readdir(__dirname, function (err, files) { 15 | console.log(''); 16 | 17 | if (!files.length) { 18 | return console.log(' \033[31m No files to show!\033[39m\n'); 19 | } 20 | 21 | console.log(' Select which file or directory you want to see\n'); 22 | 23 | // called for each file walked in the directory 24 | var stats = {}; 25 | 26 | function file(i) { 27 | var filename = files[i]; 28 | 29 | fs.stat(__dirname + '/' + filename, function (err, stat) { 30 | stats[i] = stat; 31 | 32 | if (stat.isDirectory()) { 33 | console.log(' '+i+' \033[36m' + filename + '/\033[39m'); 34 | } else { 35 | console.log(' '+i+' \033[90m' + filename + '\033[39m'); 36 | } 37 | 38 | if (++i == files.length) { 39 | read(); 40 | } else { 41 | file(i); 42 | } 43 | }); 44 | } 45 | 46 | // read user input when files are shown 47 | function read () { 48 | console.log(''); 49 | stdout.write(' \033[33mEnter your choice: \033[39m'); 50 | 51 | stdin.resume(); 52 | stdin.setEncoding('utf8'); 53 | stdin.on('data', option); 54 | } 55 | 56 | // called with the option supplied by the user 57 | function option (data) { 58 | var filename = files[Number(data)]; 59 | if (!filename) { 60 | stdout.write(' \033[31mEnter your choice: \033[39m'); 61 | } else { 62 | stdin.pause(); 63 | 64 | if (stats[Number(data)].isDirectory()) { 65 | fs.readdir(__dirname + '/' + filename, function (err, files) { 66 | console.log(''); 67 | console.log(' (' + files.length + ' files)'); 68 | files.forEach(function (file) { 69 | console.log(' - ' + file); 70 | }); 71 | console.log(''); 72 | }); 73 | } else { 74 | fs.readFile(__dirname + '/' + filename, 'utf8', function (err, data) { 75 | console.log(''); 76 | console.log('\033[90m' + data.replace(/(.*)/g, ' $1') + '\033[39m'); 77 | }); 78 | } 79 | } 80 | } 81 | 82 | // start by walking the first file 83 | file(0); 84 | }); 85 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-explorer" 3 | , "version": "0.0.1" 4 | , "description": "A command-file file explorer!" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/file-explorer/step-6/test/a.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/file-explorer/step-6/test/a.txt -------------------------------------------------------------------------------- /code-examples/file-explorer/step-6/test/b.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/smashingnode/3ca42801b584bcb9f210ad13f42e58c5cf75dc67/code-examples/file-explorer/step-6/test/b.txt -------------------------------------------------------------------------------- /code-examples/http/example-1/server.js: -------------------------------------------------------------------------------- 1 | require('http').createServer(function (req, res) { 2 | res.writeHead(200); 3 | res.end('Hello World'); 4 | }).listen(3000); 5 | -------------------------------------------------------------------------------- /code-examples/http/example-2/server.js: -------------------------------------------------------------------------------- 1 | require('http').createServer(function (req, res) { 2 | res.writeHead(200); 3 | res.end('Hello World'); 4 | }).listen(3000); 5 | -------------------------------------------------------------------------------- /code-examples/http/example-3/server.js: -------------------------------------------------------------------------------- 1 | 2 | require('http').createServer(function (req, res) { 3 | res.writeHead(200, { 'Content-Type': 'text/html' }); 4 | res.end('Hello World'); 5 | }).listen(3000); 6 | -------------------------------------------------------------------------------- /code-examples/http/example-4/server.js: -------------------------------------------------------------------------------- 1 | 2 | require('http').createServer(function (req, res) { 3 | console.log(req.headers); 4 | res.writeHead(200, { 'Content-Type': 'text/html' }); 5 | res.end('Hello World'); 6 | }).listen(3000); 7 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-form" 3 | , "description": "An HTTP server that processes forms" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-form" 3 | , "description": "An HTTP server that processes forms" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-2/server.js: -------------------------------------------------------------------------------- 1 | 2 | require('http').createServer(function (req, res) { 3 | res.writeHead(200, { 'Content-Type': 'text/html' }); 4 | res.end([ 5 | '' 13 | ].join('')); 14 | }).listen(3000); 15 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-form" 3 | , "description": "An HTTP server that processes forms" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-3/server.js: -------------------------------------------------------------------------------- 1 | 2 | require('http').createServer(function (req, res) { 3 | if ('/' == req.url) { 4 | res.writeHead(200, { 'Content-Type': 'text/html' }); 5 | res.end([ 6 | '' 14 | ].join('')); 15 | } else if ('/url' == req.url) { 16 | res.writeHead(200, { 'Content-Type': 'text/html' }); 17 | res.end('You sent a ' + req.method + ' request'); 18 | } 19 | }).listen(3000); 20 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-form" 3 | , "description": "An HTTP server that processes forms" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-4/qs-example.js: -------------------------------------------------------------------------------- 1 | 2 | console.log(require('querystring').parse('name=Guillermo')); 3 | console.log(require('querystring').parse('q=guillermo+rauch')); 4 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-4/server.js: -------------------------------------------------------------------------------- 1 | 2 | require('http').createServer(function (req, res) { 3 | if ('/' == req.url) { 4 | res.writeHead(200, { 'Content-Type': 'text/html' }); 5 | res.end([ 6 | '' 14 | ].join('')); 15 | } else if ('/url' == req.url && 'POST' == req.method) { 16 | var body = ''; 17 | 18 | req.on('data', function (chunk) { 19 | body += chunk; 20 | }); 21 | 22 | req.on('end', function () { 23 | res.writeHead(200, { 'Content-Type': 'text/html' }); 24 | res.end('Content-Type: ' + req.headers['content-type'] + '
' 25 | + 'Data:
' + body + ''); 26 | }); 27 | } 28 | }).listen(3000); 29 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-form" 3 | , "description": "An HTTP server that processes forms" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-5/server.js: -------------------------------------------------------------------------------- 1 | 2 | var qs = require('querystring'); 3 | 4 | require('http').createServer(function (req, res) { 5 | if ('/' == req.url) { 6 | res.writeHead(200, { 'Content-Type': 'text/html' }); 7 | res.end([ 8 | '' 16 | ].join('')); 17 | } else if ('/url' == req.url && 'POST' == req.method) { 18 | var body = ''; 19 | 20 | req.on('data', function (chunk) { 21 | body += chunk; 22 | }); 23 | 24 | req.on('end', function () { 25 | res.writeHead(200, { 'Content-Type': 'text/html' }); 26 | res.end('
Your name is ' + qs.parse(body).name + '
'); 27 | }); 28 | } 29 | }).listen(3000); 30 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "http-form" 3 | , "description": "An HTTP server that processes forms" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/form-processor/step-6/server.js: -------------------------------------------------------------------------------- 1 | 2 | var qs = require('querystring'); 3 | 4 | require('http').createServer(function (req, res) { 5 | if ('/' == req.url) { 6 | res.writeHead(200, { 'Content-Type': 'text/html' }); 7 | res.end([ 8 | '' 16 | ].join('')); 17 | } else if ('/url' == req.url && 'POST' == req.method) { 18 | var body = ''; 19 | 20 | req.on('data', function (chunk) { 21 | body += chunk; 22 | }); 23 | 24 | req.on('end', function () { 25 | res.writeHead(200, { 'Content-Type': 'text/html' }); 26 | res.end('Your name is ' + qs.parse(body).name + '
'); 27 | }); 28 | } else { 29 | res.writeHead(404); 30 | res.end('Not Found'); 31 | } 32 | }).listen(3000); 33 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tweet-client" 3 | , "description": "An HTTP tweets client" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-2/client.js: -------------------------------------------------------------------------------- 1 | 2 | require('http').request({ host: '127.0.0.1', port: 3000, url: '/', method: 'GET' }, function (res) { 3 | var body = ''; 4 | res.setEncoding('utf8'); 5 | res.on('data', function (chunk) { 6 | body += chunk; 7 | }); 8 | res.on('end', function () { 9 | console.log('\n We got: \033[96m' + body + '\033[39m\n'); 10 | }); 11 | }).end(); 12 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tweet-client" 3 | , "description": "An HTTP tweets client" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-2/server.js: -------------------------------------------------------------------------------- 1 | 2 | require('http').createServer(function (req, res) { 3 | res.writeHead(200); 4 | res.end('Hello World'); 5 | }).listen(3000); 6 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-3/client.js: -------------------------------------------------------------------------------- 1 | 2 | var http = require('http') 3 | , qs = require('querystring') 4 | 5 | function send (theName) { 6 | http.request({ host: '127.0.0.1', port: 3000, url: '/', method: 'POST' }, function (res) { 7 | res.setEncoding('utf8'); 8 | res.on('end', function () { 9 | console.log('\n \033[90m✔ request complete!\033[39m'); 10 | process.stdout.write('\n your name: '); 11 | }); 12 | }).end(qs.stringify({ name: theName })); 13 | } 14 | 15 | process.stdout.write('\n your name: '); 16 | process.stdin.resume(); 17 | process.stdin.setEncoding('utf-8'); 18 | process.stdin.on('data', function (name) { 19 | send(name.replace('\n', '')); 20 | }); 21 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tweet-client" 3 | , "description": "An HTTP tweets client" 4 | , "version": "0.0.1" 5 | } 6 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-3/server.js: -------------------------------------------------------------------------------- 1 | 2 | var qs = require('querystring'); 3 | 4 | require('http').createServer(function (req, res) { 5 | var body = ''; 6 | 7 | req.on('data', function (chunk) { 8 | body += chunk; 9 | }); 10 | 11 | req.on('end', function () { 12 | res.writeHead(200); 13 | res.end('Done'); 14 | 15 | console.log('\n got name \033[90m' + qs.parse(body).name + '\033[39m\n'); 16 | }); 17 | }).listen(3000); 18 | -------------------------------------------------------------------------------- /code-examples/http/tweets/step-4/tweets.js: -------------------------------------------------------------------------------- 1 | 2 | var qs = require('querystring') 3 | , http = require('http') 4 | 5 | var search = process.argv.slice(2).join(' ').trim() 6 | 7 | if (!search.length) { 8 | return console.log('\n Usage: node tweetsUser not found. Go back and try again'); 53 | req.session.loggedIn = doc._id; 54 | res.redirect('/'); 55 | }); 56 | }); 57 | 58 | /** 59 | * Signup route 60 | */ 61 | 62 | app.get('/signup', function (req, res) { 63 | res.render('signup'); 64 | }); 65 | 66 | /** 67 | * Signup processing route 68 | */ 69 | 70 | app.post('/signup', function (req, res, next) { 71 | app.users.insert(req.body.user, function (err, doc) { 72 | if (err) return next(err); 73 | res.redirect('/login/' + doc[0].email); 74 | }); 75 | }); 76 | 77 | /** 78 | * Logout route. 79 | */ 80 | 81 | app.get('/logout', function (req, res) { 82 | req.session.loggedIn = null; 83 | res.redirect('/'); 84 | }); 85 | 86 | /** 87 | * Connect to the database. 88 | */ 89 | 90 | var server = new mongodb.Server('127.0.0.1', 27017) 91 | new mongodb.Db('my-website', server).open(function (err, client) { 92 | // don't allow our app to start if there was an error 93 | if (err) throw err; 94 | 95 | console.log('\033[96m + \033[39m connected to mongodb'); 96 | 97 | // set up collection shortcuts 98 | app.users = new mongodb.Collection(client, 'users'); 99 | 100 | client.ensureIndex('users', 'email', function (err) { 101 | if (err) throw err; 102 | client.ensureIndex('users', 'password', function (err) { 103 | if (err) throw err; 104 | 105 | console.log('\033[96m + \033[39m ensured indexes'); 106 | 107 | // listen 108 | app.listen(3000, function () { 109 | console.log('\033[96m + \033[39m app listening on *:3000'); 110 | }); 111 | }); 112 | }); 113 | }); 114 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-5/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | if (authenticated) 3 | p Welcome back, #{me.name} 4 | a(href="/logout") Logout 5 | else 6 | p Welcome new visitor! 7 | ul 8 | li: a(href="/login") Login 9 | li: a(href="/signup") Signup 10 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-5/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title MongoDB example 5 | body 6 | h1 My first MongoDB app 7 | hr 8 | != body 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-5/views/login.jade: -------------------------------------------------------------------------------- 1 | 2 | if (signupEmail) 3 | p Congratulations on signing up! Please login below. 4 | 5 | form(action="/login", method="POST") 6 | fieldset 7 | legend Log in 8 | p 9 | label Email 10 | input(name="user[email]", type="text", value=signupEmail) 11 | p 12 | label Password 13 | input(name="user[password]", type="password") 14 | p 15 | button Submit 16 | p 17 | a(href="/") Go back 18 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-5/views/signup.jade: -------------------------------------------------------------------------------- 1 | 2 | form(action="/signup", method="POST") 3 | fieldset 4 | legend Sign up 5 | p 6 | label First 7 | input(name="user[first]", type="text") 8 | p 9 | label Last 10 | input(name="user[last]", type="text") 11 | p 12 | label Email 13 | input(name="user[email]", type="text") 14 | p 15 | label Password 16 | input(name="user[password]", type="password") 17 | p 18 | button Submit 19 | p 20 | a(href="/") Go back 21 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "user-auth-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "mongodb": "0.9.9" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mongodb = require('mongodb') 8 | 9 | /** 10 | * Set up application. 11 | */ 12 | 13 | app = express.createServer() 14 | 15 | /** 16 | * Middleware. 17 | */ 18 | 19 | app.use(express.bodyParser()); 20 | app.use(express.cookieParser()); 21 | app.use(express.session({ secret: 'my secret' })); 22 | 23 | /** 24 | * Specifiy our views options. 25 | */ 26 | 27 | app.set('view engine', 'jade'); 28 | app.set('view options', { layout: false }); 29 | 30 | /** 31 | * Authentication middleware. 32 | */ 33 | 34 | app.use(function (req, res, next) { 35 | if (req.session.loggedIn) { 36 | res.local('authenticated', true); 37 | app.users.findOne({ _id: mongodb.ObjectID.createFromHexString(req.session.loggedIn) }, function (err, doc) { 38 | if (err) return next(err); 39 | res.local('me', doc); 40 | next(); 41 | }); 42 | } else { 43 | res.local('authenticated', false); 44 | next(); 45 | } 46 | }); 47 | 48 | /** 49 | * Default route 50 | */ 51 | 52 | app.get('/', function (req, res) { 53 | res.render('index'); 54 | }); 55 | 56 | /** 57 | * Login route 58 | */ 59 | 60 | app.get('/login/:signupEmail?', function (req, res) { 61 | res.render('login', { signupEmail: req.params.signupEmail }); 62 | }); 63 | 64 | /** 65 | * Login process route 66 | */ 67 | 68 | app.post('/login', function (req, res) { 69 | app.users.findOne(req.body.user, function (err, doc) { 70 | if (err) return next(err); 71 | if (!doc) return res.send('
User not found. Go back and try again'); 72 | req.session.loggedIn = doc._id.toString(); 73 | res.redirect('/'); 74 | }); 75 | }); 76 | 77 | /** 78 | * Signup route 79 | */ 80 | 81 | app.get('/signup', function (req, res) { 82 | res.render('signup'); 83 | }); 84 | 85 | /** 86 | * Signup processing route 87 | */ 88 | 89 | app.post('/signup', function (req, res, next) { 90 | app.users.insert(req.body.user, function (err, doc) { 91 | if (err) return next(err); 92 | res.redirect('/login/' + doc[0].email); 93 | }); 94 | }); 95 | 96 | /** 97 | * Logout route. 98 | */ 99 | 100 | app.get('/logout', function (req, res) { 101 | req.session.loggedIn = null; 102 | res.redirect('/'); 103 | }); 104 | 105 | /** 106 | * Connect to the database. 107 | */ 108 | 109 | var server = new mongodb.Server('127.0.0.1', 27017) 110 | new mongodb.Db('my-website', server).open(function (err, client) { 111 | // don't allow our app to start if there was an error 112 | if (err) throw err; 113 | 114 | console.log('\033[96m + \033[39m connected to mongodb'); 115 | 116 | // set up collection shortcuts 117 | app.users = new mongodb.Collection(client, 'users'); 118 | 119 | client.ensureIndex('users', 'email', function (err) { 120 | if (err) throw err; 121 | client.ensureIndex('users', 'password', function (err) { 122 | if (err) throw err; 123 | 124 | console.log('\033[96m + \033[39m ensured indexes'); 125 | 126 | // listen 127 | app.listen(3000, function () { 128 | console.log('\033[96m + \033[39m app listening on *:3000'); 129 | }); 130 | }); 131 | }); 132 | }); 133 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | if (authenticated) 5 | p Welcome back, #{me.first} 6 | a(href="/logout") Logout 7 | else 8 | p Welcome new visitor! 9 | ul 10 | li: a(href="/login") Login 11 | li: a(href="/signup") Signup 12 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title MongoDB example 5 | body 6 | h1 My first MongoDB app 7 | hr 8 | block body 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/views/login.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | if (signupEmail) 5 | p Congratulations on signing up! Please login below. 6 | 7 | form(action="/login", method="POST") 8 | fieldset 9 | legend Log in 10 | p 11 | label Email 12 | input(name="user[email]", type="text", value=signupEmail) 13 | p 14 | label Password 15 | input(name="user[password]", type="password") 16 | p 17 | button Submit 18 | p 19 | a(href="/") Go back 20 | -------------------------------------------------------------------------------- /code-examples/mongodb/auth/step-6/views/signup.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | form(action="/signup", method="POST") 5 | fieldset 6 | legend Sign up 7 | p 8 | label First 9 | input(name="user[first]", type="text") 10 | p 11 | label Last 12 | input(name="user[last]", type="text") 13 | p 14 | label Email 15 | input(name="user[email]", type="text") 16 | p 17 | label Password 18 | input(name="user[password]", type="password") 19 | p 20 | button Submit 21 | p 22 | a(href="/") Go back 23 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mongoose-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "mongoose": "2.5.10" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mongoose = require('mongoose') 8 | 9 | /** 10 | * Set up application. 11 | */ 12 | 13 | app = express.createServer() 14 | 15 | /** 16 | * Middleware. 17 | */ 18 | 19 | app.use(express.bodyParser()); 20 | app.use(express.cookieParser()); 21 | app.use(express.session({ secret: 'my secret' })); 22 | 23 | /** 24 | * Specifiy our views options. 25 | */ 26 | 27 | app.set('view engine', 'jade'); 28 | app.set('view options', { layout: false }); 29 | 30 | /** 31 | * Authentication middleware. 32 | */ 33 | 34 | app.use(function (req, res, next) { 35 | if (req.session.loggedIn) { 36 | res.local('authenticated', true); 37 | User.findById(req.session.loggedIn, function (err, doc) { 38 | if (err) return next(err); 39 | res.local('me', doc); 40 | next(); 41 | }); 42 | } else { 43 | res.local('authenticated', false); 44 | next(); 45 | } 46 | }); 47 | 48 | /** 49 | * Default route 50 | */ 51 | 52 | app.get('/', function (req, res) { 53 | res.render('index'); 54 | }); 55 | 56 | /** 57 | * Login route 58 | */ 59 | 60 | app.get('/login/:signupEmail?', function (req, res) { 61 | res.render('login', { signupEmail: req.params.signupEmail }); 62 | }); 63 | 64 | /** 65 | * Login process route 66 | */ 67 | 68 | app.post('/login', function (req, res) { 69 | User.findOne({ email: req.body.user.email, password: req.body.user.password }, function (err, doc) { 70 | if (err) return next(err); 71 | if (!doc) return res.send('
User not found. Go back and try again'); 72 | req.session.loggedIn = doc._id.toString(); 73 | res.redirect('/'); 74 | }); 75 | }); 76 | 77 | /** 78 | * Signup route 79 | */ 80 | 81 | app.get('/signup', function (req, res) { 82 | res.render('signup'); 83 | }); 84 | 85 | /** 86 | * Signup processing route 87 | */ 88 | 89 | app.post('/signup', function (req, res, next) { 90 | var user = new User(req.body.user); 91 | user.save(function (err) { 92 | if (err) return next(err); 93 | res.redirect('/login/' + user.email); 94 | }); 95 | }); 96 | 97 | /** 98 | * Logout route. 99 | */ 100 | 101 | app.get('/logout', function (req, res) { 102 | req.session.loggedIn = null; 103 | res.redirect('/'); 104 | }); 105 | 106 | /** 107 | * Connect to the database. 108 | */ 109 | 110 | mongoose.connect('mongodb://127.0.0.1/my-website'); 111 | app.listen(3000, function () { 112 | console.log('\033[96m + \033[39m app listening on *:3000'); 113 | }); 114 | 115 | /** 116 | * Define model. 117 | */ 118 | 119 | var Schema = mongoose.Schema 120 | 121 | var User = mongoose.model('User', new Schema({ 122 | first: String 123 | , last: String 124 | , email: { type: String, unique: true } 125 | , password: { type: String, index: true } 126 | })); 127 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/step-final/blogpost.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var mongoose = require('mongoose') 7 | , Schema = mongoose.Schema 8 | 9 | /** 10 | * Module exports. 11 | */ 12 | 13 | var BlogPost = module.exports = new Schema({ 14 | 15 | 16 | }); 17 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/step-final/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mongoose-blog" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "mongoose": "2.5.10" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/step-final/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mongoose = require('mongoose') 8 | 9 | /** 10 | * Create app 11 | */ 12 | 13 | app = require('express').createServer(); 14 | 15 | /** 16 | * Connect to mongoose 17 | */ 18 | 19 | mongoose.connect('mongodb://localhost/my-blog'); 20 | 21 | /** 22 | * Define our model. 23 | */ 24 | 25 | var BlogPost = mongoose.model('BlogPost', require('./blogpost')); 26 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | if (authenticated) 5 | p Welcome back, #{me.first} 6 | a(href="/logout") Logout 7 | else 8 | p Welcome new visitor! 9 | ul 10 | li: a(href="/login") Login 11 | li: a(href="/signup") Signup 12 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title MongoDB example 5 | body 6 | h1 My first MongoDB app 7 | hr 8 | block body 9 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/views/login.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | if (signupEmail) 5 | p Congratulations on signing up! Please login below. 6 | 7 | form(action="/login", method="POST") 8 | fieldset 9 | legend Log in 10 | p 11 | label Email 12 | input(name="user[email]", type="text", value=signupEmail) 13 | p 14 | label Password 15 | input(name="user[password]", type="password") 16 | p 17 | button Submit 18 | p 19 | a(href="/") Go back 20 | -------------------------------------------------------------------------------- /code-examples/mongodb/blog/views/signup.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | block body 4 | form(action="/signup", method="POST") 5 | fieldset 6 | legend Sign up 7 | p 8 | label First 9 | input(name="user[first]", type="text") 10 | p 11 | label Last 12 | input(name="user[last]", type="text") 13 | p 14 | label Email 15 | input(name="user[email]", type="text") 16 | p 17 | label Password 18 | input(name="user[password]", type="password") 19 | p 20 | button Submit 21 | p 22 | a(href="/") Go back 23 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "node-mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "node-mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-2/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | 8 | /** 9 | * Create app. 10 | */ 11 | 12 | app = express.createServer(); 13 | 14 | /** 15 | * Configure app. 16 | */ 17 | 18 | app.set('view engine', 'jade'); 19 | app.set('views', __dirname + '/views'); 20 | 21 | /** 22 | * Main route 23 | */ 24 | 25 | app.get('/', function (req, res, next) { 26 | res.render('index'); 27 | }); 28 | 29 | /** 30 | * Item creation route. 31 | */ 32 | 33 | app.post('/create', function (req, res, next) { 34 | }); 35 | 36 | /** 37 | * Item route. 38 | */ 39 | 40 | app.get('/item/:id', function (req, res, next) { 41 | res.render('item'); 42 | }); 43 | 44 | /** 45 | * Item review creation route. 46 | */ 47 | 48 | app.post('/item/:id/review', function (req, res, next) { 49 | }); 50 | 51 | /** 52 | * Listen. 53 | */ 54 | 55 | app.listen(3000, function () { 56 | console.log(' - listening on http://*:3000'); 57 | }); 58 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "node-mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-3/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mysql = require('mysql') 8 | 9 | /** 10 | * Create app. 11 | */ 12 | 13 | app = express.createServer(); 14 | 15 | /** 16 | * Configure app. 17 | */ 18 | 19 | app.set('view engine', 'jade'); 20 | app.set('views', __dirname + '/views'); 21 | 22 | /** 23 | * Main route 24 | */ 25 | 26 | app.get('/', function (req, res, next) { 27 | res.render('index'); 28 | }); 29 | 30 | /** 31 | * Item creation route. 32 | */ 33 | 34 | app.post('/create', function (req, res, next) { 35 | }); 36 | 37 | /** 38 | * Item route. 39 | */ 40 | 41 | app.get('/item/:id', function (req, res, next) { 42 | res.render('item'); 43 | }); 44 | 45 | /** 46 | * Item review creation route. 47 | */ 48 | 49 | app.post('/item/:id/review', function (req, res, next) { 50 | }); 51 | 52 | /** 53 | * Connect to MySQL 54 | */ 55 | 56 | var db = mysql.createClient({ 57 | host: 'localhost' 58 | , database: 'cart-example' 59 | }); 60 | 61 | /** 62 | * Listen. 63 | */ 64 | 65 | app.listen(3000, function () { 66 | console.log(' - listening on http://*:3000'); 67 | }); 68 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-4/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "host": "localhost" 3 | , "database": "cart-example" 4 | } 5 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "node-mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-4/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mysql = require('mysql') 8 | , config = require('./config') 9 | 10 | /** 11 | * Create app. 12 | */ 13 | 14 | app = express.createServer(); 15 | 16 | /** 17 | * Configure app. 18 | */ 19 | 20 | app.set('view engine', 'jade'); 21 | app.set('views', __dirname + '/views'); 22 | 23 | /** 24 | * Main route 25 | */ 26 | 27 | app.get('/', function (req, res, next) { 28 | res.render('index'); 29 | }); 30 | 31 | /** 32 | * Item creation route. 33 | */ 34 | 35 | app.post('/create', function (req, res, next) { 36 | }); 37 | 38 | /** 39 | * Item route. 40 | */ 41 | 42 | app.get('/item/:id', function (req, res, next) { 43 | res.render('item'); 44 | }); 45 | 46 | /** 47 | * Item review creation route. 48 | */ 49 | 50 | app.post('/item/:id/review', function (req, res, next) { 51 | }); 52 | 53 | /** 54 | * Connect to MySQL 55 | */ 56 | 57 | var db = mysql.createClient(config); 58 | 59 | /** 60 | * Listen. 61 | */ 62 | 63 | app.listen(3000, function () { 64 | console.log(' - listening on http://*:3000'); 65 | }); 66 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-4/setup.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var mysql = require('mysql') 7 | , config = require('./config') 8 | 9 | /** 10 | * Initialize client. 11 | */ 12 | 13 | var db = mysql.createClient(config); 14 | 15 | /** 16 | * Create database. 17 | */ 18 | 19 | db.query('CREATE DATABASE cart-example'); 20 | 21 | /** 22 | * Create tables. 23 | */ 24 | 25 | db.query('CREATE TABLE item (' + 26 | 'id INT(11) AUTO_INCREMENT,' + 27 | 'title VARCHAR(255),' + 28 | 'description TEXT,' + 29 | 'created DATETIME,' + 30 | 'PRIMARY KEY (id))'); 31 | 32 | db.query('CREATE TABLE review (' + 33 | 'id INT(11) AUTO_INCREMENT,' + 34 | 'item_id INT(11),' + 35 | 'text TEXT,' + 36 | 'stars INT(1),' + 37 | 'created DATETIME,' + 38 | 'PRIMARY KEY (id))'); 39 | 40 | /** 41 | * Close client. 42 | */ 43 | 44 | db.end(); 45 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "host": "localhost" 3 | , "database": "cart-example" 4 | } 5 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mysql = require('mysql') 8 | , config = require('./config') 9 | 10 | /** 11 | * Create app. 12 | */ 13 | 14 | app = express.createServer(); 15 | 16 | /** 17 | * Middleware. 18 | */ 19 | 20 | app.use(express.bodyParser()); 21 | 22 | /** 23 | * Configure app. 24 | */ 25 | 26 | app.set('view engine', 'jade'); 27 | app.set('views', __dirname + '/views'); 28 | 29 | /** 30 | * Main route 31 | */ 32 | 33 | app.get('/', function (req, res, next) { 34 | res.render('index', { items: [] }); 35 | }); 36 | 37 | /** 38 | * Item creation route. 39 | */ 40 | 41 | app.post('/create', function (req, res, next) { 42 | db.query('INSERT INTO item SET title = ?, description = ?', 43 | [req.body.title, req.body.description], function (err, info) { 44 | if (err) return next(err); 45 | console.log(' - item created with id %s', info.insertId); 46 | res.redirect('/'); 47 | }); 48 | }); 49 | 50 | /** 51 | * Item route. 52 | */ 53 | 54 | app.get('/item/:id', function (req, res, next) { 55 | res.render('item'); 56 | }); 57 | 58 | /** 59 | * Item review creation route. 60 | */ 61 | 62 | app.post('/item/:id/review', function (req, res, next) { 63 | db.query('INSERT INTO review SET item_id = ?, stars = ?, text = ?', 64 | [req.params.id, req.body.stars, req.body.text], function (err, info) { 65 | if (err) return next(err); 66 | console.log(' - review created with id %s', info.insertId); 67 | res.redirect('/item/' + req.params.id); 68 | }); 69 | }); 70 | 71 | /** 72 | * Connect to MySQL 73 | */ 74 | 75 | var db = mysql.createClient(config); 76 | 77 | /** 78 | * Listen. 79 | */ 80 | 81 | app.listen(3000, function () { 82 | console.log(' - listening on http://*:3000'); 83 | }); 84 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/setup.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var mysql = require('mysql') 7 | , config = require('./config') 8 | 9 | /** 10 | * Initialize client. 11 | */ 12 | 13 | var db = mysql.createClient(config); 14 | 15 | /** 16 | * Create database. 17 | */ 18 | 19 | db.query('CREATE DATABASE cart-example'); 20 | 21 | /** 22 | * Create tables. 23 | */ 24 | 25 | db.query('CREATE TABLE item (' + 26 | 'id INT(11) AUTO_INCREMENT,' + 27 | 'title VARCHAR(255),' + 28 | 'description TEXT,' + 29 | 'created DATETIME,' + 30 | 'PRIMARY KEY (id))'); 31 | 32 | db.query('CREATE TABLE review (' + 33 | 'id INT(11) AUTO_INCREMENT,' + 34 | 'item_id INT(11),' + 35 | 'text TEXT,' + 36 | 'stars INT(1),' + 37 | 'created DATETIME,' + 38 | 'PRIMARY KEY (id))'); 39 | 40 | /** 41 | * Close client. 42 | */ 43 | 44 | db.end(); 45 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | h2 All items 3 | 4 | if (items.length) 5 | ul 6 | each item in items 7 | li 8 | h3: a(href="/item/#{item.id}")= item.title 9 | = item.description 10 | else 11 | p No items to show 12 | 13 | h2 Create new item 14 | 15 | form(action="/create", method="POST") 16 | p 17 | label Title 18 | input(type="text", name="title") 19 | p 20 | label Description 21 | textarea(name="description") 22 | p 23 | button Submit 24 | 25 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/views/item.jade: -------------------------------------------------------------------------------- 1 | 2 | extends layout 3 | 4 | block body 5 | a(href="/") Go back 6 | 7 | h2= item.title 8 | p= item.description 9 | 10 | h3 User reviews 11 | 12 | if (reviews.length) 13 | each review in reviews 14 | .review 15 | b #{review.stars} stars 16 | p= review.text 17 | hr 18 | else 19 | p No reviews to show. Write one! 20 | 21 | h4 Create review 22 | form(action="/item/#{item.id}/review", method="POST") 23 | p 24 | label Stars 25 | select 26 | option 1 27 | option 2 28 | option 3 29 | option 4 30 | option 5 31 | p 32 | label Review 33 | textarea(name="text") 34 | p 35 | submit Send 36 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-5/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title My shopping cart 5 | body 6 | h1 My shopping cart 7 | #cart!= body 8 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "host": "localhost" 3 | , "database": "cart-example" 4 | } 5 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopping-cart-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.9" 6 | , "jade": "0.19.0" 7 | , "mysql": "0.9.5" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , mysql = require('mysql') 8 | , config = require('./config') 9 | 10 | /** 11 | * Create app. 12 | */ 13 | 14 | app = express.createServer(); 15 | 16 | /** 17 | * Middleware. 18 | */ 19 | 20 | app.use(express.bodyParser()); 21 | 22 | /** 23 | * Configure app. 24 | */ 25 | 26 | app.set('view engine', 'jade'); 27 | app.set('views', __dirname + '/views'); 28 | 29 | /** 30 | * Main route 31 | */ 32 | 33 | app.get('/', function (req, res, next) { 34 | db.query('SELECT id, title, description FROM item', function (err, results) { 35 | res.render('index', { items: results }); 36 | }); 37 | }); 38 | 39 | /** 40 | * Item creation route. 41 | */ 42 | 43 | app.post('/create', function (req, res, next) { 44 | db.query('INSERT INTO item SET title = ?, description = ?', 45 | [req.body.title, req.body.description], function (err, info) { 46 | if (err) return next(err); 47 | console.log(' - item created with id %s', info.insertId); 48 | res.redirect('/'); 49 | }); 50 | }); 51 | 52 | /** 53 | * Item route. 54 | */ 55 | 56 | app.get('/item/:id', function (req, res, next) { 57 | function getItem () { 58 | db.query('SELECT id, title, description FROM item WHERE id = ? LIMIT 1', 59 | [req.params.id], function (err, results) { 60 | if (err) return next(err); 61 | var item = results[0]; 62 | if (!item) return res.send(404); 63 | fn({ id: item[0], title: item[1], description: item[2] }); 64 | }); 65 | } 66 | 67 | function getReviews (item_id) { 68 | db.query('SELECT text, stars FROM review WHERE item_id = ?', 69 | [item_id], function (err, results) { 70 | if (err) return next(err); 71 | fn(results.map(function (res) { 72 | return { text: res[0], stars: res[1] }; 73 | })); 74 | }); 75 | } 76 | 77 | getItem(function (item) { 78 | getReviews(item.id, function (reviews) { 79 | res.render('item', { item: item, reviews: reviews }); 80 | }); 81 | }); 82 | }); 83 | 84 | /** 85 | * Item review creation route. 86 | */ 87 | 88 | app.post('/item/:id/review', function (req, res, next) { 89 | db.query('INSERT INTO review SET item_id = ?, stars = ?, text = ?', 90 | [req.params.id, req.body.stars, req.body.text], function (err, info) { 91 | if (err) return next(err); 92 | console.log(' - review created with id %s', info.insertId); 93 | res.redirect('/item/' + req.params.id); 94 | }); 95 | }); 96 | 97 | /** 98 | * Connect to MySQL 99 | */ 100 | 101 | var db = mysql.createClient(config); 102 | 103 | /** 104 | * Listen. 105 | */ 106 | 107 | app.listen(3000, function () { 108 | console.log(' - listening on http://*:3000'); 109 | }); 110 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/setup.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var mysql = require('mysql') 7 | , config = require('./config') 8 | 9 | /** 10 | * Initialize client. 11 | */ 12 | 13 | var db = mysql.createClient(config); 14 | 15 | /** 16 | * Create database. 17 | */ 18 | 19 | db.query('CREATE DATABASE IF NOT EXISTS `cart-example`'); 20 | db.query('USE `cart-example`'); 21 | 22 | /** 23 | * Create tables. 24 | */ 25 | 26 | db.query('DROP TABLE IF EXISTS item'); 27 | db.query('CREATE TABLE item (' + 28 | 'id INT(11) AUTO_INCREMENT,' + 29 | 'title VARCHAR(255),' + 30 | 'description TEXT,' + 31 | 'created DATETIME,' + 32 | 'PRIMARY KEY (id))'); 33 | 34 | db.query('DROP TABLE IF EXISTS review'); 35 | db.query('CREATE TABLE review (' + 36 | 'id INT(11) AUTO_INCREMENT,' + 37 | 'item_id INT(11),' + 38 | 'text TEXT,' + 39 | 'stars INT(1),' + 40 | 'created DATETIME,' + 41 | 'PRIMARY KEY (id))'); 42 | 43 | /** 44 | * Close client. 45 | */ 46 | 47 | db.end(); 48 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | h2 All items 3 | 4 | if (items.length) 5 | ul 6 | each item in items 7 | li 8 | h3: a(href="/item/#{item.id}")= item.title 9 | = item.description 10 | else 11 | p No items to show 12 | 13 | h2 Create new item 14 | 15 | form(action="/create", method="POST") 16 | p 17 | label Title 18 | input(type="text", name="title") 19 | p 20 | label Description 21 | textarea(name="description") 22 | p 23 | button Submit 24 | 25 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/views/item.jade: -------------------------------------------------------------------------------- 1 | 2 | a(href="/") Go back 3 | 4 | h2= item.title 5 | p= item.description 6 | 7 | h3 User reviews 8 | 9 | if (reviews.length) 10 | each review in reviews 11 | .review 12 | b #{review.stars} stars 13 | p= review.text 14 | hr 15 | else 16 | p No reviews to show. Write one! 17 | 18 | h4 Create review 19 | form(action="/item/#{item.id}/review", method="POST") 20 | p 21 | label Stars 22 | select 23 | option 1 24 | option 2 25 | option 3 26 | option 4 27 | option 5 28 | p 29 | label Review 30 | textarea(name="text") 31 | p 32 | submit Send 33 | -------------------------------------------------------------------------------- /code-examples/mysql/node-mysql/step-6/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title My shopping cart 5 | body 6 | h1 My shopping cart 7 | #cart!= body 8 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "sequelize": "1.2.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "sequelize": "1.2.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/public/js/main.js: -------------------------------------------------------------------------------- 1 | 2 | $(function () { 3 | 4 | }); 5 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | 8 | /** 9 | * Create app. 10 | */ 11 | 12 | app = express.createServer(); 13 | 14 | /** 15 | * Configure app. 16 | */ 17 | 18 | app.set('view engine', 'jade'); 19 | app.set('views', __dirname + '/views'); 20 | app.set('view options', { layout: false }); 21 | 22 | /** 23 | * Main route 24 | */ 25 | 26 | app.get('/', function (req, res, next) { 27 | res.render('index'); 28 | }); 29 | 30 | /** 31 | * Project deletion route. 32 | */ 33 | 34 | app.del('/project/:id', function (req, res, next) { 35 | }); 36 | 37 | /** 38 | * Project creation route. 39 | */ 40 | 41 | app.post('/projects', function (req, res, next) { 42 | }); 43 | 44 | /** 45 | * Show tasks for project. 46 | */ 47 | 48 | app.get('/project/:id/items', function (req, res, next) { 49 | }); 50 | 51 | /** 52 | * Add tassk for project. 53 | */ 54 | 55 | app.post('/project/:id/items', function (req, res, next) { 56 | }); 57 | 58 | /** 59 | * Item route. 60 | */ 61 | 62 | app.del('/item/:id', function (req, res, next) { 63 | }); 64 | /** 65 | * Listen. 66 | */ 67 | 68 | app.listen(3000, function () { 69 | console.log(' - listening on http://*:3000'); 70 | }); 71 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | h2 Projects 3 | 4 | #list 5 | ul#projects-list 6 | each project in projects 7 | li 8 | a(href="/project/#{project.id}")= project.title 9 | a.delete(href="/project/:id") x 10 | 11 | form#add(action="/projects", method="POST") 12 | input(type="text", name="item") 13 | button Add 14 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title TODO list app 5 | script(src="http://code.jquery.com/jquery-1.6.1.js") 6 | script(src="/js/main.js") 7 | body 8 | h1 TODO list app 9 | #todo= body 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-2/views/tasks.jade: -------------------------------------------------------------------------------- 1 | 2 | 3 | h2 Tasks for project #{project.title} 4 | 5 | #list 6 | ul#tasks-list 7 | each task in tasks 8 | li 9 | span= task.title 10 | a.delete(href="/task/:id") x 11 | 12 | form#add(action="/project/#{project.id}/tasks", method="POST") 13 | input(type="text", name="item") 14 | button Add 15 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "sequelize": "1.2.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/public/js/main.js: -------------------------------------------------------------------------------- 1 | 2 | $(function () { 3 | 4 | }); 5 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , Sequelize = require('sequelize') 8 | 9 | /** 10 | * Create app. 11 | */ 12 | 13 | app = express.createServer(); 14 | 15 | /** 16 | * Instantiate sequelize. 17 | */ 18 | 19 | var sequelize = new Sequelize('todo-example') 20 | 21 | /** 22 | * Configure app. 23 | */ 24 | 25 | app.set('view engine', 'jade'); 26 | app.set('views', __dirname + '/views'); 27 | 28 | /** 29 | * Main route 30 | */ 31 | 32 | app.get('/', function (req, res, next) { 33 | res.render('index'); 34 | }); 35 | 36 | /** 37 | * Project deletion route. 38 | */ 39 | 40 | app.del('/project/:id', function (req, res, next) { 41 | }); 42 | 43 | /** 44 | * Project creation route. 45 | */ 46 | 47 | app.post('/projects', function (req, res, next) { 48 | }); 49 | 50 | /** 51 | * Show tasks for project. 52 | */ 53 | 54 | app.get('/project/:id/items', function (req, res, next) { 55 | }); 56 | 57 | /** 58 | * Add tassk for project. 59 | */ 60 | 61 | app.post('/project/:id/items', function (req, res, next) { 62 | }); 63 | 64 | /** 65 | * Item route. 66 | */ 67 | 68 | app.del('/item/:id', function (req, res, next) { 69 | }); 70 | /** 71 | * Listen. 72 | */ 73 | 74 | app.listen(3000, function () { 75 | console.log(' - listening on http://*:3000'); 76 | }); 77 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | h2 Projects 3 | 4 | #list 5 | ul#projects-list 6 | each project in projects 7 | li 8 | a(href="/project/#{project.id}")= project.title 9 | a.delete(href="/project/:id") x 10 | 11 | form#add(action="/projects", method="POST") 12 | input(type="text", name="item") 13 | button Add 14 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title TODO list app 5 | script(src="http://code.jquery.com/jquery-1.6.1.js") 6 | script(src="/js/main.js") 7 | body 8 | h1 TODO list app 9 | #todo= body 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-3/views/tasks.jade: -------------------------------------------------------------------------------- 1 | 2 | 3 | h2 Tasks for project #{project.title} 4 | 5 | #list 6 | ul#tasks-list 7 | each task in tasks 8 | li 9 | span= task.title 10 | a.delete(href="/task/:id") x 11 | 12 | form#add(action="/project/#{project.id}/tasks", method="POST") 13 | input(type="text", name="item") 14 | button Add 15 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "sequelize": "1.2.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/public/js/main.js: -------------------------------------------------------------------------------- 1 | 2 | $(function () { 3 | 4 | }); 5 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/server.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var express = require('express') 7 | , Sequelize = require('sequelize') 8 | 9 | /** 10 | * Create app. 11 | */ 12 | 13 | app = express.createServer(); 14 | 15 | /** 16 | * Instantiate sequelize. 17 | */ 18 | 19 | var sequelize = new Sequelize('todo-example') 20 | 21 | /** 22 | * Define project model. 23 | */ 24 | 25 | var Project = sequelize.define('Project', { 26 | title: sequelize.STRING 27 | , description: sequelize.TEXT 28 | , created: sequelize.DATE 29 | }); 30 | 31 | /** 32 | * Define task model. 33 | */ 34 | 35 | var Task = sequelize.define('Task', { 36 | title: sequelize.STRING 37 | }); 38 | 39 | /** 40 | * Set up association. 41 | */ 42 | 43 | Task.belongsTo(Project); 44 | 45 | /** 46 | * Synchronize. 47 | */ 48 | 49 | sequelize.sync({ force: 'production' != process.env.NODE_ENV }); 50 | 51 | /** 52 | * Configure app. 53 | */ 54 | 55 | app.set('view engine', 'jade'); 56 | app.set('views', __dirname + '/views'); 57 | 58 | /** 59 | * Main route 60 | */ 61 | 62 | app.get('/', function (req, res, next) { 63 | res.render('index'); 64 | }); 65 | 66 | /** 67 | * Project deletion route. 68 | */ 69 | 70 | app.del('/project/:id', function (req, res, next) { 71 | }); 72 | 73 | /** 74 | * Project creation route. 75 | */ 76 | 77 | app.post('/projects', function (req, res, next) { 78 | }); 79 | 80 | /** 81 | * Show tasks for project. 82 | */ 83 | 84 | app.get('/project/:id/items', function (req, res, next) { 85 | }); 86 | 87 | /** 88 | * Add tassk for project. 89 | */ 90 | 91 | app.post('/project/:id/items', function (req, res, next) { 92 | }); 93 | 94 | /** 95 | * Item route. 96 | */ 97 | 98 | app.del('/item/:id', function (req, res, next) { 99 | }); 100 | /** 101 | * Listen. 102 | */ 103 | 104 | app.listen(3000, function () { 105 | console.log(' - listening on http://*:3000'); 106 | }); 107 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/views/index.jade: -------------------------------------------------------------------------------- 1 | 2 | h2 Projects 3 | 4 | #list 5 | ul#projects-list 6 | each project in projects 7 | li 8 | a(href="/project/#{project.id}")= project.title 9 | a.delete(href="/project/:id") x 10 | 11 | form#add(action="/projects", method="POST") 12 | input(type="text", name="item") 13 | button Add 14 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/views/layout.jade: -------------------------------------------------------------------------------- 1 | doctype 5 2 | html 3 | head 4 | title TODO list app 5 | script(src="http://code.jquery.com/jquery-1.6.1.js") 6 | script(src="/js/main.js") 7 | body 8 | h1 TODO list app 9 | #todo= body 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-4/views/tasks.jade: -------------------------------------------------------------------------------- 1 | 2 | 3 | h2 Tasks for project #{project.title} 4 | 5 | #list 6 | ul#tasks-list 7 | each task in tasks 8 | li 9 | span= task.title 10 | a.delete(href="/task/:id") x 11 | 12 | form#add(action="/project/#{project.id}/tasks", method="POST") 13 | input(type="text", name="item") 14 | button Add 15 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-5/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "todo-list-example" 3 | , "version": "0.0.1" 4 | , "dependencies": { 5 | "express": "2.5.2" 6 | , "jade": "0.19.0" 7 | , "sequelize": "1.3.7" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /code-examples/mysql/sequelize/step-5/public/js/main.js: -------------------------------------------------------------------------------- 1 | 2 | $(function () { 3 | $('form').submit(function (ev) { 4 | ev.preventDefault(); 5 | var form = $(this); 6 | $.ajax({ 7 | url: form.attr('action') 8 | , type: 'POST' 9 | , data: form.serialize() 10 | , success: function (obj) { 11 | var el = $('
A paragraph
'); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /code-examples/testing/mocha/browser/expect.js: -------------------------------------------------------------------------------- 1 | 2 | (function (global, module) { 3 | 4 | if ('undefined' == typeof module) { 5 | var module = { exports: {} } 6 | , exports = module.exports 7 | } 8 | 9 | /** 10 | * Exports. 11 | */ 12 | 13 | module.exports = expect; 14 | expect.Assertion = Assertion; 15 | 16 | /** 17 | * Exports version. 18 | */ 19 | 20 | expect.version = '0.1.1'; 21 | 22 | /** 23 | * Possible assertion flags. 24 | */ 25 | 26 | var flags = { 27 | not: ['to', 'be', 'have', 'include', 'only'] 28 | , to: ['be', 'have', 'include', 'only', 'not'] 29 | , only: ['have'] 30 | , have: ['own'] 31 | , be: ['an'] 32 | }; 33 | 34 | function expect (obj) { 35 | return new Assertion(obj); 36 | } 37 | 38 | /** 39 | * Constructor 40 | * 41 | * @api private 42 | */ 43 | 44 | function Assertion (obj, flag, parent) { 45 | this.obj = obj; 46 | this.flags = {}; 47 | 48 | if (undefined != parent) { 49 | this.flags[flag] = true; 50 | 51 | for (var i in parent.flags) { 52 | if (parent.flags.hasOwnProperty(i)) { 53 | this.flags[i] = true; 54 | } 55 | } 56 | } 57 | 58 | var $flags = flag ? flags[flag] : keys(flags) 59 | , self = this 60 | 61 | if ($flags) { 62 | for (var i = 0, l = $flags.length; i < l; i++) { 63 | // avoid recursion 64 | if (this.flags[$flags[i]]) continue; 65 | 66 | var name = $flags[i] 67 | , assertion = new Assertion(this.obj, name, this) 68 | 69 | if ('function' == typeof Assertion.prototype[name]) { 70 | // clone the function, make sure we dont touch the prot reference 71 | var old = this[name]; 72 | this[name] = function () { 73 | return old.apply(self, arguments); 74 | } 75 | 76 | for (var fn in Assertion.prototype) { 77 | if (Assertion.prototype.hasOwnProperty(fn) && fn != name) { 78 | this[name][fn] = bind(assertion[fn], assertion); 79 | } 80 | } 81 | } else { 82 | this[name] = assertion; 83 | } 84 | } 85 | } 86 | }; 87 | 88 | /** 89 | * Performs an assertion 90 | * 91 | * @api private 92 | */ 93 | 94 | Assertion.prototype.assert = function (truth, msg, error) { 95 | var msg = this.flags.not ? error : msg 96 | , ok = this.flags.not ? !truth : truth; 97 | 98 | if (!ok) { 99 | throw new Error(msg); 100 | } 101 | 102 | this.and = new Assertion(this.obj); 103 | }; 104 | 105 | /** 106 | * Check if the value is truthy 107 | * 108 | * @api public 109 | */ 110 | 111 | Assertion.prototype.ok = function () { 112 | this.assert( 113 | !!this.obj 114 | , 'expected ' + i(this.obj) + ' to be truthy' 115 | , 'expected ' + i(this.obj) + ' to be falsy'); 116 | }; 117 | 118 | /** 119 | * Asser that the function throws. 120 | */ 121 | 122 | Assertion.prototype.throwException = function () { 123 | expect(this.obj).to.be.a('function'); 124 | 125 | var thrown = false; 126 | 127 | try { 128 | this.obj(); 129 | } catch (e) { 130 | thrown = true; 131 | } 132 | 133 | var name = this.obj.name || 'fn'; 134 | this.assert( 135 | thrown 136 | , 'expected ' + name + ' to throw an exception' 137 | , 'expected ' + name + ' not to throw an exception'); 138 | }; 139 | 140 | /** 141 | * Checks if the array is empty. 142 | * 143 | * @api public 144 | */ 145 | 146 | Assertion.prototype.empty = function () { 147 | expect(this.obj).to.have.property('length'); 148 | this.assert( 149 | 0 === this.obj.length 150 | , 'expected ' + i(this.obj) + ' to be empty' 151 | , 'expected ' + i(this.obj) + ' to not be empty'); 152 | return this; 153 | }; 154 | 155 | /** 156 | * Checks if the obj exactly equals another. 157 | * 158 | * @api public 159 | */ 160 | 161 | Assertion.prototype.be = 162 | Assertion.prototype.equal = function (obj) { 163 | this.assert( 164 | obj === this.obj 165 | , 'expected ' + i(this.obj) + ' to equal ' + i(obj) 166 | , 'expected ' + i(this.obj) + ' to not equal ' + i(obj)); 167 | return this; 168 | }; 169 | 170 | /** 171 | * Checks if the obj sortof equals another. 172 | * 173 | * @api public 174 | */ 175 | 176 | Assertion.prototype.eql = function (obj) { 177 | this.assert( 178 | expect.eql(obj, this.obj) 179 | , 'expected ' + i(this.obj) + ' to sort of equal ' + i(obj) 180 | , 'expected ' + i(this.obj) + ' to sort of not equal ' + i(obj)); 181 | return this; 182 | }; 183 | 184 | /** 185 | * Assert within start to finish (inclusive). 186 | * 187 | * @param {Number} start 188 | * @param {Number} finish 189 | * @api public 190 | */ 191 | 192 | Assertion.prototype.within = function (start, finish) { 193 | var range = start + '..' + finish; 194 | this.assert( 195 | this.obj >= start && this.obj <= finish 196 | , 'expected ' + i(this.obj) + ' to be within ' + range 197 | , 'expected ' + i(this.obj) + ' to not be within ' + range); 198 | return this; 199 | }; 200 | 201 | /** 202 | * Assert typeof / instance of 203 | * 204 | * @api public 205 | */ 206 | 207 | Assertion.prototype.a = 208 | Assertion.prototype.an = function (type) { 209 | if ('string' == typeof type) { 210 | // typeof with support for 'array' 211 | this.assert( 212 | 'array' == type ? isArray(this.obj) : type == typeof this.obj 213 | , 'expected ' + i(this.obj) + ' to be a ' + type 214 | , 'expected ' + i(this.obj) + ' not to be a ' + type); 215 | } else { 216 | // instanceof 217 | var name = type.name || 'supplied constructor'; 218 | this.assert( 219 | this.obj instanceof type 220 | , 'expected ' + i(this.obj) + ' to be an instance of ' + name 221 | , 'expected ' + i(this.obj) + ' not to be an instance of ' + name); 222 | } 223 | 224 | return this; 225 | }; 226 | 227 | /** 228 | * Assert numeric value above _n_. 229 | * 230 | * @param {Number} n 231 | * @api public 232 | */ 233 | 234 | Assertion.prototype.greaterThan = 235 | Assertion.prototype.above = function (n) { 236 | this.assert( 237 | this.obj > n 238 | , 'expected ' + i(this.obj) + ' to be above ' + n 239 | , 'expected ' + i(this.obj) + ' to be below ' + n); 240 | return this; 241 | }; 242 | 243 | /** 244 | * Assert numeric value below _n_. 245 | * 246 | * @param {Number} n 247 | * @api public 248 | */ 249 | 250 | Assertion.prototype.lessThan = 251 | Assertion.prototype.below = function (n) { 252 | this.assert( 253 | this.obj < n 254 | , 'expected ' + i(this.obj) + ' to be below ' + n 255 | , 'expected ' + i(this.obj) + ' to be above ' + n); 256 | return this; 257 | }; 258 | 259 | /** 260 | * Assert string value matches _regexp_. 261 | * 262 | * @param {RegExp} regexp 263 | * @api public 264 | */ 265 | 266 | Assertion.prototype.match = function (regexp) { 267 | this.assert( 268 | regexp.exec(this.obj) 269 | , 'expected ' + i(this.obj) + ' to match ' + regexp 270 | , 'expected ' + i(this.obj) + ' not to match ' + regexp); 271 | return this; 272 | }; 273 | 274 | /** 275 | * Assert property "length" exists and has value of _n_. 276 | * 277 | * @param {Number} n 278 | * @api public 279 | */ 280 | 281 | Assertion.prototype.length = function (n) { 282 | expect(this.obj).to.have.property('length'); 283 | var len = this.obj.length; 284 | this.assert( 285 | n == len 286 | , 'expected ' + i(this.obj) + ' to have a length of ' + n + ' but got ' + len 287 | , 'expected ' + i(this.obj) + ' to not have a length of ' + len); 288 | return this; 289 | }; 290 | 291 | /** 292 | * Assert property _name_ exists, with optional _val_. 293 | * 294 | * @param {String} name 295 | * @param {Mixed} val 296 | * @api public 297 | */ 298 | 299 | Assertion.prototype.property = function (name, val) { 300 | if (this.flags.own) { 301 | this.assert( 302 | Object.prototype.hasOwnProperty.call(this.obj, name) 303 | , 'expected ' + i(this.obj) + ' to have own property ' + i(name) 304 | , 'expected ' + i(this.obj) + ' to not have own property ' + i(name)); 305 | return this; 306 | } 307 | 308 | if (this.flags.not && undefined !== val) { 309 | if (undefined === this.obj[name]) { 310 | throw new Error(i(this.obj) + ' has no property ' + i(name)); 311 | } 312 | } else { 313 | this.assert( 314 | undefined !== this.obj[name] 315 | , 'expected ' + i(this.obj) + ' to have a property ' + i(name) 316 | , 'expected ' + i(this.obj) + ' to not have a property ' + i(name)); 317 | } 318 | 319 | if (undefined !== val) { 320 | this.assert( 321 | val === this.obj[name] 322 | , 'expected ' + i(this.obj) + ' to have a property ' + i(name) 323 | + ' of ' + i(val) + ', but got ' + i(this.obj[name]) 324 | , 'expected ' + i(this.obj) + ' to not have a property ' + i(name) 325 | + ' of ' + i(val)); 326 | } 327 | 328 | this.obj = this.obj[name]; 329 | return this; 330 | }; 331 | 332 | /** 333 | * Assert that the array contains _obj_ or string contains _obj_. 334 | * 335 | * @param {Mixed} obj|string 336 | * @api public 337 | */ 338 | 339 | Assertion.prototype.string = 340 | Assertion.prototype.contain = function (obj) { 341 | if ('string' == typeof this.obj) { 342 | this.assert( 343 | ~this.obj.indexOf(obj) 344 | , 'expected ' + i(this.obj) + ' to contain ' + i(obj) 345 | , 'expected ' + i(this.obj) + ' to not contain ' + i(obj)); 346 | } else { 347 | this.assert( 348 | ~indexOf(this.obj, obj) 349 | , 'expected ' + i(this.obj) + ' to contain ' + i(obj) 350 | , 'expected ' + i(this.obj) + ' to not contain ' + i(obj)); 351 | } 352 | return this; 353 | }; 354 | 355 | /** 356 | * Assert exact keys or inclusion of keys by using 357 | * the `.own` modifier. 358 | * 359 | * @param {Array|String ...} keys 360 | * @api public 361 | */ 362 | 363 | Assertion.prototype.key = 364 | Assertion.prototype.keys = function ($keys) { 365 | var str 366 | , ok = true; 367 | 368 | $keys = isArray($keys) 369 | ? $keys 370 | : Array.prototype.slice.call(arguments); 371 | 372 | if (!$keys.length) throw new Error('keys required'); 373 | 374 | var actual = keys(this.obj) 375 | , len = $keys.length; 376 | 377 | // Inclusion 378 | ok = every($keys, function (key) { 379 | return ~indexOf(actual, key); 380 | }); 381 | 382 | // Strict 383 | if (!this.flags.not && this.flags.only) { 384 | ok = ok && $keys.length == actual.length; 385 | } 386 | 387 | // Key string 388 | if (len > 1) { 389 | $keys = map($keys, function (key) { 390 | return i(key); 391 | }); 392 | var last = $keys.pop(); 393 | str = $keys.join(', ') + ', and ' + last; 394 | } else { 395 | str = i($keys[0]); 396 | } 397 | 398 | // Form 399 | str = (len > 1 ? 'keys ' : 'key ') + str; 400 | 401 | // Have / include 402 | str = (!this.flags.only ? 'include ' : 'only have ') + str; 403 | 404 | // Assertion 405 | this.assert( 406 | ok 407 | , 'expected ' + i(this.obj) + ' to ' + str 408 | , 'expected ' + i(this.obj) + ' to not ' + str); 409 | 410 | return this; 411 | }; 412 | 413 | /** 414 | * Function bind implementation. 415 | */ 416 | 417 | function bind (fn, scope) { 418 | return function () { 419 | return fn.apply(scope, arguments); 420 | } 421 | } 422 | 423 | /** 424 | * Array every compatibility 425 | * 426 | * @see bit.ly/5Fq1N2 427 | * @api public 428 | */ 429 | 430 | function every (arr, fn, thisObj) { 431 | var scope = thisObj || global; 432 | for (var i = 0, j = arr.length; i < j; ++i) { 433 | if (!fn.call(scope, arr[i], i, arr)) { 434 | return false; 435 | } 436 | } 437 | return true; 438 | }; 439 | 440 | /** 441 | * Array indexOf compatibility. 442 | * 443 | * @see bit.ly/a5Dxa2 444 | * @api public 445 | */ 446 | 447 | function indexOf (arr, o, i) { 448 | if (Array.prototype.indexOf) { 449 | return Array.prototype.indexOf.call(arr, o, i); 450 | } 451 | 452 | for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0 453 | ; i < j && arr[i] !== o; i++); 454 | 455 | return j <= i ? -1 : i; 456 | }; 457 | 458 | /** 459 | * Inspects an object. 460 | * 461 | * @see taken from node.js `util` module (copyright Joyent, MIT license) 462 | * @api private 463 | */ 464 | 465 | function i (obj, showHidden, depth) { 466 | var seen = []; 467 | 468 | function stylize (str) { 469 | return str; 470 | }; 471 | 472 | function format (value, recurseTimes) { 473 | // Provide a hook for user-specified inspect functions. 474 | // Check that value is an object with an inspect function on it 475 | if (value && typeof value.inspect === 'function' && 476 | // Filter out the util module, it's inspect function is special 477 | value !== exports && 478 | // Also filter out any prototype objects using the circular check. 479 | !(value.constructor && value.constructor.prototype === value)) { 480 | return value.inspect(recurseTimes); 481 | } 482 | 483 | // Primitive types cannot have properties 484 | switch (typeof value) { 485 | case 'undefined': 486 | return stylize('undefined', 'undefined'); 487 | 488 | case 'string': 489 | var simple = '\'' + json.stringify(value).replace(/^"|"$/g, '') 490 | .replace(/'/g, "\\'") 491 | .replace(/\\"/g, '"') + '\''; 492 | return stylize(simple, 'string'); 493 | 494 | case 'number': 495 | return stylize('' + value, 'number'); 496 | 497 | case 'boolean': 498 | return stylize('' + value, 'boolean'); 499 | } 500 | // For some reason typeof null is "object", so special case here. 501 | if (value === null) { 502 | return stylize('null', 'null'); 503 | } 504 | 505 | // Look up the keys of the object. 506 | var visible_keys = keys(value); 507 | var $keys = showHidden ? Object.getOwnPropertyNames(value) : visible_keys; 508 | 509 | // Functions without properties can be shortcutted. 510 | if (typeof value === 'function' && $keys.length === 0) { 511 | if (isRegExp(value)) { 512 | return stylize('' + value, 'regexp'); 513 | } else { 514 | var name = value.name ? ': ' + value.name : ''; 515 | return stylize('[Function' + name + ']', 'special'); 516 | } 517 | } 518 | 519 | // Dates without properties can be shortcutted 520 | if (isDate(value) && $keys.length === 0) { 521 | return stylize(value.toUTCString(), 'date'); 522 | } 523 | 524 | var base, type, braces; 525 | // Determine the object type 526 | if (isArray(value)) { 527 | type = 'Array'; 528 | braces = ['[', ']']; 529 | } else { 530 | type = 'Object'; 531 | braces = ['{', '}']; 532 | } 533 | 534 | // Make functions say that they are functions 535 | if (typeof value === 'function') { 536 | var n = value.name ? ': ' + value.name : ''; 537 | base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']'; 538 | } else { 539 | base = ''; 540 | } 541 | 542 | // Make dates with properties first say the date 543 | if (isDate(value)) { 544 | base = ' ' + value.toUTCString(); 545 | } 546 | 547 | if ($keys.length === 0) { 548 | return braces[0] + base + braces[1]; 549 | } 550 | 551 | if (recurseTimes < 0) { 552 | if (isRegExp(value)) { 553 | return stylize('' + value, 'regexp'); 554 | } else { 555 | return stylize('[Object]', 'special'); 556 | } 557 | } 558 | 559 | seen.push(value); 560 | 561 | var output = map($keys, function (key) { 562 | var name, str; 563 | if (value.__lookupGetter__) { 564 | if (value.__lookupGetter__(key)) { 565 | if (value.__lookupSetter__(key)) { 566 | str = stylize('[Getter/Setter]', 'special'); 567 | } else { 568 | str = stylize('[Getter]', 'special'); 569 | } 570 | } else { 571 | if (value.__lookupSetter__(key)) { 572 | str = stylize('[Setter]', 'special'); 573 | } 574 | } 575 | } 576 | if (indexOf(visible_keys, key) < 0) { 577 | name = '[' + key + ']'; 578 | } 579 | if (!str) { 580 | if (indexOf(seen, value[key]) < 0) { 581 | if (recurseTimes === null) { 582 | str = format(value[key]); 583 | } else { 584 | str = format(value[key], recurseTimes - 1); 585 | } 586 | if (str.indexOf('\n') > -1) { 587 | if (isArray(value)) { 588 | str = map(str.split('\n'), function (line) { 589 | return ' ' + line; 590 | }).join('\n').substr(2); 591 | } else { 592 | str = '\n' + map(str.split('\n'), function (line) { 593 | return ' ' + line; 594 | }).join('\n'); 595 | } 596 | } 597 | } else { 598 | str = stylize('[Circular]', 'special'); 599 | } 600 | } 601 | if (typeof name === 'undefined') { 602 | if (type === 'Array' && key.match(/^\d+$/)) { 603 | return str; 604 | } 605 | name = json.stringify('' + key); 606 | if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { 607 | name = name.substr(1, name.length - 2); 608 | name = stylize(name, 'name'); 609 | } else { 610 | name = name.replace(/'/g, "\\'") 611 | .replace(/\\"/g, '"') 612 | .replace(/(^"|"$)/g, "'"); 613 | name = stylize(name, 'string'); 614 | } 615 | } 616 | 617 | return name + ': ' + str; 618 | }); 619 | 620 | seen.pop(); 621 | 622 | var numLinesEst = 0; 623 | var length = reduce(output, function (prev, cur) { 624 | numLinesEst++; 625 | if (indexOf(cur, '\n') >= 0) numLinesEst++; 626 | return prev + cur.length + 1; 627 | }, 0); 628 | 629 | if (length > 50) { 630 | output = braces[0] + 631 | (base === '' ? '' : base + '\n ') + 632 | ' ' + 633 | output.join(',\n ') + 634 | ' ' + 635 | braces[1]; 636 | 637 | } else { 638 | output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; 639 | } 640 | 641 | return output; 642 | } 643 | return format(obj, (typeof depth === 'undefined' ? 2 : depth)); 644 | }; 645 | 646 | function isArray (ar) { 647 | return Object.prototype.toString.call(ar) == '[object Array]'; 648 | }; 649 | 650 | function isRegExp(re) { 651 | var s = '' + re; 652 | return re instanceof RegExp || // easy case 653 | // duck-type for context-switching evalcx case 654 | typeof(re) === 'function' && 655 | re.constructor.name === 'RegExp' && 656 | re.compile && 657 | re.test && 658 | re.exec && 659 | s.match(/^\/.*\/[gim]{0,3}$/); 660 | }; 661 | 662 | function isDate(d) { 663 | if (d instanceof Date) return true; 664 | return false; 665 | }; 666 | 667 | function keys (obj) { 668 | if (Object.keys) { 669 | return Object.keys(obj); 670 | } 671 | 672 | var keys = []; 673 | 674 | for (var i in obj) { 675 | if (Object.prototype.hasOwnProperty.call(obj, i)) { 676 | keys.push(i); 677 | } 678 | } 679 | 680 | return keys; 681 | } 682 | 683 | function map (arr, mapper, that) { 684 | if (Array.prototype.map) { 685 | return Array.prototype.map.call(arr, mapper, that); 686 | } 687 | 688 | var other= new Array(arr.length); 689 | 690 | for (var i= 0, n = arr.length; iPlease enter your search term:
5 | 9 | -------------------------------------------------------------------------------- /code-examples/testing/simple-testing/test-program/express-app/views/search.ejs: -------------------------------------------------------------------------------- 1 | 2 |No results
12 | <% } %> 13 | -------------------------------------------------------------------------------- /code-examples/testing/simple-testing/test-program/test.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module dependencies. 4 | */ 5 | 6 | var request = require('superagent') 7 | , assert = require('assert') 8 | 9 | /** 10 | * Tests /search?q=