modularity-framework
Version:
Lightweight component-oriented Web UI framework
273 lines (196 loc) • 8.97 kB
text/coffeescript
require './spec_helper'
# A module for testing.
class TestModule extends modularity.Module
describe 'modularity.Module', ->
beforeEach ->
template = """
<div id="module_container">
<div class="inside_module"></div>
</div>
<div class="outside_module"></div>
<div class="double"></div>
<div class="double"></div>
"""
$('body').html template
sinon.stub console, 'error'
afterEach ->
console.error.restore()
describe 'constructor', ->
it "is defined on the 'window' object", ->
expect(modularity.Module).to.not.be.undefined
it 'shows an error if no container is given', ->
new TestModule()
expect(console.error).to.have.been.called
it 'tries to load the DOM if the given container is a string', ->
new TestModule('#module_container')
expect(console.error).to.not.have.been.called
it 'shows an error if the container is not a jQuery object', ->
new TestModule({})
expect(console.error).to.have.been.called
it 'shows an error if the container is an empty jQuery object', ->
new TestModule($('.zonk'))
expect(console.error).to.have.been.called
it 'shows an error if the container has more than one elements', ->
new TestModule($('.double'))
expect(console.error).to.have.been.called
it "allows to provide 'testing' in tests", ->
new TestModule('testing')
expect(console.error).to.not.have.been.called
describe '@$', ->
it 'returns a new jQuery object relative to container', ->
module = new TestModule $ '#module_container'
insideObject = module.$ '.inside_module,.outside_module'
expect(insideObject.length).to.equal 1
expect(insideObject.hasClass('inside_module')).to.be.true
it 'signals an empty result set through an error message', ->
module = new TestModule $ '#module_container'
insideObject = module.$ '.zonk'
expect(console.error.callCount).to.equal 1
describe 'reportEmptyResults option set to no', ->
it 'does not signal an empty result set', ->
module = new TestModule $ '#module_container'
insideObject = module.$ '.zonk', reportEmptyResults: no
expect(console.error.callCount).to.equal 0
describe 'event handling', ->
beforeEach ->
@mockContainer = $('#module_container')
@module = new TestModule(@mockContainer)
describe 'on', ->
beforeEach ->
sinon.spy @mockContainer, 'bind'
it 'binds the given custom jQuery event type and the given callback to the container', ->
myCallback = ->
@module.on 'myEventType', myCallback
expect(@mockContainer.bind).to.have.been.called
expect(@mockContainer.bind.args[0][0]).to.equal 'myEventType'
expect(@mockContainer.bind.args[0][1]).to.equal myCallback
expect(console.error).to.not.have.been.called
it "throws an error if no parameters are given", ->
@module.on()
expect(console.error).to.have.been.called
expect(@mockContainer.bind).to.not.have.been.called
it "throws an error if the given event type doesn't exist", ->
@module.on undefined, ->
expect(console.error).to.have.been.called
expect(@mockContainer.bind).to.not.have.been.called
it 'throws an error if the given event type is not a string', ->
@module.on {}, ->
expect(console.error).to.have.been.called
expect(@mockContainer.bind).to.not.have.been.called
it "throws an error if the given callback doesn't exist", ->
@module.on '123'
expect(console.error).to.have.been.called
expect(@mockContainer.bind).to.not.have.been.called
it 'throws an error if the given callback is not a function', ->
@module.on '123', {}
expect(console.error).to.have.been.called
expect(@mockContainer.bind).to.not.have.been.called
it 'returns the object for chaining', ->
expect(@module.on 'event type', ->).to.eql @module
describe 'trigger', ->
beforeEach ->
sinon.spy @mockContainer, 'trigger'
it 'triggers a custom jQuery event with the given event type on the container object', ->
@module.trigger 'event type', 'event data'
expect(@mockContainer.trigger).to.have.been.called
expect(@mockContainer.trigger.args[0][0]).to.equal 'event type'
expect(@mockContainer.trigger.args[0][1]).to.equal 'event data'
describe 'when no payload is given', ->
it 'provides an empty object as payload', ->
@module.trigger 'event type'
expect(@mockContainer.trigger).to.have.been.called
expect(@mockContainer.trigger.args[0][1]).to.eql({})
it "doesn't change the original payload variable", ->
data = undefined
@module.trigger 'event type', data
expect(data).to.be.undefined
it 'provides 0 as payload if 0 is given', ->
@module.trigger 'event type', 0
expect(@mockContainer.trigger).to.have.been.called
expect(@mockContainer.trigger.args[0][1]).to.equal(0)
it 'throws an error if the given event type is not a string', ->
@module.trigger {}
expect(@mockContainer.trigger).to.not.have.been.called
expect(console.error).to.have.been.called
it 'returns the object for chaining', ->
expect(@module.trigger 'event type', 'event data').to.eql @module
describe 'mixins', ->
recordedSelf = null
myMixin =
constructor: -> recordedSelf = @
method1: ->
method2: ->
beforeEach ->
class @Test extends modularity.Module
@mixin myMixin
it 'adds all methods from the mixin object to the class prototype', ->
instance = new @Test('testing')
expect(instance.method1).to.be.a("function")
it 'calls the proper mixin method when calling from the implementing module', ->
sinon.spy myMixin, 'method1'
sinon.spy myMixin, 'method2'
instance = new @Test('testing')
instance.method1()
expect(myMixin.method1).to.have.been.called
expect(myMixin.method2).to.not.have.been.called
myMixin.method1.restore()
myMixin.method2.restore()
it 'calls the mixin with the proper paramaters', ->
sinon.spy myMixin, 'method1'
instance = new @Test('testing')
instance.method1("arg1", "arg2")
expect(myMixin.method1.calledWith("arg1", "arg2")).to.be.true
myMixin.method1.restore()
it 'calls the constructor of the mixin', ->
sinon.spy myMixin, 'constructor'
instance = new @Test('testing')
expect(myMixin.constructor).to.have.been.called
it 'calls the constructor with the this object pointing to the instance', ->
instance = new @Test('testing')
expect(recordedSelf).to.equal instance
it "can handle mixins that don't define a constructor"
it "shows an error message if the given mixin is undefined"
it 'provides arguments to the @mixin method to the mixin constructor'
describe 'hide', ->
it 'makes the container of the module invisible', ->
module = new TestModule '#module_container'
expect(module.container).to.be.visible
module.hide()
expect(module.container).to.not.be.visible
it 'triggers a "hide" event on the container', ->
@mockContainer = $('#module_container')
@module = new TestModule @mockContainer
sinon.spy @mockContainer, 'trigger'
@module.hide()
expect(@mockContainer.trigger).to.have.been.called
expect(@mockContainer.trigger.args[0][0]).to.equal 'hide'
it 'returns the object for chaining', ->
module = new TestModule '#module_container'
expect(module.hide()).to.eql module
describe 'show', ->
it 'makes the container of the module visible', ->
module = new TestModule '#module_container'
expect(module.container).to.be.visible
module.hide()
expect(module.container).to.not.be.visible
module.show()
expect(module.container).to.be.visible
it 'triggers a "show" event on the container', ->
@mockContainer = $('#module_container')
@module = new TestModule @mockContainer
sinon.spy @mockContainer, 'trigger'
@module.show()
expect(@mockContainer.trigger).to.have.been.called
expect(@mockContainer.trigger.args[0][0]).to.equal 'show'
it 'returns the object for chaining', ->
module = new TestModule '#module_container'
expect(module.show()).to.eql module
describe 'visible', ->
beforeEach ->
@module = new TestModule '#module_container'
it 'returns true for visible containers', ->
expect(@module.visible()).to.be.true
# This doesn't seem to work in JSDOM.
xit 'returns false for invisible containers', ->
@module.hide()
expect(@module.visible()).to.be.false