From adf9d7b87d1dee95ddf18b41c89175d273b92521 Mon Sep 17 00:00:00 2001 From: Andrew Nichols Date: Wed, 16 Oct 2013 13:38:12 -0400 Subject: [PATCH 1/4] Getting started with tests for models --- app/package.json | 51 ++++++++++++++++++++++++--------------------- spec/player.spec.js | 14 +++++++++++++ 2 files changed, 41 insertions(+), 24 deletions(-) create mode 100644 spec/player.spec.js diff --git a/app/package.json b/app/package.json index 9fd52e0..6273076 100644 --- a/app/package.json +++ b/app/package.json @@ -1,24 +1,27 @@ -{ - "name": "Ping-Pong", - "version": "1.0.0", - "scripts": { - "start": "node app.js" - }, - "dependencies": { - "express": "3.3.7", - "ejs": "0.8.4", - "mongoose": "3.6.18", - "express-ejs-layouts": "0.3.1", - "stylus": "0.37.0", - "supertest": "0.7.1", - "expect.js": "0.2.0", - "nconf": "0.6.7", - "async": "0.2.9", - "nodemailer": "0.5.2", - "cron": "1.0.1", - "twitter": "0.2.2", - "winston": "0.7.2", - "mocha": "~1.13", - "MD5": "1.1.x" - } -} +{ + "name": "Ping-Pong", + "version": "1.0.0", + "scripts": { + "start": "node app.js" + }, + "dependencies": { + "express": "3.3.7", + "ejs": "0.8.4", + "mongoose": "3.6.18", + "express-ejs-layouts": "0.3.1", + "stylus": "0.37.0", + "supertest": "0.7.1", + "expect.js": "0.2.0", + "nconf": "0.6.7", + "async": "0.2.9", + "nodemailer": "0.5.2", + "cron": "1.0.1", + "twitter": "0.2.2", + "winston": "0.7.2", + "mocha": "~1.13", + "MD5": "1.1.x" + }, + "devDependencies": { + "sandboxed-module": "~0.2.2" + } +} diff --git a/spec/player.spec.js b/spec/player.spec.js new file mode 100644 index 0000000..9972083 --- /dev/null +++ b/spec/player.spec.js @@ -0,0 +1,14 @@ +var assert = require('assert'), + sandbox = require('./../node_modules/sandboxed-module'); + + Player = require('./../app/models/Player')(); + +var player = new Player({fname: 'Test', lname: 'Player', nickname: 'Hotness'}); + +describe("Player", function(){ + describe("#gravatar", function(){ + it("should return a gravatar url", function(done){ + done(); + }); + }); +}); From 26910d8e1704d674a25b2907eb83433526f3b145 Mon Sep 17 00:00:00 2001 From: Andrew Nichols Date: Fri, 18 Oct 2013 21:37:00 -0400 Subject: [PATCH 2/4] Work in progress --- app/models/Player.js | 2 +- app/package.json | 10 ++-- spec/player.spec.js | 131 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 132 insertions(+), 11 deletions(-) diff --git a/app/models/Player.js b/app/models/Player.js index f89c61b..1b98ec5 100644 --- a/app/models/Player.js +++ b/app/models/Player.js @@ -25,7 +25,7 @@ module.exports = function(mongoose) { }); playerSchema.virtual('displayName').get(function(){ - return this.fname + ' ' + this.nickname + ' ' + this.lname; + return this.fname + ' "' + this.nickname + '" ' + this.lname; }); playerSchema.virtual('fullName').get(function(){ diff --git a/app/package.json b/app/package.json index 6273076..185e3b9 100644 --- a/app/package.json +++ b/app/package.json @@ -10,18 +10,20 @@ "mongoose": "3.6.18", "express-ejs-layouts": "0.3.1", "stylus": "0.37.0", - "supertest": "0.7.1", - "expect.js": "0.2.0", "nconf": "0.6.7", "async": "0.2.9", "nodemailer": "0.5.2", "cron": "1.0.1", "twitter": "0.2.2", "winston": "0.7.2", - "mocha": "~1.13", "MD5": "1.1.x" }, "devDependencies": { - "sandboxed-module": "~0.2.2" + "expect.js": "0.2.0", + "supertest": "0.7.1", + "mocha": "~1.13", + "sandboxed-module": "~0.2.2", + "jasmine-node": "~1.11.0", + "jasmine-stealth": "0.0.13" } } diff --git a/spec/player.spec.js b/spec/player.spec.js index 9972083..2ca0681 100644 --- a/spec/player.spec.js +++ b/spec/player.spec.js @@ -1,14 +1,133 @@ -var assert = require('assert'), - sandbox = require('./../node_modules/sandboxed-module'); +require('../app/node_modules/jasmine-stealth'); +var sandbox = require('./../app/node_modules/sandboxed-module'), + md5 = jasmine.createSpy("MD5"), + async = jasmine.createSpyObj("async", ["eachSeries"]), + mongoose = require("./../app/node_modules/mongoose"), + schema = sandbox.require("./../app/models/Player", { + requires: { + MD5: md5, + async: async + } + }), + Player = schema(mongoose).Players; - Player = require('./../app/models/Player')(); +var player = new Player({ + fname: 'Test', + lname: 'Player', + nickname: 'Hotness', + email: "hotness@email.com", + wins: 6, + losses: 6, + streak: -1 +}); + +var player2 = new Player({ + fname: 'Foo', + lname: 'Baby', + nickname: 'Bar', + streak: 4 +}); -var player = new Player({fname: 'Test', lname: 'Player', nickname: 'Hotness'}); +var countCallback, recalculateCallback, query; describe("Player", function(){ - describe("#gravatar", function(){ + + describe("#gravatar", function(){ + beforeEach(function(){ + md5.when("hotness@email.com").thenReturn("md5hotness"); + }); + it("should return a gravatar url", function(done){ + expect(player.gravatar).toBe('http://www.gravatar.com/avatar/md5hotness?d=mm'); + done(); + }); + }); + + describe("#displayName", function(){ + it("should return a player's display name", function(done){ + expect(player.displayName).toBe('Test "Hotness" Player'); + done(); + }); + }); + + describe("#fullname", function(){ + it("should return a player's full name", function(done){ + expect(player.fullName).toBe("Test Player"); + done(); + }); + }); + + describe("#matchesPlayed", function(){ + it("should return the number of games a player has played", function(done){ + expect(player.matchesPlayed).toBe(12); + done(); + }); + }); + + describe("#ratio", function(){ + it("should return a player's win percentage", function(done){ + expect(player.ratio).toBe((50).toFixed(1)); done(); }); - }); + }); + + describe("#currentStreak", function(){ + it("should return a Lx when negative", function(done){ + expect(player.currentStreak).toBe("L1"); + done(); + }); + + it("should return a Wx when positive", function(done){ + expect(player2.currentStreak).toBe("W4"); + done(); + }); + }); + + describe("#recalculateWins", function(){ + beforeEach(function(){ + countCallback = jasmine.captor(); + recalculateCallback = jasmine.createSpy("recalculateWinsCallback"); + query = jasmine.createSpyObj("mongooseQuery", ["count"]); + spyOn(mongoose, "model").andReturn(query); + spyOn(player, "save").andCallFake(function(){ + recalculateCallback(null, player); + }); + }); + + it("should return the correct number of wins", function(done){ + player.recalculateWins(recalculateCallback); + expect(query.count).toHaveBeenCalledWith(jasmine.any(Object), countCallback.capture()); + countCallback.value(null, 8); + expect(player.wins).toBe(8); + expect(recalculateCallback).toHaveBeenCalledWith(null, player); + done(); + }); + }); + + describe("#recalculateLosses", function(){ + beforeEach(function(){ + countCallback = jasmine.captor(); + recalculateCallback = jasmine.createSpy("recalculateLossesCallback"); + + query = jasmine.createSpyObj("mongooseQuery", ["count"]); + spyOn(mongoose, "model").andReturn(query); + spyOn(player, "save").andCallFake(function(){ + console.log("save called"); + recalculateCallback(null, player); + }); + }); + + it("should return the correct number of losses", function(done){ + console.log("running recalculateLosses test"); + player.recalculateLosses(recalculateCallback); + recalculateCallback.when(null, player).thenCallFake(function(){ + console.log("callback called"); + expect(query.count).toHaveBeenCalledWith(jasmine.any(Object), countCallback.capture()); + countCallback.value(null, 3); + expect(p.wins).toBe(3); + expect(err).toBe(null); + done(); + }); + }); + }); }); From 70a03fd47642c6bafd5ecb685a608aa65b7fa40b Mon Sep 17 00:00:00 2001 From: Andrew Nichols Date: Tue, 22 Oct 2013 16:20:55 -0400 Subject: [PATCH 3/4] Most tests done --- app/models/Player.js | 5 +-- spec/player.spec.js | 93 ++++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 50 deletions(-) diff --git a/app/models/Player.js b/app/models/Player.js index 1b98ec5..0b2570e 100644 --- a/app/models/Player.js +++ b/app/models/Player.js @@ -91,10 +91,7 @@ module.exports = function(mongoose) { } else { f('break'); } - } else { - console.log('neither one matches??????'); - f(); - } + } }, function(err){ if (err && err != 'break') { cb(err); diff --git a/spec/player.spec.js b/spec/player.spec.js index 2ca0681..12155b5 100644 --- a/spec/player.spec.js +++ b/spec/player.spec.js @@ -1,16 +1,34 @@ +// Dependencies require('../app/node_modules/jasmine-stealth'); -var sandbox = require('./../app/node_modules/sandboxed-module'), - md5 = jasmine.createSpy("MD5"), - async = jasmine.createSpyObj("async", ["eachSeries"]), - mongoose = require("./../app/node_modules/mongoose"), - schema = sandbox.require("./../app/models/Player", { - requires: { - MD5: md5, - async: async - } - }), - Player = schema(mongoose).Players; +var sandbox = require('./../app/node_modules/sandboxed-module'); +var realMongoose = require("./../app/node_modules/mongoose"); +var md5 = jasmine.createSpy("MD5"); +var async = jasmine.createSpyObj("async", ["eachSeries"]); +var mongoose = jasmine.createSpyObj("mongoose", ["Schema", "model", "count"]); +var schema = sandbox.require("./../app/models/Player", { + requires: { + MD5: md5, + async: async + } +}); + +// Setup spy methods +mongoose.Schema.andCallFake(function(){ + return realMongoose.Schema.apply(realMongoose, arguments); +}); +mongoose.model.andCallFake(function(name, schema){ + if (name === "players"){ + return realMongoose.model.apply(realMongoose, arguments); + } else if (name === "matches"){ + return mongoose; + } +}); +mongoose.count.andCallFake(function(params, cb){ + cb(null, 12); +}); +// Create fake players +var Player = schema(mongoose).Players; var player = new Player({ fname: 'Test', lname: 'Player', @@ -20,21 +38,20 @@ var player = new Player({ losses: 6, streak: -1 }); - var player2 = new Player({ fname: 'Foo', lname: 'Baby', nickname: 'Bar', + wins: 4, + losses: 4, streak: 4 }); -var countCallback, recalculateCallback, query; - describe("Player", function(){ - describe("#gravatar", function(){ - beforeEach(function(){ + beforeEach(function(done){ md5.when("hotness@email.com").thenReturn("md5hotness"); + done(); }); it("should return a gravatar url", function(done){ @@ -84,48 +101,32 @@ describe("Player", function(){ }); describe("#recalculateWins", function(){ - beforeEach(function(){ - countCallback = jasmine.captor(); - recalculateCallback = jasmine.createSpy("recalculateWinsCallback"); - query = jasmine.createSpyObj("mongooseQuery", ["count"]); - spyOn(mongoose, "model").andReturn(query); - spyOn(player, "save").andCallFake(function(){ - recalculateCallback(null, player); + beforeEach(function(done){ + spyOn(player, "save").andCallFake(function(cb){ + cb(null, player); }); + done(); }); it("should return the correct number of wins", function(done){ - player.recalculateWins(recalculateCallback); - expect(query.count).toHaveBeenCalledWith(jasmine.any(Object), countCallback.capture()); - countCallback.value(null, 8); - expect(player.wins).toBe(8); - expect(recalculateCallback).toHaveBeenCalledWith(null, player); - done(); + player.recalculateWins(function(err, p){ + expect(p.wins).toBe(12); + done(); + }); }); }); describe("#recalculateLosses", function(){ - beforeEach(function(){ - countCallback = jasmine.captor(); - recalculateCallback = jasmine.createSpy("recalculateLossesCallback"); - - query = jasmine.createSpyObj("mongooseQuery", ["count"]); - spyOn(mongoose, "model").andReturn(query); - spyOn(player, "save").andCallFake(function(){ - console.log("save called"); - recalculateCallback(null, player); + beforeEach(function(done){ + spyOn(player, "save").andCallFake(function(cb){ + cb(null, player); }); + done(); }); it("should return the correct number of losses", function(done){ - console.log("running recalculateLosses test"); - player.recalculateLosses(recalculateCallback); - recalculateCallback.when(null, player).thenCallFake(function(){ - console.log("callback called"); - expect(query.count).toHaveBeenCalledWith(jasmine.any(Object), countCallback.capture()); - countCallback.value(null, 3); - expect(p.wins).toBe(3); - expect(err).toBe(null); + player.recalculateLosses(function(err, p){ + expect(p.losses).toBe(12); done(); }); }); From ba48ae51d794fe088f8cfd9b4b7f38aeaa679fd9 Mon Sep 17 00:00:00 2001 From: Andrew Nichols Date: Tue, 22 Oct 2013 16:51:30 -0400 Subject: [PATCH 4/4] Don't need to mock async probably --- spec/player.spec.js | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/spec/player.spec.js b/spec/player.spec.js index 12155b5..5688026 100644 --- a/spec/player.spec.js +++ b/spec/player.spec.js @@ -3,14 +3,8 @@ require('../app/node_modules/jasmine-stealth'); var sandbox = require('./../app/node_modules/sandboxed-module'); var realMongoose = require("./../app/node_modules/mongoose"); var md5 = jasmine.createSpy("MD5"); -var async = jasmine.createSpyObj("async", ["eachSeries"]); var mongoose = jasmine.createSpyObj("mongoose", ["Schema", "model", "count"]); -var schema = sandbox.require("./../app/models/Player", { - requires: { - MD5: md5, - async: async - } -}); +var schema = sandbox.require("./../app/models/Player", { requires: { MD5: md5 } }); // Setup spy methods mongoose.Schema.andCallFake(function(){