jQuery powered unit test

by fresheyeball

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/mocha/1.12.1/mocha.js"></script>
<script src="http://code.angularjs.org/1.1.5/angular.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/mocha/1.12.1/mocha.css">
<script src="http://chaijs.com/chai.js"></script>
<!-- We are going to use Mocha + Chai setup for testing -->
<script>
    mocha.setup('bdd');
</script>
<body>
    <div id="mocha"></div>
</body>
<!-- Adding angular mocks to have 'module' and 'inject' functions -->
<script src="http://code.angularjs.org/1.1.5/angular-mocks.js"></script>

CoffeeScript

angular.module 'myModule', []

angular.module('myModule').directive 'clickOff', ->
  restrict : 'A'
  link     : (scope, element, attrs) ->
    isOff = true
        
    angular.element(document.body).bind 'click', ->
      if isOff
        scope.$eval attrs.clickOff
        scope.$digest()
      isOff = true

    element.bind 'click', -> 
      isOff = false
      return

{expect} = chai
    
HTML = """
    <section>
		<div click-off="test()" id="the-zone">
        	<span>I'm in the click off zone</span>
        </div>
    	<div id="not-the-zone"></div>
    </section>
"""
describe "click off directive jQuery test", ->
  $compile = null
  $elem    = null
  scope    = null
  
  beforeEach module "myModule"
  
  beforeEach inject ($injector, $rootScope) ->  
    scope = $rootScope.$new()
    scope.didFire = null
    scope.test = -> scope.didFire = true

    $compile = $injector.get "$compile" 
  
  # Add the element to the page
  beforeEach ->
    # now result is passed into jQuery
    $elem = $ $compile(HTML)(scope)
    $('body').append $elem
    scope.$digest()
    
  afterEach ->
    # clean up the dom for the next test
    $('body').off 'click'
    $elem.remove()
  
  it "click on element should not fire expression", ->
    expect(scope.didFire).to.be.null
    $('#the-zone').trigger "click"
    # we no longer have to simulate the event bubbling ourselves
    # but use the native dom implimentation
    expect(scope.didFire).to.be.null
    
    # now we can easily test the effect on child elements
    scope.didFire = false
    $('#the-zone span').trigger 'click'
    expect(scope.didFire).to.be.false

  it "click off the elemnt should fire expression", ->
    expect(scope.didFire).to.be.null
    $('body').trigger "click"
    expect(scope.didFire).to.be.true
    
    # as well as test other elements on the page
    scope.didFire = false
    $('#not-the-zone').trigger 'click'
    expect(scope.didFire).to.be.true

  it "clicking on and off", ->
    # there is just...