taskwarrior-web 0.0.15 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +5 -0
- data/README.md +2 -10
- data/lib/taskwarrior-web/app.rb +6 -0
- data/lib/taskwarrior-web/command.rb +6 -11
- data/lib/taskwarrior-web/command_builder.rb +22 -0
- data/lib/taskwarrior-web/command_builders/base.rb +64 -0
- data/lib/taskwarrior-web/command_builders/v1.rb +35 -0
- data/lib/taskwarrior-web/command_builders/v2.rb +5 -0
- data/lib/taskwarrior-web/config.rb +4 -5
- data/lib/taskwarrior-web/public/css/styles.css +26 -3
- data/lib/taskwarrior-web/public/js/application.js +22 -0
- data/lib/taskwarrior-web/runner.rb +6 -51
- data/lib/taskwarrior-web/task.rb +4 -0
- data/lib/taskwarrior-web/views/_navigation.erb +0 -4
- data/lib/taskwarrior-web/views/listing.erb +6 -0
- data/spec/models/command_builder_spec.rb +37 -0
- data/spec/models/command_builders/base_spec.rb +50 -0
- data/spec/models/command_builders/v1_spec.rb +0 -0
- data/spec/models/command_builders/v2_spec.rb +0 -0
- data/spec/models/command_spec.rb +1 -18
- data/spec/models/runner_spec.rb +28 -52
- data/spec/models/task_spec.rb +8 -5
- data/taskwarrior-web.gemspec +1 -1
- metadata +35 -25
- data/lib/taskwarrior-web/runners/v1.rb +0 -11
- data/lib/taskwarrior-web/runners/v2.rb +0 -7
data/CHANGELOG.md
CHANGED
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
|
[](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
|
|
data/lib/taskwarrior-web/app.rb
CHANGED
@@ -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
|
-
|
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
|
@@ -4,12 +4,11 @@ module TaskwarriorWeb
|
|
4
4
|
class Config
|
5
5
|
|
6
6
|
def self.task_version
|
7
|
-
|
8
|
-
|
9
|
-
@task_version = version_line.split.at(1)
|
10
|
-
end
|
7
|
+
@task_version ||= `task _version`
|
8
|
+
end
|
11
9
|
|
12
|
-
|
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
|
-
*
|
274
|
+
* MESSAGES
|
274
275
|
*******************************/
|
275
|
-
|
276
|
-
|
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
|
-
|
4
|
+
module Runner
|
5
5
|
|
6
6
|
TASK_BIN = 'task'
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
:
|
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
|
data/lib/taskwarrior-web/task.rb
CHANGED
@@ -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
|
File without changes
|
File without changes
|
data/spec/models/command_spec.rb
CHANGED
@@ -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 '
|
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
|
data/spec/models/runner_spec.rb
CHANGED
@@ -3,72 +3,48 @@ require 'taskwarrior-web/runner'
|
|
3
3
|
|
4
4
|
describe TaskwarriorWeb::Runner do
|
5
5
|
before do
|
6
|
-
|
7
|
-
|
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 '
|
41
|
-
it 'should
|
42
|
-
|
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
|
47
|
-
|
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 '
|
52
|
-
|
53
|
-
|
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
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
70
|
-
|
71
|
-
|
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
|
data/spec/models/task_spec.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
39
|
+
@command.should_receive(:run).and_return('No matches.')
|
37
40
|
::JSON.should_not_receive(:parse)
|
38
41
|
TaskwarriorWeb::Task.query
|
39
42
|
end
|
data/taskwarrior-web.gemspec
CHANGED
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
|
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
|
+
date: 2012-03-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra
|
16
|
-
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: *
|
24
|
+
version_requirements: *70160263316020
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: parseconfig
|
27
|
-
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: *
|
35
|
+
version_requirements: *70160263313300
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: vegas
|
38
|
-
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: *
|
46
|
+
version_requirements: *70160263347360
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rinku
|
49
|
-
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: *
|
57
|
+
version_requirements: *70160263345300
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rake
|
60
|
-
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: *
|
68
|
+
version_requirements: *70160263342060
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rack-test
|
71
|
-
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: *
|
79
|
+
version_requirements: *70160263340640
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rspec
|
82
|
-
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: *
|
90
|
+
version_requirements: *70160263363240
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: simplecov
|
93
|
-
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: *
|
101
|
+
version_requirements: *70160263362440
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: guard-rspec
|
104
|
-
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: *
|
112
|
+
version_requirements: *70160263361760
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: guard-bundler
|
115
|
-
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: *
|
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: -
|
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
|