From e167f28549b80141165f42b567073c5dd55f80c5 Mon Sep 17 00:00:00 2001 From: Robert Speicher <rspeicher@gmail.com> Date: Wed, 29 Apr 2015 17:47:55 -0400 Subject: [PATCH] Update Taskable to use TaskList --- app/models/concerns/taskable.rb | 45 ++++++++---------------- spec/support/taskable_shared_examples.rb | 30 ++++++---------- 2 files changed, 25 insertions(+), 50 deletions(-) diff --git a/app/models/concerns/taskable.rb b/app/models/concerns/taskable.rb index bbb3b301a9f..6e04578a7df 100644 --- a/app/models/concerns/taskable.rb +++ b/app/models/concerns/taskable.rb @@ -1,51 +1,36 @@ +require 'task_list' + # Contains functionality for objects that can have task lists in their # descriptions. Task list items can be added with Markdown like "* [x] Fix # bugs". # # Used by MergeRequest and Issue module Taskable - TASK_PATTERN_MD = /^(?<bullet> *[*-] *)\[(?<checked>[ xX])\]/.freeze - TASK_PATTERN_HTML = /^<li>(?<p_tag>\s*<p>)?\[(?<checked>[ xX])\]/.freeze - - # Change the state of a task list item for this Taskable. Edit the object's - # description by finding the nth task item and changing its checkbox - # placeholder to "[x]" if +checked+ is true, or "[ ]" if it's false. - # Note: task numbering starts with 1 - def update_nth_task(n, checked) - index = 0 - check_char = checked ? 'x' : ' ' + # Called by `TaskList::Summary` + def task_list_items + return [] if description.blank? - # Do this instead of using #gsub! so that ActiveRecord detects that a field - # has changed. - self.description = self.description.gsub(TASK_PATTERN_MD) do |match| - index += 1 - case index - when n then "#{$LAST_MATCH_INFO[:bullet]}[#{check_char}]" - else match - end + @task_list_items ||= description.scan(TaskList::Filter::ItemPattern).collect do |item| + # ItemPattern strips out the hyphen, but Item requires it. Rabble rabble. + TaskList::Item.new("- #{item}") end + end - save + def tasks + @tasks ||= TaskList.new(self) end # Return true if this object's description has any task list items. def tasks? - description && description.match(TASK_PATTERN_MD) + tasks.summary.items? end # Return a string that describes the current state of this Taskable's task # list items, e.g. "20 tasks (12 done, 8 unfinished)" def task_status - return nil unless description - - num_tasks = 0 - num_done = 0 - - description.scan(TASK_PATTERN_MD) do - num_tasks += 1 - num_done += 1 unless $LAST_MATCH_INFO[:checked] == ' ' - end + return '' if description.blank? - "#{num_tasks} tasks (#{num_done} done, #{num_tasks - num_done} unfinished)" + sum = tasks.summary + "#{sum.item_count} tasks (#{sum.complete_count} done, #{sum.incomplete_count} unfinished)" end end diff --git a/spec/support/taskable_shared_examples.rb b/spec/support/taskable_shared_examples.rb index 8e5e3a8aafc..77e0ed5f578 100644 --- a/spec/support/taskable_shared_examples.rb +++ b/spec/support/taskable_shared_examples.rb @@ -4,27 +4,13 @@ # subject { Issue or MergeRequest } shared_examples 'a Taskable' do before do - subject.description = <<EOT.gsub(/ {6}/, '') + subject.description = <<-EOT.strip_heredoc * [ ] Task 1 * [x] Task 2 * [x] Task 3 * [ ] Task 4 * [ ] Task 5 -EOT - end - - it 'updates the Nth task correctly' do - subject.update_nth_task(1, true) - expect(subject.description).to match(/\[x\] Task 1/) - - subject.update_nth_task(2, true) - expect(subject.description).to match('\[x\] Task 2') - - subject.update_nth_task(3, false) - expect(subject.description).to match('\[ \] Task 3') - - subject.update_nth_task(4, false) - expect(subject.description).to match('\[ \] Task 4') + EOT end it 'returns the correct task status' do @@ -33,10 +19,14 @@ EOT expect(subject.task_status).to match('3 unfinished') end - it 'knows if it has tasks' do - expect(subject.tasks?).to be_truthy + describe '#tasks?' do + it 'returns true when object has tasks' do + expect(subject.tasks?).to eq true + end - subject.description = 'Now I have no tasks' - expect(subject.tasks?).to be_falsey + it 'returns false when object has no tasks' do + subject.description = 'Now I have no tasks' + expect(subject.tasks?).to eq false + end end end -- GitLab