task_list 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,142 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../../test_helper', __FILE__)
3
+ require 'task_list/filter'
4
+
5
+ class TaskList::FilterTest < Minitest::Test
6
+ def setup
7
+ @pipeline = HTML::Pipeline.new [
8
+ HTML::Pipeline::MarkdownFilter,
9
+ TaskList::Filter
10
+ ], {}, {}
11
+
12
+ @context = {}
13
+ @item_selector = "input.task-list-item-checkbox[type=checkbox]"
14
+ end
15
+
16
+ def test_filters_items_in_a_list
17
+ text = <<-md
18
+ - [ ] incomplete
19
+ - [x] complete
20
+ md
21
+ assert_equal 2, filter(text)[:output].css(@item_selector).size
22
+ end
23
+
24
+ def test_filters_items_with_HTML_contents
25
+ text = <<-md
26
+ - [ ] incomplete **with bold** text
27
+ - [x] complete __with italic__ text
28
+ md
29
+ assert_equal 2, filter(text)[:output].css(@item_selector).size
30
+ end
31
+
32
+ def test_filters_items_in_a_list_wrapped_in_paras
33
+ # See issue #7951 for details.
34
+ text = <<-md
35
+ - [ ] one
36
+ - [ ] this one will be wrapped in a para
37
+
38
+ - [ ] this one too, wtf
39
+ md
40
+ assert_equal 3, filter(text)[:output].css(@item_selector).size
41
+ end
42
+
43
+ def test_populates_result_with_task_list_items
44
+ text = <<-md
45
+ - [ ] incomplete
46
+ - [x] complete
47
+ md
48
+
49
+ result = filter(text)
50
+ assert !result[:task_list_items].empty?
51
+ incomplete, complete = result[:task_list_items]
52
+
53
+ assert incomplete
54
+ assert !incomplete.complete?
55
+
56
+ assert complete
57
+ assert complete.complete?
58
+ end
59
+
60
+ def test_skips_lists_in_code_blocks
61
+ code = <<-md
62
+ ```
63
+ - [ ] incomplete
64
+ - [x] complete
65
+ ```
66
+ md
67
+
68
+ assert filter(code)[:output].css(@item_selector).empty?,
69
+ "should not have any task list items"
70
+ end
71
+
72
+ def test_handles_encoding_correctly
73
+ unicode = "中文"
74
+ text = <<-md
75
+ - [ ] #{unicode}
76
+ md
77
+ assert item = filter(text)[:output].css('.task-list-item').pop
78
+ assert_equal unicode, item.text.strip
79
+ end
80
+
81
+ def test_handles_nested_items
82
+ text = <<-md
83
+ - [ ] one
84
+ - [ ] one.one
85
+ md
86
+ assert item = filter(text)[:output].css('.task-list-item .task-list-item').pop
87
+ end
88
+
89
+ def test_handles_complicated_nested_items
90
+ text = <<-md
91
+ - [ ] one
92
+ - [ ] one.one
93
+ - [x] one.two
94
+ - [ ] one.two.one
95
+ - [ ] one.two.two
96
+ - [ ] one.three
97
+ - [ ] one.four
98
+ - [ ] two
99
+ - [x] two.one
100
+ - [ ] two.two
101
+ - [ ] three
102
+ md
103
+
104
+ assert_equal 6 + 2, filter(text)[:output].css('.task-list-item .task-list-item').size
105
+ assert_equal 2, filter(text)[:output].css('.task-list-item .task-list-item .task-list-item').size
106
+ end
107
+
108
+ # NOTE: This is an edge case experienced regularly by users using a Swiss
109
+ # German keyboard.
110
+ # See: https://github.com/github/github/pull/18362
111
+ def test_non_breaking_space_between_brackets
112
+ text = "- [\xC2\xA0] ok"
113
+ assert item = filter(text)[:output].css('.task-list-item').pop, "item expected"
114
+ assert_equal 'ok', item.text.strip
115
+ end
116
+
117
+ # See: https://github.com/github/github/pull/18362
118
+ def test_non_breaking_space_between_brackets_in_paras
119
+ text = <<-md
120
+ - [\xC2\xA0] one
121
+ - [\xC2\xA0] this one will be wrapped in a para
122
+
123
+ - [\xC2\xA0] this one too, wtf
124
+ md
125
+ assert_equal 3, filter(text)[:output].css(@item_selector).size
126
+ end
127
+
128
+ def test_capital_X
129
+ text = <<-md
130
+ - [x] lower case
131
+ - [X] capital
132
+ md
133
+ assert_equal 2, filter(text)[:output].css("[checked]").size
134
+ end
135
+
136
+ protected
137
+
138
+ def filter(input, context = @context, result = nil)
139
+ result ||= {}
140
+ @pipeline.call(input, context, result)
141
+ end
142
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../../test_helper', __FILE__)
3
+ require 'task_list/summary'
4
+
5
+ class TaskList::SummaryTest < Minitest::Test
6
+ def setup
7
+ @complete = make_item "[x]", "complete"
8
+ @incomplete = make_item "[ ]", "incomplete"
9
+ @items = [@complete, @incomplete]
10
+ @summary = make_summary @items
11
+ end
12
+
13
+ def test_no_items
14
+ summary = make_summary []
15
+ assert !summary.items?, "no task list items are expected"
16
+ end
17
+
18
+ def test_items
19
+ assert @summary.items?, "task list items are expected"
20
+ assert_equal 2, @summary.item_count
21
+ end
22
+
23
+ def test_complete_count
24
+ assert_equal 1, @summary.complete_count
25
+ end
26
+
27
+ def test_incomplete_count
28
+ assert_equal 1, @summary.incomplete_count
29
+ end
30
+
31
+ protected
32
+
33
+ def make_item(checkbox_text = "[ ]", source = "an item!")
34
+ TaskList::Item.new(checkbox_text, source)
35
+ end
36
+
37
+ def make_summary(items)
38
+ TaskList::Summary.new(items)
39
+ end
40
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ require File.expand_path('../test_helper', __FILE__)
3
+ require 'task_list'
4
+ require 'task_list/filter'
5
+
6
+ class TaskListTest < Minitest::Test
7
+ class Record < Struct.new(:body)
8
+ def task_list_items
9
+ []
10
+ end
11
+ end
12
+
13
+ def test_has_summary
14
+ assert summary = task_list("- [ ] one").summary, "summary expected"
15
+ assert_kind_of TaskList::Summary, summary
16
+ end
17
+
18
+ def test_complete_item
19
+ item = TaskList::Item.new("[x]", "complete")
20
+ assert item.complete?, "expected to be complete"
21
+ end
22
+
23
+ def test_incomplete_item
24
+ item = TaskList::Item.new("[ ]", "incomplete")
25
+ assert !item.complete?, "expected to be incomplete"
26
+ end
27
+
28
+ protected
29
+
30
+ def task_list(text)
31
+ TaskList.new(Record.new(text))
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ $:.unshift "lib"
2
+ require 'minitest/autorun'
3
+ require 'task_list'
@@ -0,0 +1,96 @@
1
+ #= require task_list
2
+
3
+ module "TaskList events",
4
+ setup: ->
5
+ @container = $ '<div>', class: 'js-task-list-container'
6
+
7
+ @list = $ '<ul>', class: 'task-list'
8
+ @item = $ '<li>', class: 'task-list-item'
9
+ @checkbox = $ '<input>',
10
+ type: 'checkbox'
11
+ class: 'task-list-item-checkbox'
12
+ disabled: true
13
+ checked: false
14
+
15
+ @field = $ '<textarea>', class: 'js-task-list-field', "- [ ] text"
16
+
17
+ @item.append @checkbox
18
+ @list.append @item
19
+ @container.append @list
20
+
21
+ @container.append @field
22
+
23
+ $('#qunit-fixture').append(@container)
24
+ @container.taskList()
25
+
26
+ teardown: ->
27
+ $(document).off 'tasklist:enabled'
28
+ $(document).off 'tasklist:disabled'
29
+ $(document).off 'tasklist:change'
30
+ $(document).off 'tasklist:changed'
31
+
32
+ asyncTest "triggers a tasklist:change event before making task list item changes", ->
33
+ expect 1
34
+
35
+ @field.on 'tasklist:change', (event, index, checked) ->
36
+ ok true
37
+
38
+ setTimeout ->
39
+ start()
40
+ , 20
41
+
42
+ @checkbox.click()
43
+
44
+ asyncTest "triggers a tasklist:changed event once a task list item changes", ->
45
+ expect 1
46
+
47
+ @field.on 'tasklist:changed', (event, index, checked) ->
48
+ ok true
49
+
50
+ setTimeout ->
51
+ start()
52
+ , 20
53
+
54
+ @checkbox.click()
55
+
56
+ asyncTest "can cancel a tasklist:changed event", ->
57
+ expect 2
58
+
59
+ @field.on 'tasklist:change', (event, index, checked) ->
60
+ ok true
61
+ event.preventDefault()
62
+
63
+ @field.on 'tasklist:changed', (event, index, checked) ->
64
+ ok false
65
+
66
+ before = @checkbox.val()
67
+ setTimeout =>
68
+ equal before, @checkbox.val()
69
+ start()
70
+ , 20
71
+
72
+ @checkbox.click()
73
+
74
+ asyncTest "enables task list items when a .js-task-list-field is present", ->
75
+ expect 1
76
+
77
+ $(document).on 'tasklist:enabled', (event) ->
78
+ ok true
79
+
80
+ @container.taskList()
81
+ setTimeout ->
82
+ start()
83
+ , 20
84
+
85
+ asyncTest "doesn't enable task list items when a .js-task-list-field is absent", ->
86
+ expect 0
87
+
88
+ $(document).on 'tasklist:enabled', (event) ->
89
+ ok true
90
+
91
+ @field.remove()
92
+
93
+ @container.taskList()
94
+ setTimeout ->
95
+ start()
96
+ , 20
@@ -0,0 +1,566 @@
1
+ #= require task_list
2
+
3
+ module "TaskList updates",
4
+ setup: ->
5
+ @container = $ '<div>', class: 'js-task-list-container'
6
+
7
+ @list = $ '<ul>', class: 'task-list'
8
+
9
+ @completeItem = $ '<li>', class: 'task-list-item'
10
+ @completeCheckbox = $ '<input>',
11
+ type: 'checkbox'
12
+ class: 'task-list-item-checkbox'
13
+ disabled: true
14
+ checked: true
15
+
16
+ @incompleteItem = $ '<li>', class: 'task-list-item'
17
+ @incompleteCheckbox = $ '<input>',
18
+ type: 'checkbox'
19
+ class: 'task-list-item-checkbox'
20
+ disabled: true
21
+ checked: false
22
+
23
+ # non-breaking space. See: https://github.com/github/task-lists/pull/14
24
+ @nbsp = String.fromCharCode(160)
25
+ @incompleteNBSPItem = $ '<li>', class: 'task-list-item'
26
+ @incompleteNBSPCheckbox = $ '<input>',
27
+ type: 'checkbox'
28
+ class: 'task-list-item-checkbox'
29
+ disabled: true
30
+ checked: false
31
+
32
+ @blockquote = $ '<blockquote>'
33
+
34
+ @quotedList = $ '<ul>', class: 'task-list'
35
+
36
+ @quotedCompleteItem = $ '<li>', class: 'task-list-item'
37
+ @quotedCompleteCheckbox = $ '<input>',
38
+ type: 'checkbox'
39
+ class: 'task-list-item-checkbox'
40
+ disabled: true
41
+ checked: true
42
+
43
+ @quotedIncompleteItem = $ '<li>', class: 'task-list-item'
44
+ @quotedIncompleteCheckbox = $ '<input>',
45
+ type: 'checkbox'
46
+ class: 'task-list-item-checkbox'
47
+ disabled: true
48
+ checked: false
49
+
50
+ @innerBlockquote = $ '<blockquote>'
51
+
52
+ @innerList = $ '<ul>', class: 'task-list'
53
+
54
+ @innerCompleteItem = $ '<li>', class: 'task-list-item'
55
+ @innerCompleteCheckbox = $ '<input>',
56
+ type: 'checkbox'
57
+ class: 'task-list-item-checkbox'
58
+ disabled: true
59
+ checked: true
60
+
61
+ @innerIncompleteItem = $ '<li>', class: 'task-list-item'
62
+ @innerIncompleteCheckbox = $ '<input>',
63
+ type: 'checkbox'
64
+ class: 'task-list-item-checkbox'
65
+ disabled: true
66
+ checked: false
67
+
68
+ @orderedList = $ '<ol>', class: 'task-list'
69
+
70
+ @orderedCompleteItem = $ '<li>', class: 'task-list-item'
71
+ @orderedCompleteCheckbox = $ '<input>',
72
+ type: 'checkbox'
73
+ class: 'task-list-item-checkbox'
74
+ disabled: true
75
+ checked: true
76
+
77
+ @orderedIncompleteItem = $ '<li>', class: 'task-list-item'
78
+ @orderedIncompleteCheckbox = $ '<input>',
79
+ type: 'checkbox'
80
+ class: 'task-list-item-checkbox'
81
+ disabled: true
82
+ checked: false
83
+
84
+ @field = $ '<textarea>', class: 'js-task-list-field', text: """
85
+ - [x] complete
86
+ - [ ] incomplete
87
+ - [#{@nbsp}] incompleteNBSP
88
+ > - [x] quoted complete
89
+ > - [ ] quoted incomplete
90
+ >> - [x] inner complete
91
+ > > - [ ] inner incomplete
92
+ > 0. [x] ordered complete
93
+ > 0. [ ] ordered incomplete
94
+ """
95
+
96
+ @changes =
97
+ toComplete: """
98
+ - [ ] complete
99
+ - [ ] incomplete
100
+ - [#{@nbsp}] incompleteNBSP
101
+ > - [x] quoted complete
102
+ > - [ ] quoted incomplete
103
+ >> - [x] inner complete
104
+ > > - [ ] inner incomplete
105
+ > 0. [x] ordered complete
106
+ > 0. [ ] ordered incomplete
107
+ """
108
+ toQuotedComplete: """
109
+ - [x] complete
110
+ - [ ] incomplete
111
+ - [#{@nbsp}] incompleteNBSP
112
+ > - [ ] quoted complete
113
+ > - [ ] quoted incomplete
114
+ >> - [x] inner complete
115
+ > > - [ ] inner incomplete
116
+ > 0. [x] ordered complete
117
+ > 0. [ ] ordered incomplete
118
+ """
119
+ toInnerComplete: """
120
+ - [x] complete
121
+ - [ ] incomplete
122
+ - [#{@nbsp}] incompleteNBSP
123
+ > - [x] quoted complete
124
+ > - [ ] quoted incomplete
125
+ >> - [ ] inner complete
126
+ > > - [ ] inner incomplete
127
+ > 0. [x] ordered complete
128
+ > 0. [ ] ordered incomplete
129
+ """
130
+ toOrderedComplete: """
131
+ - [x] complete
132
+ - [ ] incomplete
133
+ - [#{@nbsp}] incompleteNBSP
134
+ > - [x] quoted complete
135
+ > - [ ] quoted incomplete
136
+ >> - [x] inner complete
137
+ > > - [ ] inner incomplete
138
+ > 0. [ ] ordered complete
139
+ > 0. [ ] ordered incomplete
140
+ """
141
+ toIncomplete: """
142
+ - [x] complete
143
+ - [x] incomplete
144
+ - [#{@nbsp}] incompleteNBSP
145
+ > - [x] quoted complete
146
+ > - [ ] quoted incomplete
147
+ >> - [x] inner complete
148
+ > > - [ ] inner incomplete
149
+ > 0. [x] ordered complete
150
+ > 0. [ ] ordered incomplete
151
+ """
152
+ toQuotedIncomplete: """
153
+ - [x] complete
154
+ - [ ] incomplete
155
+ - [#{@nbsp}] incompleteNBSP
156
+ > - [x] quoted complete
157
+ > - [x] quoted incomplete
158
+ >> - [x] inner complete
159
+ > > - [ ] inner incomplete
160
+ > 0. [x] ordered complete
161
+ > 0. [ ] ordered incomplete
162
+ """
163
+ toInnerIncomplete: """
164
+ - [x] complete
165
+ - [ ] incomplete
166
+ - [#{@nbsp}] incompleteNBSP
167
+ > - [x] quoted complete
168
+ > - [ ] quoted incomplete
169
+ >> - [x] inner complete
170
+ > > - [x] inner incomplete
171
+ > 0. [x] ordered complete
172
+ > 0. [ ] ordered incomplete
173
+ """
174
+ toOrderedIncomplete: """
175
+ - [x] complete
176
+ - [ ] incomplete
177
+ - [#{@nbsp}] incompleteNBSP
178
+ > - [x] quoted complete
179
+ > - [ ] quoted incomplete
180
+ >> - [x] inner complete
181
+ > > - [ ] inner incomplete
182
+ > 0. [x] ordered complete
183
+ > 0. [x] ordered incomplete
184
+ """
185
+ toIncompleteNBSP: """
186
+ - [x] complete
187
+ - [ ] incomplete
188
+ - [x] incompleteNBSP
189
+ > - [x] quoted complete
190
+ > - [ ] quoted incomplete
191
+ >> - [x] inner complete
192
+ > > - [ ] inner incomplete
193
+ > 0. [x] ordered complete
194
+ > 0. [ ] ordered incomplete
195
+ """
196
+
197
+ @completeItem.append @completeCheckbox
198
+ @list.append @completeItem
199
+ @completeItem.expectedIndex = 1
200
+
201
+ @incompleteItem.append @incompleteCheckbox
202
+ @list.append @incompleteItem
203
+ @incompleteItem.expectedIndex = 2
204
+
205
+ @incompleteNBSPItem.append @incompleteNBSPCheckbox
206
+ @list.append @incompleteNBSPItem
207
+ @incompleteNBSPItem.expectedIndex = 3
208
+
209
+ @container.append @list
210
+ @container.append @field
211
+
212
+ @quotedCompleteItem.append @quotedCompleteCheckbox
213
+ @quotedList.append @quotedCompleteItem
214
+ @quotedCompleteItem.expectedIndex = 4
215
+
216
+ @quotedIncompleteItem.append @quotedIncompleteCheckbox
217
+ @quotedList.append @quotedIncompleteItem
218
+ @quotedIncompleteItem.expectedIndex = 5
219
+
220
+ @blockquote.append @quotedList
221
+
222
+ @innerCompleteItem.append @innerCompleteCheckbox
223
+ @innerList.append @innerCompleteItem
224
+ @innerCompleteItem.expectedIndex = 6
225
+
226
+ @innerIncompleteItem.append @innerIncompleteCheckbox
227
+ @innerList.append @innerIncompleteItem
228
+ @innerIncompleteItem.expectedIndex = 7
229
+
230
+ @innerBlockquote.append @innerList
231
+ @innerBlockquote.append @innerField
232
+
233
+ @blockquote.append @innerBlockquote
234
+
235
+ @container.append @blockquote
236
+
237
+ @orderedCompleteItem.append @orderedCompleteCheckbox
238
+ @orderedList.append @orderedCompleteItem
239
+ @orderedCompleteItem.expectedIndex = 8
240
+
241
+ @orderedIncompleteItem.append @orderedIncompleteCheckbox
242
+ @orderedList.append @orderedIncompleteItem
243
+ @orderedIncompleteItem.expectedIndex = 9
244
+
245
+ @container.append @orderedList
246
+
247
+ @blockquote.append @field
248
+
249
+ $('#qunit-fixture').append(@container)
250
+ @container.taskList()
251
+
252
+ teardown: ->
253
+ $(document).off 'tasklist:changed'
254
+
255
+ asyncTest "updates the source, marking the incomplete item as complete", ->
256
+ expect 3
257
+
258
+ @field.on 'tasklist:changed', (event, index, checked) =>
259
+ ok checked
260
+ equal index, @incompleteItem.expectedIndex
261
+ equal @field.val(), @changes.toIncomplete
262
+
263
+ setTimeout ->
264
+ start()
265
+ , 20
266
+
267
+ @incompleteCheckbox.click()
268
+
269
+ asyncTest "updates the source, marking the complete item as incomplete", ->
270
+ expect 3
271
+
272
+ @field.on 'tasklist:changed', (event, index, checked) =>
273
+ ok !checked
274
+ equal index, @completeItem.expectedIndex
275
+ equal @field.val(), @changes.toComplete
276
+
277
+ setTimeout ->
278
+ start()
279
+ , 20
280
+
281
+ @completeCheckbox.click()
282
+
283
+ # See: https://github.com/github/task-lists/pull/14
284
+ asyncTest "updates the source for items with non-breaking spaces", ->
285
+ expect 3
286
+
287
+ @field.on 'tasklist:changed', (event, index, checked) =>
288
+ ok checked
289
+ equal index, @incompleteNBSPItem.expectedIndex
290
+ equal @field.val(), @changes.toIncompleteNBSP
291
+
292
+ setTimeout ->
293
+ start()
294
+ , 20
295
+
296
+ @incompleteNBSPCheckbox.click()
297
+
298
+ asyncTest "updates the source of a quoted item, marking the incomplete item as complete", ->
299
+ expect 3
300
+
301
+ @field.on 'tasklist:changed', (event, index, checked) =>
302
+ ok checked
303
+ equal index, @quotedIncompleteItem.expectedIndex
304
+ equal @field.val(), @changes.toQuotedIncomplete
305
+
306
+ setTimeout ->
307
+ start()
308
+ , 20
309
+
310
+ @quotedIncompleteCheckbox.click()
311
+
312
+ asyncTest "updates the source of a quoted item, marking the complete item as incomplete", ->
313
+ expect 3
314
+
315
+ @field.on 'tasklist:changed', (event, index, checked) =>
316
+ ok !checked
317
+ equal index, @quotedCompleteItem.expectedIndex
318
+ equal @field.val(), @changes.toQuotedComplete
319
+
320
+ setTimeout ->
321
+ start()
322
+ , 20
323
+
324
+ @quotedCompleteCheckbox.click()
325
+
326
+ asyncTest "updates the source of a quoted quoted item, marking the incomplete item as complete", ->
327
+ expect 3
328
+
329
+ @field.on 'tasklist:changed', (event, index, checked) =>
330
+ ok checked
331
+ equal index, @innerIncompleteItem.expectedIndex
332
+ equal @field.val(), @changes.toInnerIncomplete
333
+
334
+ setTimeout ->
335
+ start()
336
+ , 20
337
+
338
+ @innerIncompleteCheckbox.click()
339
+
340
+ asyncTest "updates the source of a quoted quoted item, marking the complete item as incomplete", ->
341
+ expect 3
342
+
343
+ @field.on 'tasklist:changed', (event, index, checked) =>
344
+ ok !checked
345
+ equal index, @innerCompleteItem.expectedIndex
346
+ equal @field.val(), @changes.toInnerComplete
347
+
348
+ setTimeout ->
349
+ start()
350
+ , 20
351
+
352
+ @innerCompleteCheckbox.click()
353
+
354
+ asyncTest "updates the source of an ordered list item, marking the incomplete item as complete", ->
355
+ expect 3
356
+
357
+ @field.on 'tasklist:changed', (event, index, checked) =>
358
+ ok checked
359
+ equal index, @orderedIncompleteItem.expectedIndex
360
+ equal @field.val(), @changes.toOrderedIncomplete
361
+
362
+ setTimeout ->
363
+ start()
364
+ , 20
365
+
366
+ @orderedIncompleteCheckbox.click()
367
+
368
+ asyncTest "updates the source of an ordered list item, marking the complete item as incomplete", ->
369
+ expect 3
370
+
371
+ @field.on 'tasklist:changed', (event, index, checked) =>
372
+ ok !checked
373
+ equal index, @orderedCompleteItem.expectedIndex
374
+ equal @field.val(), @changes.toOrderedComplete
375
+
376
+ setTimeout ->
377
+ start()
378
+ , 20
379
+
380
+ @orderedCompleteCheckbox.click()
381
+
382
+ asyncTest "update ignores items that look like Task List items but lack list prefix", ->
383
+ expect 3
384
+
385
+ $('#qunit-fixture').empty()
386
+
387
+ container = $ '<div>', class: 'js-task-list-container'
388
+
389
+ list = $ '<ul>', class: 'task-list'
390
+
391
+ item1 = $ '<li>', class: 'task-list-item'
392
+ item1Checkbox = $ '<input>',
393
+ type: 'checkbox'
394
+ class: 'task-list-item-checkbox'
395
+ disabled: true
396
+ checked: false
397
+
398
+ item2 = $ '<li>', class: 'task-list-item'
399
+ item2Checkbox = $ '<input>',
400
+ type: 'checkbox'
401
+ class: 'task-list-item-checkbox'
402
+ disabled: true
403
+ checked: false
404
+
405
+ field = $ '<textarea>', class: 'js-task-list-field', text: """
406
+ [ ] one
407
+ [ ] two
408
+ - [ ] three
409
+ - [ ] four
410
+ """
411
+
412
+ changes = """
413
+ [ ] one
414
+ [ ] two
415
+ - [ ] three
416
+ - [x] four
417
+ """
418
+
419
+ item1.append item1Checkbox
420
+ list.append item1
421
+ item1.expectedIndex = 1
422
+
423
+ item2.append item2Checkbox
424
+ list.append item2
425
+ item2.expectedIndex = 2
426
+
427
+ container.append list
428
+ container.append field
429
+
430
+ $('#qunit-fixture').append(container)
431
+ container.taskList()
432
+
433
+ field.on 'tasklist:changed', (event, index, checked) =>
434
+ ok checked
435
+ equal index, item2.expectedIndex
436
+ equal field.val(), changes
437
+
438
+ setTimeout ->
439
+ start()
440
+ , 20
441
+
442
+ item2Checkbox.click()
443
+
444
+ asyncTest "update ignores items that look like Task List items but are links", ->
445
+ expect 3
446
+
447
+ $('#qunit-fixture').empty()
448
+
449
+ container = $ '<div>', class: 'js-task-list-container'
450
+
451
+ list = $ '<ul>', class: 'task-list'
452
+
453
+ item1 = $ '<li>', class: 'task-list-item'
454
+ item1Checkbox = $ '<input>',
455
+ type: 'checkbox'
456
+ class: 'task-list-item-checkbox'
457
+ disabled: true
458
+ checked: false
459
+
460
+ item2 = $ '<li>', class: 'task-list-item'
461
+ item2Checkbox = $ '<input>',
462
+ type: 'checkbox'
463
+ class: 'task-list-item-checkbox'
464
+ disabled: true
465
+ checked: false
466
+
467
+ field = $ '<textarea>', class: 'js-task-list-field', text: """
468
+ - [ ] (link)
469
+ - [ ] [reference]
470
+ - [ ] () collapsed
471
+ - [ ] [] collapsed reference
472
+ - [ ] \\(escaped item)
473
+ - [ ] item
474
+ """
475
+
476
+ changes = """
477
+ - [ ] (link)
478
+ - [ ] [reference]
479
+ - [ ] () collapsed
480
+ - [ ] [] collapsed reference
481
+ - [ ] \\(escaped item)
482
+ - [x] item
483
+ """
484
+
485
+ item1.append item1Checkbox
486
+ list.append item1
487
+ item1.expectedIndex = 1
488
+
489
+ item2.append item2Checkbox
490
+ list.append item2
491
+ item2.expectedIndex = 2
492
+
493
+ container.append list
494
+ container.append field
495
+
496
+ $('#qunit-fixture').append(container)
497
+ container.taskList()
498
+
499
+ field.on 'tasklist:changed', (event, index, checked) =>
500
+ ok checked
501
+ equal index, item2.expectedIndex
502
+ equal field.val(), changes
503
+
504
+ setTimeout ->
505
+ start()
506
+ , 20
507
+
508
+ item2Checkbox.click()
509
+
510
+ asyncTest "updates items followed by links", ->
511
+ expect 3
512
+
513
+ $('#qunit-fixture').empty()
514
+
515
+ container = $ '<div>', class: 'js-task-list-container'
516
+
517
+ list = $ '<ul>', class: 'task-list'
518
+
519
+ item1 = $ '<li>', class: 'task-list-item'
520
+ item1Checkbox = $ '<input>',
521
+ type: 'checkbox'
522
+ class: 'task-list-item-checkbox'
523
+ disabled: true
524
+ checked: false
525
+
526
+ item2 = $ '<li>', class: 'task-list-item'
527
+ item2Checkbox = $ '<input>',
528
+ type: 'checkbox'
529
+ class: 'task-list-item-checkbox'
530
+ disabled: true
531
+ checked: false
532
+
533
+ field = $ '<textarea>', class: 'js-task-list-field', text: """
534
+ - [ ] [link label](link)
535
+ - [ ] [reference label][reference]
536
+ """
537
+
538
+ changes = """
539
+ - [ ] [link label](link)
540
+ - [x] [reference label][reference]
541
+ """
542
+
543
+ item1.append item1Checkbox
544
+ list.append item1
545
+ item1.expectedIndex = 1
546
+
547
+ item2.append item2Checkbox
548
+ list.append item2
549
+ item2.expectedIndex = 2
550
+
551
+ container.append list
552
+ container.append field
553
+
554
+ $('#qunit-fixture').append(container)
555
+ container.taskList()
556
+
557
+ field.on 'tasklist:changed', (event, index, checked) =>
558
+ ok checked
559
+ equal index, item2.expectedIndex
560
+ equal field.val(), changes
561
+
562
+ setTimeout ->
563
+ start()
564
+ , 20
565
+
566
+ item2Checkbox.click()