Skip to content

Commit

Permalink
Major spec overhaul:
Browse files Browse the repository at this point in the history
More loose coupling
More AppController testing
Started testing AppView
  • Loading branch information
molily committed Apr 4, 2012
1 parent f3beeaf commit b813fee
Show file tree
Hide file tree
Showing 12 changed files with 302 additions and 122 deletions.
13 changes: 5 additions & 8 deletions test/index.html
Expand Up @@ -6,6 +6,7 @@
</head>
<body>

<div id="jasmine-root"></div>
<div id="fb-root"></div>

<script src="../js/vendor/jquery-1.7.2.js"></script>
Expand All @@ -18,7 +19,7 @@
<script>
(function () {

var reporter = new jasmine.TrivialReporter();
var reporter = new jasmine.TrivialReporter(document.getElementById('jasmine-root'));
//jasmineEnv.specFilter = trivialReporter.specFilter.bind(trivialReporter);
var jasmineEnv = new jasmine.getEnv();
jasmineEnv.addReporter(reporter);
Expand All @@ -37,14 +38,10 @@
'../test/spec/js/mediator_spec'
, '../test/spec/js/router_spec'
, '../test/spec/js/application_spec'
, '../test/spec/js/application_controller_spec'
, '../test/spec/js/application_view_spec'
], function () {
// The order plugin does not seem to play well with the text plugin.
// Enforce the order manually. These specs need to run after the
require([
'../test/spec/js/application_controller_spec'
], function () {
jasmineEnv.execute();
});
jasmineEnv.execute();
});

})();
Expand Down
17 changes: 6 additions & 11 deletions test/lib/jasmine-1.1.0/jasmine-html.js
@@ -1,5 +1,5 @@
jasmine.TrivialReporter = function(doc) {
this.document = doc || document;
jasmine.TrivialReporter = function(rootElement) {
this.rootElement = rootElement || document.body;
this.suiteDivs = {};
this.logRunningSpecs = false;
};
Expand Down Expand Up @@ -51,7 +51,8 @@ jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
);

this.document.body.appendChild(this.outerDiv);
this.rootElement.innerHTML = '';
this.rootElement.appendChild(this.outerDiv);

var suites = runner.suites();
for (var i = 0; i < suites.length; i++) {
Expand Down Expand Up @@ -90,9 +91,7 @@ jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
var results = runner.results();
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
this.runnerDiv.setAttribute("class", className);
//do it twice for IE
this.runnerDiv.setAttribute("className", className);
this.runnerDiv.className = className
var specs = runner.specs();
var specCount = 0;
for (var i = 0; i < specs.length; i++) {
Expand Down Expand Up @@ -171,13 +170,9 @@ jasmine.TrivialReporter.prototype.log = function() {
}
};

jasmine.TrivialReporter.prototype.getLocation = function() {
return this.document.location;
};

jasmine.TrivialReporter.prototype.specFilter = function(spec) {
var paramMap = {};
var params = this.getLocation().search.substring(1).split('&');
var params = jasmine.getGlobal().location.search.substring(1).split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
Expand Down
71 changes: 57 additions & 14 deletions test/spec/coffee/application_controller_spec.coffee
@@ -1,17 +1,34 @@
define [
'mediator', 'lib/router', 'application', 'controllers/controller', 'controllers/application_controller'
], (mediator, Router, Application, Controller, ApplicationController) ->
'mediator', 'controllers/controller', 'controllers/application_controller'
], (mediator, Controller, ApplicationController) ->
'use strict'

describe 'ApplicationController', ->
#console.debug 'ApplicationController spec'

initializeCalled = actionCalled = historyURLCalled = false
applicationController = undefined

initializeCalled = actionCalled =
historyURLCalled = disposeCalled = undefined
params = passedParams = undefined
# Unique ID counter for creating params objects
paramsId = 0

resetFlags = ->
initializeCalled = actionCalled =
historyURLCalled = disposeCalled = false

freshParams = ->
# Create a fresh params object which does not equal the previous one
params = changeURL: false, id: paramsId++
passedParams = undefined

# Fake route object, walks like a route and swims like a route
route = controller: 'test', action: 'show'

# Clear the mediator
mediator.unsubscribe()

# Define a test controller
class TestController extends Controller

Expand All @@ -22,19 +39,27 @@ define [

initialize: ->
#console.debug 'TestController#initialize'
super
initializeCalled = true

show: (params) ->
#console.debug 'TestController#show', params
actionCalled = true
passedParams = params

dispose: ->
disposeCalled = true
super

# Define a test controller module
define 'controllers/test_controller', (Controller) -> TestController

beforeEach ->
# Create a fresh params object which does not equal the previous one
params = changeURL: false, id: Math.random().toString().replace('0.', '')
resetFlags()
freshParams()

it 'should initialize', ->
applicationController = new ApplicationController()

it 'should dispatch routes to controller actions', ->
mediator.publish 'matchRoute', route, params
Expand All @@ -43,9 +68,27 @@ define [
expect(historyURLCalled).toBe true
expect(passedParams).toBe params

it 'should start a controller anyway when forced', ->
mediator.publish 'matchRoute', route, params
resetFlags()
params.forceStartup = true
mediator.publish 'matchRoute', route, params

expect(initializeCalled).toBe true
expect(actionCalled).toBe true
expect(historyURLCalled).toBe true
expect(passedParams).toBe params

it 'should dispose old controllers', ->
controller = undefined
handler = (passedController) ->
controller = passedController
mediator.subscribe 'beforeControllerDispose', handler
mediator.publish 'matchRoute', route, params

it 'should save the current controller, action and params', ->
mediator.publish 'matchRoute', route, params
c = Application.applicationController
c = applicationController
expect(c.previousControllerName).toBe 'test'
expect(c.currentControllerName).toBe 'test'
expect(c.currentController instanceof TestController).toBe true
Expand All @@ -54,16 +97,16 @@ define [
expect(c.url).toBe "test/#{params.id}"

it 'should publish startupController events', ->
passedEvent = undefined
handler = (event) ->
passedEvent = event
event = undefined
handler = (passedEvent) ->
event = passedEvent

mediator.subscribe 'startupController', handler
mediator.publish 'matchRoute', route, params
mediator.unsubscribe 'startupController', handler

expect(typeof passedEvent).toBe 'object'
expect(passedEvent.controller instanceof TestController).toBe true
expect(passedEvent.controllerName).toBe 'test'
expect(passedEvent.params).toBe params
expect(passedEvent.previousControllerName).toBe 'test'
expect(typeof event).toBe 'object'
expect(event.controller instanceof TestController).toBe true
expect(event.controllerName).toBe 'test'
expect(event.params).toBe params
expect(event.previousControllerName).toBe 'test'
10 changes: 1 addition & 9 deletions test/spec/coffee/application_spec.coffee
Expand Up @@ -25,17 +25,9 @@ define [
it 'should create a router on the mediator', ->
expect(mediator.router instanceof Router).toEqual true

it 'should create a readonly router', ->
return unless Object.defineProperty
expect(->
mediator.router = 'foo'
).toThrow()
desc = Object.getOwnPropertyDescriptor mediator, 'router'
expect(desc.writable).toBe false

it 'should start Backbone.history', ->
expect(Backbone.History.started).toBe true

it 'should be frozen', ->
return unless Object.isFrozen
return unless Object.isFrozen
expect(Object.isFrozen(Application)).toBe true
18 changes: 18 additions & 0 deletions test/spec/coffee/application_view_spec.coffee
@@ -0,0 +1,18 @@
define [
'mediator', 'controllers/controller', 'views/application_view'
], (mediator, Controller, ApplicationView) ->
'use strict'

describe 'ApplicationView', ->
applicationView = undefined

# Clear the mediator
mediator.unsubscribe()

testController = new Controller()

it 'should initialize', ->
applicationView = new ApplicationView()

xit 'should be tested more thoroughly', ->
expect(false).toBe true
70 changes: 44 additions & 26 deletions test/spec/coffee/mediator_spec.coffee
@@ -1,8 +1,10 @@
define [
'mediator'
], (mediator) ->
'lib/create_mediator', 'models/model'
], (createMediator, Model) ->
'use strict'

mediator = createMediator()

describe 'mediator', ->
#console.debug 'mediator spec'

Expand All @@ -13,26 +15,6 @@ define [
return unless Object.isSealed
expect(Object.isSealed(mediator)).toBe true

it 'should have a router which is null', ->
expect(mediator.router).toBeNull()

it 'should have a user which is null', ->
expect(mediator.user).toBeNull()

it 'should have a readonly user', ->
return unless Object.defineProperty
expect(->
mediator.user = 'foo'
).toThrow()

it 'should have a setUser method', ->
expect(typeof mediator.setUser).toEqual 'function'

it 'should have a user after calling setUser', ->
user = {}
mediator.setUser user
expect(mediator.user).toBe user

it 'should have Pub/Sub methods', ->
expect(typeof mediator.subscribe).toEqual 'function'
expect(typeof mediator.unsubscribe).toEqual 'function'
Expand All @@ -49,26 +31,62 @@ define [
return unless Object.getOwnPropertyDescriptor
methods.forEach (property) ->
desc = Object.getOwnPropertyDescriptor(mediator, property)
expect(desc.enumerable).toBe true
expect(desc.writable).toBe false

it 'should be sealed', ->
if Object.isSealed
expect(Object.isSealed(mediator)).toBe true
expect(desc.configurable).toBe false

it 'should publish messages to subscribers', ->
callback = jasmine.createSpy()
eventName = 'foo'
payload = 'payload'

mediator.subscribe eventName, callback
mediator.publish eventName, payload

expect(callback).toHaveBeenCalledWith payload
mediator.unsubscribe eventName, callback

it 'should allow to unsubscribe to events', ->
callback = jasmine.createSpy()
eventName = 'foo'
payload = 'payload'

mediator.subscribe eventName, callback
mediator.unsubscribe eventName, callback
mediator.publish eventName, payload

expect(callback).not.toHaveBeenCalledWith payload

it 'should have a user which is null', ->
expect(mediator.user).toBeNull()

it 'should have a readonly user', ->
return unless Object.defineProperty
expect(->
mediator.user = 'foo'
).toThrow()

it 'should have a setUser method', ->
expect(typeof mediator.setUser).toEqual 'function'

it 'should have a user after calling setUser', ->
user = new Model
mediator.setUser user
expect(mediator.user).toBe user

it 'should have a router which is null', ->
expect(mediator.router).toBeNull()

it 'should have a readonly router', ->
return unless Object.defineProperty
expect(->
mediator.router = 'foo'
).toThrow()

it 'should have a setRouter method', ->
expect(typeof mediator.setRouter).toEqual 'function'

it 'should have a user after calling setUser', ->
router = { fakeRouter: true }
mediator.setRouter router
expect(mediator.router).toBe router
23 changes: 23 additions & 0 deletions test/spec/coffee/router_spec2.coffee
@@ -0,0 +1,23 @@
define ['lib/create_mediator', 'mediator'], (createMediator, originalMediator) ->
'use strict'

mockMediator = createMediator()
define 'mediator', () -> mockMediator

require ['lib/router'], (Router) ->
console.debug 'Router loaded'
router = new Router

describe 'Router and Route', ->
console.debug 'describe Router and Route'
it 'should fire a matchRoute event', ->
matchRoute = jasmine.createSpy()
fakeMediator.subscribe 'matchRoute', matchRoute
router.match '', 'x#y'
router.route '/'
expect(matchRoute).toHaveBeenCalled()
fakeMediator.unsubscribe 'matchRoute', matchRoute

jasmineEnv.execute()

define 'mediator', -> originalMediator

0 comments on commit b813fee

Please sign in to comment.