paradeiser 0.2.0 → 0.4.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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/Guardfile +1 -0
- data/README.md +98 -6
- data/TODO.md +22 -6
- data/VISION.md +171 -26
- data/bin/par +20 -4
- data/lib/paradeiser/controllers/breaks_controller.rb +0 -1
- data/lib/paradeiser/controllers/controller.rb +15 -1
- data/lib/paradeiser/controllers/paradeiser_controller.rb +23 -1
- data/lib/paradeiser/controllers/pomodori_controller.rb +23 -1
- data/lib/paradeiser/errors.rb +6 -0
- data/lib/paradeiser/executor.rb +1 -1
- data/lib/paradeiser/initializers/inflections.rb +3 -0
- data/lib/paradeiser/models/break.rb +1 -0
- data/lib/paradeiser/models/pomodoro.rb +13 -1
- data/lib/paradeiser/models/repository.rb +11 -1
- data/lib/paradeiser/models/scheduled.rb +7 -1
- data/lib/paradeiser/refinements/pluralize.rb +10 -0
- data/lib/paradeiser/router.rb +0 -2
- data/lib/paradeiser/version.rb +1 -1
- data/lib/paradeiser/view.rb +1 -1
- data/lib/paradeiser/views/breaks/finish.erb +1 -0
- data/lib/paradeiser/views/breaks/start.erb +1 -0
- data/lib/paradeiser/views/paradeiser/init.erb +1 -1
- data/lib/paradeiser/views/paradeiser/report.erb +10 -4
- data/lib/paradeiser/views/paradeiser/status.erb +2 -1
- data/lib/paradeiser/views/pomodori/annotate.erb +1 -0
- data/lib/paradeiser/views/pomodori/cancel.erb +1 -0
- data/lib/paradeiser/views/pomodori/interrupt.erb +1 -0
- data/lib/paradeiser/views/pomodori/log.erb +1 -0
- data/lib/paradeiser/views/pomodori/start.erb +1 -1
- data/paradeiser.gemspec +2 -0
- data/test/bin/notify-send +1 -0
- data/test/helper.rb +7 -24
- data/test/integration/test_annotate.rb +19 -0
- data/test/integration/test_finish.rb +9 -0
- data/test/integration/test_interrupt.rb +9 -0
- data/test/integration/test_log.rb +12 -0
- data/test/integration/test_no_args.rb +7 -0
- data/test/integration/test_start.rb +7 -0
- data/test/integration/test_status.rb +10 -0
- data/test/integration/test_unknown.rb +7 -0
- data/test/lib/at_mock.rb +1 -1
- data/test/lib/controller_test.rb +25 -0
- data/test/lib/integration_test.rb +45 -0
- data/test/lib/paradeiser_controller_test.rb +7 -0
- data/test/lib/view_test.rb +12 -0
- data/test/unit/test_break.rb +7 -44
- data/test/unit/test_break_view.rb +22 -0
- data/test/unit/test_breaks_controller.rb +66 -0
- data/test/unit/test_paradeiser_controller_export.rb +107 -0
- data/test/unit/test_paradeiser_controller_report.rb +73 -26
- data/test/unit/test_paradeiser_controller_status.rb +42 -24
- data/test/unit/test_paradeiser_view_init.rb +7 -0
- data/test/unit/test_paradeiser_view_report.rb +132 -0
- data/test/unit/test_paradeiser_view_status.rb +17 -0
- data/test/unit/test_pomodori_controller.rb +241 -33
- data/test/unit/test_pomodori_view.rb +26 -13
- data/test/unit/test_pomodoro.rb +23 -81
- data/test/unit/test_pomodoro_hooks.rb +12 -25
- data/test/unit/test_repository.rb +5 -21
- data/test/unit/test_scheduler.rb +1 -1
- metadata +61 -8
- data/test/integration/test_par.rb +0 -17
- data/test/unit/test_break_controller.rb +0 -56
- data/test/unit/test_paradeiser_view.rb +0 -66
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestAnnotateCommand < Paradeiser::IntegrationTest
|
4
|
+
def test_annotate_no_previous
|
5
|
+
refute_command('annotate')
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_annotate_active
|
9
|
+
assert_command('start')
|
10
|
+
assert_command('annotate', 0, name.split('_'))
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_annotate_second_last_successful
|
14
|
+
assert_command('start')
|
15
|
+
assert_command('finish')
|
16
|
+
assert_command('break')
|
17
|
+
assert_command('annotate', 0, name.split('_'))
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestStatusCommand < Paradeiser::IntegrationTest
|
4
|
+
def test_status
|
5
|
+
assert_command('status', 255) # not initialized
|
6
|
+
assert_command('start')
|
7
|
+
out = assert_command('status')
|
8
|
+
refute_empty(out, "Expected 'status' to produce an non-empty output")
|
9
|
+
end
|
10
|
+
end
|
data/test/lib/at_mock.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module Paradeiser
|
2
|
+
class ControllerTest < MiniTest::Test
|
3
|
+
def invoke(method, args = nil, options = nil, *attributes)
|
4
|
+
controller = Paradeiser.const_get("#{model.pluralize.capitalize}Controller".to_sym).new(method)
|
5
|
+
|
6
|
+
stdout, stderr = Repository.stub :backend, @backend do
|
7
|
+
Scheduler.stub(:add, nil) do
|
8
|
+
Scheduler.stub(:clear, nil) do
|
9
|
+
capture_io do
|
10
|
+
controller.call(Array(args), options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
result = Hash[attributes.map do |e|
|
17
|
+
[e.split('@').last.to_sym, controller.get_binding.eval(e)]
|
18
|
+
end]
|
19
|
+
|
20
|
+
result[:stdout] = stdout
|
21
|
+
result[:stderr] = stderr
|
22
|
+
result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
module Paradeiser
|
4
|
+
#
|
5
|
+
# We put all integration tests into separate files so we only run one at a
|
6
|
+
# time after a change. These tests are expensive to run.
|
7
|
+
#
|
8
|
+
class IntegrationTest < MiniTest::Test
|
9
|
+
PAR = 'bin/par'
|
10
|
+
include Executor
|
11
|
+
|
12
|
+
def setup
|
13
|
+
if Scheduler.list.any?
|
14
|
+
@do_not_clear = true
|
15
|
+
raise "The at queue '#{queue}' is not empty. Clean it up before running this test again."
|
16
|
+
end
|
17
|
+
|
18
|
+
@orig_PAR_DIR = ENV['PAR_DIR']
|
19
|
+
ENV['PAR_DIR'] = Dir.mktmpdir
|
20
|
+
ENV['PAR_AT_QUEUE'] = 'i'
|
21
|
+
assert_command('init')
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
FileUtils.rm_rf(Paradeiser.par_dir)
|
26
|
+
ENV['PAR_DIR'] = @orig_PAR_DIR
|
27
|
+
Scheduler.clear unless @do_not_clear
|
28
|
+
raise "The at queue #{queue} is not empty. Clean it up before running this test again." if Scheduler.list.any?
|
29
|
+
ENV.delete('PAR_AT_QUEUE')
|
30
|
+
end
|
31
|
+
|
32
|
+
def assert_command(cmd, expected_status = 0, *args)
|
33
|
+
out, err, status = Open3.capture3("#{PAR} #{cmd} #{Shellwords.join(args)}")
|
34
|
+
assert_equal(expected_status, status.exitstatus, "Expected exit status to be #{expected_status}, but it was #{status.exitstatus}. STDERR is: '#{err}'")
|
35
|
+
assert_empty(err)
|
36
|
+
out
|
37
|
+
end
|
38
|
+
|
39
|
+
def refute_command(cmd, expected_status = 1, *args)
|
40
|
+
out, err, status = Open3.capture3("#{PAR} #{cmd}")
|
41
|
+
assert_equal(expected_status, status.exitstatus, "Expected exit status to be #{expected_status}, but it was #{status.exitstatus}.")
|
42
|
+
[out, err]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/test/unit/test_break.rb
CHANGED
@@ -2,26 +2,14 @@ require 'helper'
|
|
2
2
|
|
3
3
|
class TestBreak < MiniTest::Test
|
4
4
|
def setup
|
5
|
-
@break = Break
|
5
|
+
@break = produce(Break)
|
6
6
|
end
|
7
7
|
|
8
|
-
def
|
9
|
-
assert_equal(:idle, @break.status_name)
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_break
|
13
|
-
start!
|
8
|
+
def test_new
|
14
9
|
assert_equal(:active, @break.status_name)
|
15
10
|
end
|
16
11
|
|
17
|
-
def test_finish_idle
|
18
|
-
assert_raises StateMachine::InvalidTransition do
|
19
|
-
finish!
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
12
|
def test_finish_break
|
24
|
-
start!
|
25
13
|
assert_equal(:active, @break.status_name)
|
26
14
|
|
27
15
|
now = srand
|
@@ -38,43 +26,25 @@ class TestBreak < MiniTest::Test
|
|
38
26
|
assert_equal(5 * 60, @break.length)
|
39
27
|
end
|
40
28
|
|
41
|
-
|
42
|
-
def test_duration_idle
|
43
|
-
assert_equal(0, @break.duration)
|
44
|
-
end
|
45
|
-
|
46
29
|
def test_duration
|
47
|
-
|
48
|
-
|
49
|
-
Time.stub :now, Time.at(now) do
|
50
|
-
start!
|
51
|
-
end
|
52
|
-
|
53
|
-
later = now + rand(42)
|
30
|
+
later = @started + rand(42)
|
54
31
|
|
55
32
|
Time.stub :now, Time.at(later) do
|
56
|
-
assert_equal(later -
|
33
|
+
assert_equal(later - @started, @break.duration)
|
57
34
|
end
|
58
35
|
end
|
59
36
|
|
60
37
|
def test_duration_finished
|
61
|
-
|
62
|
-
|
63
|
-
Time.stub :now, Time.at(now) do
|
64
|
-
start!
|
65
|
-
end
|
66
|
-
|
67
|
-
later = now + rand(42)
|
38
|
+
later = @started + rand(42)
|
68
39
|
|
69
40
|
Time.stub :now, Time.at(later) do
|
70
41
|
finish!
|
71
42
|
end
|
72
43
|
|
73
|
-
assert_equal(later -
|
44
|
+
assert_equal(later - @started, @break.duration)
|
74
45
|
end
|
75
46
|
|
76
47
|
def test_finish_break
|
77
|
-
start!
|
78
48
|
finish!
|
79
49
|
assert_raises StateMachine::InvalidTransition do
|
80
50
|
finish!
|
@@ -82,15 +52,8 @@ class TestBreak < MiniTest::Test
|
|
82
52
|
end
|
83
53
|
|
84
54
|
def test_remaining
|
85
|
-
now = srand
|
86
|
-
|
87
|
-
Time.stub :now, Time.at(now) do
|
88
|
-
start!
|
89
|
-
assert_equal(@break.length, @break.remaining)
|
90
|
-
end
|
91
|
-
|
92
55
|
delta = 120
|
93
|
-
later =
|
56
|
+
later = @started + delta
|
94
57
|
|
95
58
|
Time.stub :now, Time.at(later) do
|
96
59
|
assert_equal(@break.length - delta, @break.remaining)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestBreakView < ViewTest
|
4
|
+
def setup
|
5
|
+
@break = produce(Break)
|
6
|
+
@break.id = 1
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_start
|
10
|
+
assert_match(/^Started a new break \(5 minutes\)\.$/m, render(:start))
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_finish
|
14
|
+
assert_match(/^Finished break #1 after .* minutes\.$/m, render(:finish))
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def model
|
20
|
+
'Break'
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestBreaksController < ControllerTest
|
4
|
+
def setup
|
5
|
+
@backend = PStoreMock.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def model
|
9
|
+
'break'
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_break
|
13
|
+
attrs = invoke(:start, nil, nil, '@break', 'exitstatus', 'has_output')
|
14
|
+
assert_equal(:active, attrs[:break].status_name)
|
15
|
+
assert_equal(false, attrs[:has_output])
|
16
|
+
assert_empty(attrs[:stdout])
|
17
|
+
assert_empty(attrs[:stderr])
|
18
|
+
assert_equal(1, @backend.size)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_break_verbose
|
22
|
+
attrs = invoke(:start, nil, OpenStruct.new(:verbose => true), '@break', 'exitstatus', 'has_output')
|
23
|
+
assert_equal(:active, attrs[:break].status_name)
|
24
|
+
assert_equal(false, attrs[:has_output])
|
25
|
+
refute_empty(attrs[:stdout])
|
26
|
+
assert_empty(attrs[:stderr])
|
27
|
+
assert_equal(1, @backend.size)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_break_active
|
31
|
+
invoke(:start)
|
32
|
+
assert_equal(1, @backend.size)
|
33
|
+
|
34
|
+
assert_raises SingletonError do
|
35
|
+
invoke(:start)
|
36
|
+
end
|
37
|
+
assert_equal(1, @backend.size)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_finish
|
41
|
+
invoke(:start)
|
42
|
+
attrs = invoke(:finish, nil, nil, '@break', 'exitstatus', 'has_output')
|
43
|
+
assert_equal(:finished, attrs[:break].status_name)
|
44
|
+
assert_equal(false, attrs[:has_output])
|
45
|
+
assert_empty(attrs[:stdout])
|
46
|
+
assert_empty(attrs[:stderr])
|
47
|
+
assert_equal(1, @backend.size)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_finish_verbose
|
51
|
+
invoke(:start)
|
52
|
+
attrs = invoke(:finish, nil, OpenStruct.new(:verbose => true), '@break', 'exitstatus', 'has_output')
|
53
|
+
assert_equal(:finished, attrs[:break].status_name)
|
54
|
+
assert_equal(false, attrs[:has_output])
|
55
|
+
refute_empty(attrs[:stdout])
|
56
|
+
assert_empty(attrs[:stderr])
|
57
|
+
assert_equal(1, @backend.size)
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_finish_idle
|
61
|
+
assert_raises NotActiveError do
|
62
|
+
invoke(:finish)
|
63
|
+
end
|
64
|
+
assert_equal(0, @backend.size)
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
#
|
4
|
+
# There is no view for export, so we need to test the entire results here
|
5
|
+
#
|
6
|
+
class TestParadeiserControllerExport < ParadeiserControllerTest
|
7
|
+
def setup
|
8
|
+
@backend = PStoreMock.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_empty
|
12
|
+
attrs = invoke(:export)
|
13
|
+
assert_empty(attrs[:stderr])
|
14
|
+
|
15
|
+
result = JSON.parse(attrs[:stdout])
|
16
|
+
assert(result)
|
17
|
+
assert_empty(result)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_pomodoro
|
21
|
+
pom = produce(Pomodoro)
|
22
|
+
started_at = Time.new(8)
|
23
|
+
pom.started_at = started_at
|
24
|
+
pom.finish!
|
25
|
+
finished_at = Time.new(16)
|
26
|
+
pom.finished_at = finished_at
|
27
|
+
@backend[:bar] = pom
|
28
|
+
|
29
|
+
attrs = invoke(:export)
|
30
|
+
assert_empty(attrs[:stderr])
|
31
|
+
result = JSON.parse(attrs[:stdout])
|
32
|
+
|
33
|
+
assert(result)
|
34
|
+
refute_empty(result)
|
35
|
+
assert_equal(1, result.size)
|
36
|
+
p = result.first
|
37
|
+
assert(p)
|
38
|
+
|
39
|
+
assert_equal('Pomodoro', p['type'])
|
40
|
+
assert_equal(1500, p['length'])
|
41
|
+
assert_equal('finished', p['status'])
|
42
|
+
assert_equal(started_at.as_json, p['started_at'])
|
43
|
+
assert_equal(finished_at.as_json, p['finished_at'])
|
44
|
+
|
45
|
+
interrupts = p['interrupts']
|
46
|
+
assert(interrupts)
|
47
|
+
assert_empty(interrupts)
|
48
|
+
|
49
|
+
annotations = p['annotations']
|
50
|
+
assert(annotations)
|
51
|
+
assert_empty(annotations)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_break
|
55
|
+
br3ak = produce(Break)
|
56
|
+
started_at = Time.new(8)
|
57
|
+
br3ak.started_at = started_at
|
58
|
+
br3ak.finish!
|
59
|
+
finished_at = Time.new(16)
|
60
|
+
br3ak.finished_at = finished_at
|
61
|
+
@backend[:bar] = br3ak
|
62
|
+
|
63
|
+
attrs = invoke(:export)
|
64
|
+
assert_empty(attrs[:stderr])
|
65
|
+
result = JSON.parse(attrs[:stdout])
|
66
|
+
|
67
|
+
assert(result)
|
68
|
+
refute_empty(result)
|
69
|
+
assert_equal(1, result.size)
|
70
|
+
p = result.first
|
71
|
+
assert(p)
|
72
|
+
|
73
|
+
assert_equal('Break', p['type'])
|
74
|
+
assert_equal(300, p['length'])
|
75
|
+
assert_equal('finished', p['status'])
|
76
|
+
assert_equal(started_at.as_json, p['started_at'])
|
77
|
+
assert_equal(finished_at.as_json, p['finished_at'])
|
78
|
+
|
79
|
+
refute(p['interrupts'])
|
80
|
+
refute(p['annotations'])
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_multiple
|
84
|
+
br3ak = produce(Break)
|
85
|
+
br3ak.started_at = Time.new(8)
|
86
|
+
br3ak.finish!
|
87
|
+
br3ak.finished_at = Time.new(16)
|
88
|
+
@backend[:bar] = br3ak
|
89
|
+
|
90
|
+
pom = produce(Pomodoro)
|
91
|
+
pom.started_at = Time.new(8)
|
92
|
+
pom.finish!
|
93
|
+
pom.finished_at = Time.new(16)
|
94
|
+
@backend[:foo] = pom
|
95
|
+
|
96
|
+
attrs = invoke(:export)
|
97
|
+
assert_empty(attrs[:stderr])
|
98
|
+
result = JSON.parse(attrs[:stdout])
|
99
|
+
|
100
|
+
assert(result)
|
101
|
+
refute_empty(result)
|
102
|
+
assert_equal(2, result.size)
|
103
|
+
|
104
|
+
assert_equal('Break', result.first['type'])
|
105
|
+
assert_equal('Pomodoro', result.last['type'])
|
106
|
+
end
|
107
|
+
end
|