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 'assert', ->

    it 'shows an alert with the given message if the given condition is false', ->
      modularity.assert false, 'Message'
      expect(console.error.calledWith "Message").to.be.true

    it 'fails when the condition is null', ->
      modularity.assert null, 'Message'
      expect(console.error.calledWith "Message").to.be.true

    it 'fails when the condition is undefined', ->
      modularity.assert undefined, 'Message'
      expect(console.error.calledWith "Message").to.be.true

    it 'fails when the condition is an empty array', ->
      modularity.assert [], 'Message'
      expect(console.error.calledWith "Message").to.be.true

    it 'fails when the condition is an empty string', ->
      modularity.assert '', 'Message'
      expect(console.error.calledWith "Message").to.be.true

    it 'passes when the condition is a string', ->
      modularity.assert '123', 'Message'
      expect(console.error).to.not.have.been.called

    it "returns false if the condition doesn't pass", ->
      expect(modularity.assert(false)).to.be.false

    it "returns true if the condition passes", ->
      expect(modularity.assert('123')).to.be.true


    describe 'global events', ->

      beforeEach ->
        @mockGlobalContainer = $('#test #module_container')
        sinon.stub(modularity, 'global_event_container').returns(@mockGlobalContainer)

      afterEach ->
        modularity.global_event_container.restore()


      describe 'on', ->

        beforeEach ->
          sinon.spy @mockGlobalContainer, 'on'

        afterEach ->
          @mockGlobalContainer.on.restore()

        it 'binds the given event type and callback method to the global event container', ->
          callback = ->
          modularity.on '123', callback
          expect(@mockGlobalContainer.on).to.have.been.called
          expect(@mockGlobalContainer.on.args[0][0]).to.equal '123'
          expect(@mockGlobalContainer.on.args[0][1]).to.equal callback

        it "throws an error if no parameters are given", ->
          modularity.on()
          expect(console.error).to.have.been.called
          expect(@mockGlobalContainer.on).to.not.have.been.called

        it "throws an error if the given event type doesn't exist", ->
          modularity.on undefined, ->
          expect(console.error).to.have.been.called
          expect(@mockGlobalContainer.on).to.not.have.been.called

        it 'throws an error if the given event type is not a string', ->
          modularity.on {}, ->
          expect(console.error).to.have.been.called
          expect(@mockGlobalContainer.on).to.not.have.been.called

        it "throws an error if the given callback doesn't exist", ->
          modularity.on '123'
          expect(console.error).to.have.been.called
          expect(@mockGlobalContainer.on).to.not.have.been.called

        it 'throws an error if the given callback is not a function', ->
          modularity.on '123', {}
          expect(console.error).to.have.been.called
          expect(@mockGlobalContainer.on).to.not.have.been.called


      describe 'trigger', ->

        beforeEach ->
          sinon.spy @mockGlobalContainer, 'trigger'

        afterEach ->
          @mockGlobalContainer.trigger.restore()


        it 'triggers a custom jQuery event with the given event type on the global event container object', ->
          modularity.trigger 'event type', 'event data'
          expect(@mockGlobalContainer.trigger).to.have.been.called
          expect(@mockGlobalContainer.trigger.args[0][0]).to.equal 'event type'
          expect(@mockGlobalContainer.trigger.args[0][1]).to.equal 'event data'

        describe 'when no payload is given', ->
          it 'provides an empty object as payload', ->
            modularity.trigger 'event type'
            expect(@mockGlobalContainer.trigger).to.have.been.called
            expect(@mockGlobalContainer.trigger.args[0][1]).to.eql({})

          it "doesn't change the original payload variable", ->
            data = undefined
            modularity.trigger 'event type', data
            expect(data).to.equal.undefined

        it 'provides 0 as payload if 0 is given', ->
          modularity.trigger 'event type', 0
          expect(@mockGlobalContainer.trigger).to.have.been.called
          expect(@mockGlobalContainer.trigger.args[0][1]).to.equal(0)

        it 'throws an error if the given event type is not a string', ->
          modularity.trigger {}
          expect(@mockGlobalContainer.trigger).to.not.have.been.called
          expect(console.error).to.have.been.called

