taskwarrior-web 0.0.15 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,8 @@
1
+ ## v1.0.0 (3/19/12)
2
+
3
+ * Refactored for taskwarrior 2.0 compatibility.
4
+ * Re-added task completion for both v1 and v2.
5
+
1
6
  ## v0.0.15 (3/12/12)
2
7
 
3
8
  * Fixed error in http auth
data/README.md CHANGED
@@ -3,6 +3,8 @@
3
3
  A lightweight, Sinatra-based web interface for the
4
4
  wonderful [Taskwarrior](http://taskwarrior.org/) todo application.
5
5
 
6
+ **Now compatible with ALL versions of Taskwarrior, including the new 2.0.0**
7
+
6
8
  [![Build Status](https://secure.travis-ci.org/theunraveler/taskwarrior-web.png)](http://travis-ci.org/theunraveler/taskwarrior-web)
7
9
 
8
10
  ## Installation
@@ -32,20 +34,10 @@ The current featureset includes:
32
34
  * If you are on a Mac and use Fluid.app, you get a dock badge showing the
33
35
  number of pending tasks.
34
36
 
35
- I'm looking to include more features once `task` supports issuing commands via
36
- UUID, like:
37
-
38
- * Marking a pending task as done.
39
- * Deleting tasks
40
-
41
37
  ## Known Issues
42
38
 
43
- * Currently, taskwarrior-web does not work with task 2. It will by the time
44
- task 2 is out of beta.
45
39
  * taskwarrior-web requires Ruby >= 1.9. It will not work with 1.8 and lower.
46
40
  Support for 1.8 will happen at some point.
47
- * The "View as list"/"View as Grid" links do nothing right now. (They will
48
- soon).
49
41
 
50
42
  ## Marginalia
51
43
 
@@ -119,6 +119,12 @@ module TaskwarriorWeb
119
119
  TaskwarriorWeb::Task.count(:status => :pending).to_s
120
120
  end
121
121
 
122
+ post '/ajax/task-complete/:id/?' do
123
+ # Bummer that we have to directly use Command here, but apparently tasks
124
+ # cannot be filtered by UUID.
125
+ TaskwarriorWeb::Command.new(:complete, params[:id]).run
126
+ end
127
+
122
128
  # Error handling
123
129
  not_found do
124
130
  @title = 'Page Not Found'
@@ -1,25 +1,20 @@
1
+ require 'taskwarrior-web/command_builder'
1
2
  require 'taskwarrior-web/runner'
2
3
 
3
4
  module TaskwarriorWeb
4
5
  class Command
5
6
 
6
- attr_accessor :command, :id, :params
7
+ include TaskwarriorWeb::CommandBuilder
8
+ include TaskwarriorWeb::Runner
9
+
10
+ attr_accessor :command, :id, :params, :built, :command_string
7
11
 
8
12
  def initialize(command, id = nil, *args)
9
13
  @command = command if command
10
14
  @id = id if id
15
+ puts "@id in command.rb: #{@id}"
11
16
  @params = args.last.is_a?(::Hash) ? args.pop : {}
12
17
  end
13
18
 
14
- def run
15
- if @command
16
- TaskwarriorWeb::Runner.run(self)
17
- else
18
- raise MissingCommandError
19
- end
20
- end
21
-
22
19
  end
23
-
24
- class MissingCommandError < Exception; end
25
20
  end
@@ -0,0 +1,22 @@
1
+ require 'taskwarrior-web/config'
2
+
3
+ module TaskwarriorWeb
4
+ module CommandBuilder
5
+ def self.included(class_name)
6
+ class_name.class_eval do
7
+ case TaskwarriorWeb::Config.task_major_version
8
+ when 2
9
+ require 'taskwarrior-web/command_builders/v2'
10
+ include TaskwarriorWeb::CommandBuilder::V2
11
+ when 1
12
+ require 'taskwarrior-web/command_builders/v1'
13
+ include TaskwarriorWeb::CommandBuilder::V1
14
+ else
15
+ raise TaskwarriorWeb::UnrecognizedTaskVersion
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ class UnrecognizedTaskVersion < Exception; end
22
+ end
@@ -0,0 +1,64 @@
1
+ module TaskwarriorWeb::CommandBuilder
2
+ module Base
3
+
4
+ TASK_COMMANDS = {
5
+ :add => 'add',
6
+ :query => '_query',
7
+ :count => 'count',
8
+ :complete => ':id done'
9
+ }
10
+
11
+ def build
12
+ unless @command_string
13
+ task_command
14
+ substitute_parts if @command_string =~ /:id/
15
+ end
16
+ parse_params
17
+ @built = "#{self.command_string}#{params}"
18
+ end
19
+
20
+ def task_command
21
+ if TASK_COMMANDS.has_key?(@command.to_sym)
22
+ @command_string = TASK_COMMANDS[@command.to_sym]
23
+ return self
24
+ else
25
+ raise InvalidCommandError
26
+ end
27
+ end
28
+
29
+ def substitute_parts
30
+ if @id
31
+ @command_string.gsub!(':id', "uuid:#{@id.to_s}")
32
+ return self
33
+ else
34
+ raise MissingTaskIDError
35
+ end
36
+ end
37
+
38
+ def parse_params
39
+ string = ''
40
+ string << " '#{@params.delete(:description)}'" if @params.has_key?(:description)
41
+
42
+ if @params.has_key?(:tags)
43
+ tags = @params.delete(:tags)
44
+ tag_indicator = TaskwarriorWeb::Config.property('tag.indicator') || '+'
45
+ tags.each { |tag| string << " #{tag_indicator}#{tag.to_s}" }
46
+ end
47
+
48
+ @params.each do |attr, value|
49
+ if value.respond_to? :each
50
+ value.each { |val| string << " #{attr.to_s}:#{val.to_s}" }
51
+ else
52
+ string << " #{attr.to_s}:#{value.to_s}"
53
+ end
54
+ end
55
+
56
+ @params = string
57
+ return self
58
+ end
59
+
60
+ end
61
+
62
+ class InvalidCommandError < Exception; end
63
+ class MissingTaskIDError < Exception; end
64
+ end
@@ -0,0 +1,35 @@
1
+ require 'taskwarrior-web/command_builders/base'
2
+
3
+ module TaskwarriorWeb::CommandBuilder::V1
4
+
5
+ include TaskwarriorWeb::CommandBuilder::Base
6
+
7
+ def build
8
+ unless @command_string
9
+ task_command
10
+ substitute_parts if @command_string =~ /:id/
11
+ end
12
+ parse_params
13
+ @built = "#{self.command_string}#{params}"
14
+ end
15
+
16
+ # Overridden from TaskwarriorWeb::CommandBuilder::Base
17
+ #
18
+ # Substitute the task's ID for its UUID.
19
+ def substitute_parts
20
+ if @id
21
+ assign_id_from_uuid
22
+ @command_string.gsub!(':id', @id.to_s)
23
+ return self
24
+ else
25
+ raise MissingTaskIDError
26
+ end
27
+ end
28
+
29
+ def assign_id_from_uuid
30
+ @all_tasks ||= TaskwarriorWeb::Task.query('status.not' => [:deleted, :completed])
31
+ @id = @all_tasks.index { |task| task.uuid == @id } + 1
32
+ puts "@id in v1.rb:19: #{@id}"
33
+ end
34
+
35
+ end
@@ -0,0 +1,5 @@
1
+ require 'taskwarrior-web/command_builders/base'
2
+
3
+ module TaskwarriorWeb::CommandBuilder::V2
4
+ include TaskwarriorWeb::CommandBuilder::Base
5
+ end
@@ -4,12 +4,11 @@ module TaskwarriorWeb
4
4
  class Config
5
5
 
6
6
  def self.task_version
7
- unless @task_version
8
- version_line = `task version | grep '^task '`
9
- @task_version = version_line.split.at(1)
10
- end
7
+ @task_version ||= `task _version`
8
+ end
11
9
 
12
- @task_version
10
+ def self.task_major_version
11
+ self.task_version[0,1].to_i
13
12
  end
14
13
 
15
14
  def self.file
@@ -231,6 +231,7 @@ ul.view-mode-group { float: right; position: relative; top: -32px; right: 10px;
231
231
  li.view-mode a { height: 12px; width: 12px; }
232
232
 
233
233
  a#task-add { float: right; margin: 20px 0; }
234
+
234
235
  /********************************
235
236
  * LISTING STYLES
236
237
  *******************************/
@@ -270,10 +271,32 @@ h3.project.done a { color: #ddd; }
270
271
  .doneness-measure { background: #BBFFB6; height: 16px; text-align: center; padding-top: 4px; color: #bbb; font-size: 0.8em; }
271
272
 
272
273
  /********************************
273
- * INPLACE EDITING
274
+ * MESSAGES
274
275
  *******************************/
275
- .inplace-text { width: 250px; height: 30px; padding: 5px; }
276
- .inplace-edit, .inplace-cancel { font-style: italic; }
276
+ #flash-messages .message {
277
+ background-color: #FCF8E3;
278
+ border: 1px solid #FBEED5;
279
+ border-radius: 4px 4px 4px 4px;
280
+ color: #C09853;
281
+ margin-bottom: 18px;
282
+ padding: 8px 35px 8px 14px;
283
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
284
+ }
285
+ #flash-messages .message.success {
286
+ background-color: #DFF0D8;
287
+ border-color: #D6E9C6;
288
+ color: #468847;
289
+ }
290
+ #flash-messages .message.info {
291
+ background-color: #D9EDF7;
292
+ border-color: #BCE8F1;
293
+ color: #3A87AD;
294
+ }
295
+ #flash-messages .message.error {
296
+ background-color: #F2DEDE;
297
+ border-color: #EED3D7;
298
+ color: #B94A48;
299
+ }
277
300
 
278
301
  /********************************
279
302
  * TASK FORM
@@ -3,6 +3,7 @@ $(document).ready(function() {
3
3
  initTooltips();
4
4
  initDatePicker();
5
5
  initAutocomplete();
6
+ initTaskCompletion();
6
7
 
7
8
  // Fluid-specific stuff.
8
9
  if (window.fluid) {
@@ -75,6 +76,27 @@ var initAutocomplete = function() {
75
76
  });
76
77
  };
77
78
 
79
+ var initTaskCompletion = function() {
80
+ $('input.complete').click(function() {
81
+ // Cache the checkbox in case we need to restore it.
82
+ var row = $(this).closest('tr');
83
+ $(this).parent().html('<img src="/images/ajax-loader.gif" />');
84
+ $.ajax({
85
+ url: '/ajax/task-complete/' + $(this).data('task-id'),
86
+ type: 'POST',
87
+ success: function(data) {
88
+ var message = (data === '') ? 'Task marked as completed.' : data;
89
+ set_message(message, 'success');
90
+ row.remove();
91
+ },
92
+ error: function(data) {
93
+ set_message('There was an error when marking the task as completed.', 'error');
94
+ // TODO: Re-insert the checkbox.
95
+ }
96
+ });
97
+ });
98
+ };
99
+
78
100
  // Count updating.
79
101
 
80
102
  var getCount = function(callback) {
@@ -1,61 +1,16 @@
1
1
  require 'taskwarrior-web/config'
2
2
 
3
3
  module TaskwarriorWeb
4
- class Runner
4
+ module Runner
5
5
 
6
6
  TASK_BIN = 'task'
7
7
 
8
- TASK_COMMANDS = {
9
- :add => 'add',
10
- :query => '_query',
11
- :count => 'count'
12
- }
13
-
14
- def self.run(command_obj)
15
- command = build(command_obj)
16
- # Add some logging
17
- `#{TASK_BIN} #{command}`
18
- end
19
-
20
- def self.build(command_obj)
21
- command = task_command(command_obj)
22
- command = substitute_parts(command, command_obj) if command =~ /:id/
23
- params = parsed_params(command_obj.params)
24
- "#{command}#{params}"
25
- end
26
-
27
- def self.task_command(command_obj)
28
- if TASK_COMMANDS.has_key?(command_obj.command.to_sym)
29
- TASK_COMMANDS[command_obj.command.to_sym]
30
- else
31
- raise InvalidCommandError
32
- end
33
- end
34
-
35
- def self.substitute_parts(task_command, command_obj)
36
- if command_obj.id
37
- task_command.gsub(':id', command_obj.id.to_s)
38
- else
39
- raise MissingTaskIDError
40
- end
41
- end
42
-
43
- def self.parsed_params(params)
44
- String.new.tap do |string|
45
- string << " '#{params.delete(:description)}'" if params.has_key?(:description)
46
-
47
- if params.has_key?(:tags)
48
- tags = params.delete(:tags)
49
- tag_indicator = TaskwarriorWeb::Config.property('tag.indicator') || '+'
50
- tags.each { |tag| string << " #{tag_indicator}#{tag.to_s}" }
51
- end
52
-
53
- params.each { |attr, value| string << " #{attr.to_s}:#{value.to_s}" }
54
- end
8
+ def run
9
+ @built ||= build
10
+ to_run = "#{TASK_BIN} #{@built}"
11
+ puts "Final command: #{to_run}"
12
+ `#{to_run}`
55
13
  end
56
14
 
57
15
  end
58
-
59
- class InvalidCommandError < Exception; end
60
- class MissingTaskIDError < Exception; end
61
16
  end
@@ -26,6 +26,10 @@ module TaskwarriorWeb
26
26
  Command.new(:add, nil, self.to_hash).run
27
27
  end
28
28
 
29
+ def complete!
30
+ Command.new(:complete, self.uuid).run
31
+ end
32
+
29
33
  # Make sure that the tags are an array.
30
34
  def tags=(value)
31
35
  @tags = value.is_a?(String) ? value.gsub(', ', ',').split(',') : value
@@ -5,10 +5,6 @@
5
5
  <li><a href="<%= path %>"<%= ' class="selected"' if @current_page.index(path) == 0 %>><%= text %></a></li>
6
6
  <% end %>
7
7
  </ul>
8
- <ul class="button-group view-mode-group">
9
- <li id="view-mode-list" class="view-mode"><a class="button tooltip" data-tooltip="View items in a list" href="javascript:void(0);"><img src="/images/list-view.png" /></a></li>
10
- <li id="view-mode-grid" class="view-mode"><a class="button tooltip" data-tooltip="View items in a grid" href="javascript:void(0);"><img src="/images/grid-view.png" /></a></li>
11
- </ul>
12
8
  </nav>
13
9
  <nav id="subnav-bar">
14
10
  <ul>
@@ -2,6 +2,9 @@
2
2
  <table>
3
3
  <thead>
4
4
  <tr>
5
+ <% if params[:status] == 'pending' %>
6
+ <th></th>
7
+ <% end %>
5
8
  <th>Description</th>
6
9
  <th>Project</th>
7
10
  <th>Due</th>
@@ -16,6 +19,9 @@
16
19
  <% else %>
17
20
  <tr class="<%= task.status %>">
18
21
  <% end %>
22
+ <% if params[:status] == 'pending' %>
23
+ <td><input type="checkbox" class="complete" data-task-id="<%= task.uuid %>" /></td>
24
+ <% end %>
19
25
  <td>
20
26
  <%= task.description %>
21
27
  <% unless task.annotations.nil? || task.annotations.empty? %>
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'taskwarrior-web/command_builder'
3
+
4
+ RSpec::Mocks::setup(TaskwarriorWeb::Config)
5
+
6
+ describe TaskwarriorWeb::CommandBuilder do
7
+ describe '.included' do
8
+ context 'when v2 is reported' do
9
+ it 'should include CommandBuilder V2 module' do
10
+ TaskwarriorWeb::Config.should_receive(:task_version).and_return('2.0.1')
11
+ TestCommandClass.class_eval { include TaskwarriorWeb::CommandBuilder }
12
+ TestCommandClass.should include(TaskwarriorWeb::CommandBuilder::V2)
13
+ end
14
+ end
15
+
16
+ context 'when v1 is reported' do
17
+ it 'should include CommandBuilder V1 module' do
18
+ TaskwarriorWeb::Config.should_receive(:task_version).and_return('1.9.4')
19
+ TestCommandClass.class_eval { include TaskwarriorWeb::CommandBuilder }
20
+ TestCommandClass.should include(TaskwarriorWeb::CommandBuilder::V1)
21
+ end
22
+ end
23
+
24
+ context 'when an invalid version number is reported' do
25
+ it 'should throw an UnrecognizedTaskVersion exception' do
26
+ TaskwarriorWeb::Config.should_receive(:task_version).and_return('95.583.3')
27
+ expect {
28
+ TestCommandClass.class_eval { include TaskwarriorWeb::CommandBuilder }
29
+ }.should raise_exception(TaskwarriorWeb::UnrecognizedTaskVersion)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ class TestCommandClass; end
36
+
37
+ module TaskwarriorWeb::CommandBuilder::V2; end
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'taskwarrior-web/command'
3
+ require 'ostruct'
4
+
5
+ describe TaskwarriorWeb::CommandBuilder::Base do
6
+ describe '#substitute_parts' do
7
+ before do
8
+ @command = TaskwarriorWeb::Command.new(:complete, 34588)
9
+ end
10
+
11
+ it 'should replace the :id string with the given task ID' do
12
+ TaskwarriorWeb::Task.should_receive(:query).and_return([OpenStruct.new(:uuid => 34588)])
13
+ @command.task_command.substitute_parts
14
+ @command.command_string.should eq('1 done')
15
+ end
16
+
17
+ it 'should throw an error if the command has no task ID' do
18
+ @command.id = nil
19
+ expect { @command.substitute_parts }.to raise_error(TaskwarriorWeb::CommandBuilder::MissingTaskIDError)
20
+ end
21
+ end
22
+
23
+ describe '#parse_params' do
24
+ it 'should create a string from the passed paramters' do
25
+ command = TaskwarriorWeb::Command.new(:query, nil, :test => 14, :none => :none, :hello => :hi)
26
+ command.parse_params
27
+ command.params.should eq(' test:14 none:none hello:hi')
28
+ end
29
+
30
+ it 'should prefix tags with the tag.indicator if specified' do
31
+ TaskwarriorWeb::Config.should_receive(:property).with('tag.indicator').and_return(';')
32
+ command = TaskwarriorWeb::Command.new(:add, nil, :tags => [:today, :tomorrow])
33
+ command.parse_params
34
+ command.params.should eq(' ;today ;tomorrow')
35
+ end
36
+
37
+ it 'should prefix tags with a + if no tag.indicator is specified' do
38
+ TaskwarriorWeb::Config.should_receive(:property).with('tag.indicator').and_return(nil)
39
+ command = TaskwarriorWeb::Command.new(:add, nil, :tags => [:today, :tomorrow])
40
+ command.parse_params
41
+ command.params.should eq(' +today +tomorrow')
42
+ end
43
+
44
+ it 'should pull out the description parameter' do
45
+ command = TaskwarriorWeb::Command.new(:add, nil, :description => 'Hello', :status => :pending)
46
+ command.parse_params
47
+ command.params.should eq(" 'Hello' status:pending")
48
+ end
49
+ end
50
+ end
@@ -2,7 +2,7 @@ require File.dirname(__FILE__) + '/../spec_helper'
2
2
  require 'taskwarrior-web/command'
3
3
 
4
4
  describe TaskwarriorWeb::Command do
5
- describe '.initialize' do
5
+ describe '#initialize' do
6
6
  context 'when the command, id, and params are specified' do
7
7
  it 'should set the passed variables' do
8
8
  command = TaskwarriorWeb::Command.new('test', 3, :hello => :hi, :none => :none)
@@ -19,21 +19,4 @@ describe TaskwarriorWeb::Command do
19
19
  command.params.should eq({ :hello => :hi, :none => :none })
20
20
  end
21
21
  end
22
-
23
- describe '#run' do
24
- before do
25
- @command = TaskwarriorWeb::Command.new('test', 4)
26
- end
27
-
28
- it 'should pass the object to the Runner' do
29
- TaskwarriorWeb::Runner.should_receive(:run).with(@command).and_return('{}')
30
- @command.run
31
- end
32
-
33
- it 'should raise an exception if no command is specified' do
34
- command = TaskwarriorWeb::Command.new(nil, 5)
35
- expect { command.run }.to raise_error(TaskwarriorWeb::MissingCommandError)
36
- end
37
-
38
- end
39
22
  end
@@ -3,72 +3,48 @@ require 'taskwarrior-web/runner'
3
3
 
4
4
  describe TaskwarriorWeb::Runner do
5
5
  before do
6
- @command = TaskwarriorWeb::Command.new(:add)
7
- end
8
-
9
- describe '.run' do
10
- context 'valid, without a command' do
11
- before do
12
- TaskwarriorWeb::Runner.should_receive(:`).and_return('{}')
13
- end
14
-
15
- it 'should return the stdout' do
16
- TaskwarriorWeb::Runner.run(@command).should eq('{}')
17
- end
18
-
19
- it 'should not call .substitute_parts if not necessary' do
20
- TaskwarriorWeb::Runner.should_not_receive(:substitute_parts)
21
- TaskwarriorWeb::Runner.run(@command)
22
- end
23
- end
24
-
25
- context 'invalid' do
26
- it 'should throw an exception if the command is not valid' do
27
- @command.command = :test
28
- expect { TaskwarriorWeb::Runner.run(@command) }.to raise_error(TaskwarriorWeb::InvalidCommandError)
29
- end
30
- end
31
-
32
- context 'with a given command' do
33
- it 'should execute the given command' do
34
- TaskwarriorWeb::Runner.should_receive(:`).with('task add').and_return('{}')
35
- TaskwarriorWeb::Runner.run(@command)
36
- end
6
+ TestCommandClass.class_eval do |class_name|
7
+ include TaskwarriorWeb::Runner
37
8
  end
9
+ @object = TestCommandClass.new
38
10
  end
39
11
 
40
- describe '.substitute_parts' do
41
- it 'should replace the :id string with the given task ID' do
42
- command = TaskwarriorWeb::Command.new(:complete, 4)
43
- TaskwarriorWeb::Runner.substitute_parts(':id done', command).should eq('4 done')
12
+ describe 'include' do
13
+ it 'should make the class respond to the run command' do
14
+ @object.should respond_to(:run)
44
15
  end
45
16
 
46
- it 'should throw an error if the command has no task ID' do
47
- expect { TaskwarriorWeb::Runner.substitute_parts(':id done', @command) }.to raise_error(TaskwarriorWeb::MissingTaskIDError)
17
+ it 'should add a TASK_VERSION constant' do
18
+ @object.class.const_get(:TASK_BIN).should eq('task')
48
19
  end
49
20
  end
50
21
 
51
- describe '.parsed_params' do
52
- it 'should create a string from the passed paramters' do
53
- command = TaskwarriorWeb::Command.new(:query, nil, :test => 14, :none => :none, :hello => :hi)
54
- TaskwarriorWeb::Runner.parsed_params(command.params).should eq(' test:14 none:none hello:hi')
22
+ describe '#run' do
23
+ before do
24
+ @object.should_receive(:`).and_return('{"new_thing" => "old_thing"}')
55
25
  end
56
26
 
57
- it 'should prefix tags with the tag.indicator if specified' do
58
- TaskwarriorWeb::Config.should_receive(:property).with('tag.indicator').and_return(';')
59
- command = TaskwarriorWeb::Command.new(:add, nil, :tags => [:today, :tomorrow])
60
- TaskwarriorWeb::Runner.parsed_params(command.params).should eq(' ;today ;tomorrow')
27
+ context 'when the command has not been built' do
28
+ it 'should build the command' do
29
+ @object.should_receive(:build).and_return('build command')
30
+ @object.run
31
+ end
61
32
  end
62
33
 
63
- it 'should prefix tags with a + if no tag.indicator is specified' do
64
- TaskwarriorWeb::Config.should_receive(:property).with('tag.indicator').and_return(nil)
65
- command = TaskwarriorWeb::Command.new(:add, nil, :tags => [:today, :tomorrow])
66
- TaskwarriorWeb::Runner.parsed_params(command.params).should eq(' +today +tomorrow')
34
+ context 'when the command has been built' do
35
+ it 'should not build the command' do
36
+ @object.instance_variable_set(:@built, 'command set manually')
37
+ @object.should_not_receive(:build)
38
+ @object.run
39
+ end
67
40
  end
68
41
 
69
- it 'should pull out the description parameter' do
70
- command = TaskwarriorWeb::Command.new(:add, nil, :description => 'Hello', :status => :pending)
71
- TaskwarriorWeb::Runner.parsed_params(command.params).should eq(" 'Hello' status:pending")
42
+ it 'should return the stdout' do
43
+ @object.should_receive(:build).and_return('build command')
44
+ @object.run.should eq('{"new_thing" => "old_thing"}')
72
45
  end
73
46
  end
47
+
74
48
  end
49
+
50
+ class TestCommandClass; end
@@ -19,21 +19,24 @@ describe TaskwarriorWeb::Task do
19
19
  end
20
20
 
21
21
  describe '.query' do
22
+ before do
23
+ @command = TaskwarriorWeb::Command.new(:query)
24
+ TaskwarriorWeb::Command.should_receive(:new).with(:query, nil).and_return(@command)
25
+ end
26
+
22
27
  it 'should create and run a new Command object' do
23
- command = TaskwarriorWeb::Command.new(:query)
24
- TaskwarriorWeb::Command.should_receive(:new).with(:query, nil).and_return(command)
25
- command.should_receive(:run).and_return('{}')
28
+ @command.should_receive(:run).and_return('{}')
26
29
  TaskwarriorWeb::Task.query
27
30
  end
28
31
 
29
32
  it 'should parse the JSON received from the `task` command' do
30
- TaskwarriorWeb::Runner.should_receive(:run).and_return('{}')
33
+ @command.should_receive(:run).and_return('{}')
31
34
  ::JSON.should_receive(:parse).with('[{}]').and_return([])
32
35
  TaskwarriorWeb::Task.query
33
36
  end
34
37
 
35
38
  it 'should not parse the results when there are no matching tasks' do
36
- TaskwarriorWeb::Runner.should_receive(:run).and_return('No matches.')
39
+ @command.should_receive(:run).and_return('No matches.')
37
40
  ::JSON.should_not_receive(:parse)
38
41
  TaskwarriorWeb::Task.query
39
42
  end
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "taskwarrior-web"
6
- s.version = '0.0.15'
6
+ s.version = '1.0.0'
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ["Jake Bell"]
9
9
  s.email = ["jake@theunraveler.com"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taskwarrior-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-12 00:00:00.000000000 Z
12
+ date: 2012-03-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
16
- requirement: &70154504021780 !ruby/object:Gem::Requirement
16
+ requirement: &70160263316020 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70154504021780
24
+ version_requirements: *70160263316020
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: parseconfig
27
- requirement: &70154504020500 !ruby/object:Gem::Requirement
27
+ requirement: &70160263313300 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70154504020500
35
+ version_requirements: *70160263313300
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: vegas
38
- requirement: &70154504040200 !ruby/object:Gem::Requirement
38
+ requirement: &70160263347360 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70154504040200
46
+ version_requirements: *70160263347360
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rinku
49
- requirement: &70154504039160 !ruby/object:Gem::Requirement
49
+ requirement: &70160263345300 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70154504039160
57
+ version_requirements: *70160263345300
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rake
60
- requirement: &70154504036820 !ruby/object:Gem::Requirement
60
+ requirement: &70160263342060 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70154504036820
68
+ version_requirements: *70160263342060
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rack-test
71
- requirement: &70154504034640 !ruby/object:Gem::Requirement
71
+ requirement: &70160263340640 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70154504034640
79
+ version_requirements: *70160263340640
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rspec
82
- requirement: &70154504033940 !ruby/object:Gem::Requirement
82
+ requirement: &70160263363240 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70154504033940
90
+ version_requirements: *70160263363240
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: simplecov
93
- requirement: &70154504049400 !ruby/object:Gem::Requirement
93
+ requirement: &70160263362440 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70154504049400
101
+ version_requirements: *70160263362440
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: guard-rspec
104
- requirement: &70154504048520 !ruby/object:Gem::Requirement
104
+ requirement: &70160263361760 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: '0'
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70154504048520
112
+ version_requirements: *70160263361760
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: guard-bundler
115
- requirement: &70154504047860 !ruby/object:Gem::Requirement
115
+ requirement: &70160263359760 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,7 +120,7 @@ dependencies:
120
120
  version: '0'
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *70154504047860
123
+ version_requirements: *70160263359760
124
124
  description: This gem provides a graphical frontend for the Taskwarrior task manager.
125
125
  It is based on Sinatra.
126
126
  email:
@@ -143,6 +143,10 @@ files:
143
143
  - lib/taskwarrior-web.rb
144
144
  - lib/taskwarrior-web/app.rb
145
145
  - lib/taskwarrior-web/command.rb
146
+ - lib/taskwarrior-web/command_builder.rb
147
+ - lib/taskwarrior-web/command_builders/base.rb
148
+ - lib/taskwarrior-web/command_builders/v1.rb
149
+ - lib/taskwarrior-web/command_builders/v2.rb
146
150
  - lib/taskwarrior-web/config.rb
147
151
  - lib/taskwarrior-web/helpers.rb
148
152
  - lib/taskwarrior-web/public/css/gh-buttons.css
@@ -174,8 +178,6 @@ files:
174
178
  - lib/taskwarrior-web/public/js/jquery.tagsinput.js
175
179
  - lib/taskwarrior-web/public/js/jquery.tipsy.js
176
180
  - lib/taskwarrior-web/runner.rb
177
- - lib/taskwarrior-web/runners/v1.rb
178
- - lib/taskwarrior-web/runners/v2.rb
179
181
  - lib/taskwarrior-web/task.rb
180
182
  - lib/taskwarrior-web/views/404.erb
181
183
  - lib/taskwarrior-web/views/_navigation.erb
@@ -186,6 +188,10 @@ files:
186
188
  - lib/taskwarrior-web/views/task_form.erb
187
189
  - spec/app/app_spec.rb
188
190
  - spec/app/helpers_spec.rb
191
+ - spec/models/command_builder_spec.rb
192
+ - spec/models/command_builders/base_spec.rb
193
+ - spec/models/command_builders/v1_spec.rb
194
+ - spec/models/command_builders/v2_spec.rb
189
195
  - spec/models/command_spec.rb
190
196
  - spec/models/runner_spec.rb
191
197
  - spec/models/task_spec.rb
@@ -211,7 +217,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
217
  version: '0'
212
218
  segments:
213
219
  - 0
214
- hash: -2283855477715549866
220
+ hash: -1098967059428710404
215
221
  requirements: []
216
222
  rubyforge_project: taskwarrior-web
217
223
  rubygems_version: 1.8.11
@@ -221,6 +227,10 @@ summary: Web frontend for taskwarrior command line task manager.
221
227
  test_files:
222
228
  - spec/app/app_spec.rb
223
229
  - spec/app/helpers_spec.rb
230
+ - spec/models/command_builder_spec.rb
231
+ - spec/models/command_builders/base_spec.rb
232
+ - spec/models/command_builders/v1_spec.rb
233
+ - spec/models/command_builders/v2_spec.rb
224
234
  - spec/models/command_spec.rb
225
235
  - spec/models/runner_spec.rb
226
236
  - spec/models/task_spec.rb
@@ -1,11 +0,0 @@
1
- module TaskwarriorWeb
2
- module Runner
3
- module Version1
4
-
5
- def self.run
6
- puts 'Called versioned run method.'
7
- end
8
-
9
- end
10
- end
11
- end
@@ -1,7 +0,0 @@
1
- module TaskwarriorWeb
2
- module Runner
3
- module Version2
4
-
5
- end
6
- end
7
- end