Question

First, I just wanted to say that the below code is working in reality. It is only failing in the jasmine spec. The function is very simple. When the check box with id "check_all" is selected, select all the other check boxes as well.

When I run the test, everything up to and including expect #check_all to be true passes as expected. I'm having trouble understanding however why all my expectations are not passing. Any advice?

Function:

window.check_all = () ->
  $('#check_all').change(->
    if $('#check_all').is(':checked')
      $('.checkbox').attr('checked', 'checked')
    else
      $('.checkbox').removeAttr('checked')
  )
$(check_all)

Test:

describe 'checkbox', ->
  beforeEach ->
    loadFixtures 'checkbox'
  describe 'check_all', ->
    it 'checks all the checkboxes if check_all is checked', ->
      expect($('#check_all').is(':checked')).toBeFalsy()
      expect($('#question_1').is(':checked')).toBeFalsy()
      expect($('#question_2').is(':checked')).toBeFalsy()
      expect($('#question_3').is(':checked')).toBeFalsy()
      expect($('#question_4').is(':checked')).toBeFalsy()
      expect($('#question_5').is(':checked')).toBeFalsy()

      $('#check_all').attr('checked', 'checked')
      $('#check_all').change()

      expect($('#check_all').is(':checked')).toBeTruthy()
      expect($('#question_1').is(':checked')).toBeTruthy()
      expect($('#question_2').is(':checked')).toBeTruthy()
      expect($('#question_3').is(':checked')).toBeTruthy()
      expect($('#question_4').is(':checked')).toBeTruthy()
      expect($('#question_5').is(':checked')).toBeTruthy()

Fixture:

<p class="small gray"><input type="checkbox" name="check_all" id="check_all"> Select All</p>
<form accept-charset="UTF-8" action="" method="post">
    <ul class="library_questions">
        <li>
            <input class="checkbox" id="question_1" name="question[]" type="checkbox" value="1"/>
            Template Q1
        </li>
        <li>
            <input class="checkbox" id="question_2" name="question[]" type="checkbox" value="2"/>
            Template Q2
        </li>
        <li>
            <input class="checkbox" id="question_3" name="question[]" type="checkbox" value="3"/>
            Template Q3
        </li>
        <li>
            <input class="checkbox" id="question_4" name="question[]" type="checkbox" value="4"/>
            Template Q4
        </li>
        <li>
            <input class="checkbox" id="question_5" name="question[]" type="checkbox" value="5"/>
            Instructions
        </li>
    </ul>
    <input class="purple submit_button" name="commit" type="submit" value="Submit"/>
</form>
Was it helpful?

Solution

You're running check_all from the $ function, meaning that it runs after the document ready event. I'm guessing that your test runs sooner, which is why triggering the change event doesn't affect the checkboxes. So, either:

  1. Put your tests in the $ wrapper, or
  2. Put the script that defines check_all in your page at the end of the <body>. Then you don't need to use the $ wrapper at all.

A third option would be to bind a change event handler on an ancestor of #check_all instead. For instance,

$(document).on('change', '#check_all', -> ...)

(Before jQuery 1.7, you'd use live instead of on.) That way, even if your script ran from the <head>, you still wouldn't need the $ wrapper.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top