Reputation: 15662
I have a file app.coffee
:
class TaskList
class Task
constructor: (@name) ->
@status = 'incomplete'
complete: ->
if @parent? and @parent.status isnt 'completed'
throw "Dependent task '#{@parent.name}' is not completed."
@status = 'complete'
true
dependsOn: (@parent) ->
@parent.child = @
@status = 'dependent'
# Prepare scope stuff
root = exports ? window
root.TaskList = TaskList
root.Task = Task
and a file called test/taskTest.coffee
:
{TaskList, Task} = require '../app'
should = require 'should'
describe 'Task Instance', ->
task1 = task2 = null
it 'should have a name', ->
something = 'asdf'
something.should.equal 'asdf'
task1 = new Task 'feed the cat'
task1.name.should.equal 'feed the cat'
it 'should be initially incomplete', ->
task1.status.should.equal 'incomplete'
it 'should be able to be completed', ->
task1.complete().should.be.true
task1.status.should.equal 'complete'
it 'should be able to be dependent on another task', ->
task1 = new Task 'wash dishes'
task2 = new Task 'dry dishes'
task2.dependsOn task1
task2.status.should.equal 'dependent'
task2.parent.should.equal task1
task1.child.should.equal task2
it 'should refuse completion it is dependent on an uncompleted task', ->
(-> task2.complete()).should.throw "Dependent task 'wash dishes' is not completed."
If I run this command in terminal: mocha -r should --compilers coffee:coffee-script -R spec
I have a failing test (the final one) saying that it was expecting an exception "Dependent task 'wash dishes' is not completed." but got 'undefined'.
If I change (-> task2.complete()).should.throw
to -> task2.complete().should.throw
by removing the parenthesis, the test passes, and fails if I don't throw the exception. But if I change the exception message to something random, it still passes. Am I doing something wrong? Shouldn't the test only pass if the message is literally "Dependent task 'wash dishes' is not completed."?
Upvotes: 8
Views: 5855
Reputation: 3639
First off, that's some good looking Coffeescript.
Second, David Weldon is correct in his answer that you can just change the throw to actually throw an error and it works.
Here's your code put into one long file with just the throw changed.
class TaskList
class Task
constructor: (@name) ->
@status = 'incomplete'
complete: ->
if @parent? and @parent.status isnt 'completed'
throw new Error "Dependent task '#{@parent.name}' is not completed."
@status = 'complete'
true
dependsOn: (@parent) ->
@parent.child = @
@status = 'dependent'
# Prepare scope stuff
root = exports ? window
root.TaskList = TaskList
root.Task = Task
should = require 'should'
describe 'Task Instance', ->
task1 = task2 = null
it 'should have a name', ->
something = 'asdf'
something.should.equal 'asdf'
task1 = new Task 'feed the cat'
task1.name.should.equal 'feed the cat'
it 'should be initially incomplete', ->
task1.status.should.equal 'incomplete'
it 'should be able to be completed', ->
task1.complete().should.be.true
task1.status.should.equal 'complete'
it 'should be able to be dependent on another task', ->
task1 = new Task 'wash dishes'
task2 = new Task 'dry dishes'
task2.dependsOn task1
task2.status.should.equal 'dependent'
task2.parent.should.equal task1
task1.child.should.equal task2
it 'should refuse completion it is dependent on an uncompleted task', ->
(-> task2.complete()).should.throw "Dependent task 'wash dishes' is not completed."
Mocha that bastard and you're good to go.
Upvotes: 3
Reputation: 64342
You are throwing an exception with a string instead of throwing an error object. throw()
looks for the latter. So your original code works if you do:
throw new Error "Dependent task '#{@parent.name}' is not completed."
If something you write in CoffeeScript is producing results that make no sense, try compiling it to js (or pasting the code into try CoffeeScript. You'll see that:
-> task2.complete().should.throw "Dependent task 'wash dishes' is not completed."
compiles to:
(function() {
return task2.complete().should["throw"]("Dependent task 'wash dishes' is not completed.");
});
which just defines a function and does not execute it. This explains why changing the string makes no difference. I hope that helps.
Upvotes: 4