Created
July 9, 2014 02:31
-
-
Save maxbeatty/13da72529895ed4522ec to your computer and use it in GitHub Desktop.
Promises make dealing with validation + AJAX cases a breeze when testing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
saveDraft: -> $.Deferred (deferred) => | |
# do validation | |
validationError = @validate() | |
if validationError | |
# use deferred to return immediately with failure | |
return deferred.reject validationError | |
$.post @url, @toJSON() | |
.done (payload, response, options) -> | |
# things went well | |
deferred.resolve() | |
.fail (jqXHR, textStatus, errorThrown) -> | |
# poop | |
try | |
res = JSON.parse jqXHR.responseText | |
msg = if res.error then res.error else res | |
catch e | |
msg = jqXHR.responseText | |
# tell whomever about the failure | |
deferred.reject msg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe 'saveDraft', -> | |
beforeEach -> | |
# stub anything not in the method we're testing | |
@validateStub = sinon.stub(@collection, 'validate').returns undefined | |
it 'should reject if validation error', (done) -> | |
# control the fail case (returns anything) | |
@validateStub.returns 'test msg' | |
# use promise chaining for assertions | |
@collection.saveDraft().fail (msg) -> | |
msg.should.equal 'test msg' | |
done() | |
it 'should reject if post fails', (done) -> | |
# validate is taken care of for us in the beforeEach | |
# control jQuery AJAX by returning a Deferred that we can control (reject) | |
sinon.stub($, 'post').returns do -> $.Deferred().reject('test').promise() | |
# use promise chaining for assertion | |
@collection.saveDraft().fail (msg) -> | |
msg.should.equal 'test' | |
done() | |
# what it ends up looking like without explainer comments: | |
it 'should succeed', (done) -> | |
sinon.stub($, 'post').returns do -> $.Deferred().resolve().promise() | |
@collection.saveDraft().done done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# view method triggered by click event on button | |
saveDraft: -> | |
# change UI | |
@$clBtn.button('loading') | |
# do data things | |
@collection.saveDraft().fail (msg) => | |
# if data things go wrong... | |
@makeUnsaved() | |
alert msg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# the same promise-based concepts work for our view as well since Deferreds are returned up the stack | |
describe 'saveDraft', -> | |
it 'should make unsaved and alert if saving fails', (done) -> | |
sinon.stub(@collection, 'saveDraft').returns do -> $.Deferred().reject('test').promise() | |
@view.saveDraft().fail (msg) -> | |
msg.should.equal 'test' | |
done() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment