paradeiser 0.1.0 → 0.2.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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/README.md +96 -35
  4. data/TODO.md +14 -15
  5. data/VISION.md +92 -84
  6. data/bin/{pom → par} +32 -2
  7. data/doc/Paradeiser::Break_status.svg +50 -0
  8. data/doc/Paradeiser::Pomodoro_status.svg +40 -22
  9. data/lib/paradeiser.rb +3 -3
  10. data/lib/paradeiser/controllers/breaks_controller.rb +19 -0
  11. data/lib/paradeiser/controllers/controller.rb +3 -3
  12. data/lib/paradeiser/controllers/paradeiser_controller.rb +13 -2
  13. data/lib/paradeiser/controllers/pomodori_controller.rb +36 -17
  14. data/lib/paradeiser/errors.rb +12 -6
  15. data/lib/paradeiser/executor.rb +2 -0
  16. data/lib/paradeiser/initializers/inflections.rb +4 -0
  17. data/lib/paradeiser/models/break.rb +40 -0
  18. data/lib/paradeiser/models/hook.rb +4 -4
  19. data/lib/paradeiser/models/interrupt.rb +18 -0
  20. data/lib/paradeiser/models/job.rb +1 -1
  21. data/lib/paradeiser/models/pomodoro.rb +30 -22
  22. data/lib/paradeiser/models/repository.rb +26 -13
  23. data/lib/paradeiser/models/scheduled.rb +25 -0
  24. data/lib/paradeiser/models/scheduler.rb +1 -1
  25. data/lib/paradeiser/models/status.rb +21 -0
  26. data/lib/paradeiser/{refinements.rb → refinements/numeric.rb} +4 -0
  27. data/lib/paradeiser/router.rb +12 -7
  28. data/lib/paradeiser/version.rb +1 -1
  29. data/lib/paradeiser/views/paradeiser/init.erb +1 -1
  30. data/lib/paradeiser/views/paradeiser/report.erb +5 -0
  31. data/lib/paradeiser/views/paradeiser/status.erb +13 -0
  32. data/paradeiser.gemspec +2 -0
  33. data/templates/linux/hooks/after-finish-break +10 -0
  34. data/templates/linux/hooks/after-finish-pomodoro +10 -0
  35. data/templates/linux/hooks/after-start-break +7 -0
  36. data/templates/linux/hooks/after-start-pomodoro +7 -0
  37. data/templates/mac/hooks/after-finish-break +10 -0
  38. data/templates/mac/hooks/after-finish-pomodoro +10 -0
  39. data/templates/mac/hooks/after-start-break +7 -0
  40. data/templates/mac/hooks/after-start-pomodoro +7 -0
  41. data/test/helper.rb +37 -4
  42. data/test/integration/{test_pom.rb → test_par.rb} +4 -4
  43. data/test/lib/{pomodoro_mock.rb → schedulable_mock.rb} +9 -1
  44. data/test/unit/test_break.rb +99 -0
  45. data/test/unit/test_break_controller.rb +56 -0
  46. data/test/unit/test_interrupt.rb +36 -0
  47. data/test/unit/test_paradeiser_controller_init.rb +92 -0
  48. data/test/unit/test_paradeiser_controller_report.rb +44 -0
  49. data/test/unit/test_paradeiser_controller_status.rb +70 -0
  50. data/test/unit/test_paradeiser_view.rb +66 -0
  51. data/test/unit/test_pomodori_controller.rb +87 -31
  52. data/test/unit/test_pomodori_view.rb +0 -50
  53. data/test/unit/test_pomodoro.rb +131 -9
  54. data/test/unit/test_pomodoro_hooks.rb +165 -17
  55. data/test/unit/test_repository.rb +38 -15
  56. data/test/unit/test_router.rb +4 -4
  57. data/test/unit/test_status.rb +26 -0
  58. metadata +70 -17
  59. data/lib/paradeiser/views/pomodori/report.erb +0 -5
  60. data/lib/paradeiser/views/pomodori/status.erb +0 -9
  61. data/templates/linux/hooks/after-finish +0 -10
  62. data/templates/linux/hooks/after-start +0 -7
  63. data/templates/mac/hooks/after-finish +0 -10
  64. data/templates/mac/hooks/after-start +0 -7
  65. data/test/unit/test_paradeiser_controller.rb +0 -88
@@ -6,7 +6,7 @@ class TestPomodoriController < MiniTest::Test
6
6
  end
7
7
 
8
8
  def test_start
9
- pom, has_output = invoke(:start, '@pom', 'has_output')
9
+ pom, has_output = invoke(:start, nil, '@pom', 'has_output')
10
10
  assert_equal(:active, pom.status_name)
11
11
  assert_equal(false, has_output)
12
12
  assert_equal(1, @backend.size)
@@ -24,80 +24,136 @@ class TestPomodoriController < MiniTest::Test
24
24
 
25
25
  def test_finish
26
26
  invoke(:start)
27
- pom, has_output = invoke(:finish, '@pom', 'has_output')
27
+ pom, has_output = invoke(:finish, nil, '@pom', 'has_output')
28
28
  assert_equal(:finished, pom.status_name)
29
29
  assert_equal(false, has_output)
30
30
  assert_equal(1, @backend.size)
31
31
  end
32
32
 
33
33
  def test_finish_idle
34
- assert_raises NoActivePomodoroError do
34
+ assert_raises NotActiveError do
35
35
  invoke(:finish)
36
36
  end
37
37
  assert_equal(0, @backend.size)
38
38
  end
39
39
 
40
- def test_report_idle
41
- pomodori, has_output = invoke(:report, '@pom', 'has_output')
42
- assert_empty(pomodori)
43
- assert_equal(true, has_output)
40
+ def test_finish_canceled
41
+ invoke(:start)
42
+ invoke(:cancel)
43
+ assert_equal(1, @backend.size)
44
+
45
+ assert_raises NotActiveError do
46
+ invoke(:finish)
47
+ end
48
+ assert_equal(1, @backend.size)
49
+ assert_equal(:canceled, @backend[@backend.roots.first].status_name)
50
+ end
51
+
52
+ def test_interrupt_idle
53
+ assert_raises NotActiveError do
54
+ invoke(:interrupt)
55
+ end
56
+ assert_equal(0, @backend.size)
44
57
  end
45
58
 
46
- def test_report_active
59
+ def test_interrupt_active
47
60
  invoke(:start)
48
- pomodori, has_output = invoke(:report, '@pom', 'has_output')
49
- assert_equal(1, pomodori.size)
50
- assert_equal(true, has_output)
61
+ pom, has_output = invoke(:interrupt, OpenStruct.new, '@pom', 'has_output')
62
+ assert_equal(:active, pom.status_name)
63
+
64
+ interrupts = pom.interrupts
65
+ refute_nil(interrupts)
66
+ refute_empty(interrupts)
67
+ assert_equal(1, interrupts.size)
68
+
69
+ interrupt = interrupts.first
70
+ refute_nil(interrupt)
71
+ refute_nil(interrupt.created_at)
72
+ assert_equal(:internal, interrupt.type)
51
73
  end
52
74
 
53
- def test_report_finished
75
+ def test_interrupt_active_internal
54
76
  invoke(:start)
55
- invoke(:finish)
77
+ pom = invoke(:interrupt, OpenStruct.new(:internal => true), '@pom')
78
+ interrupt = pom.interrupts.first
79
+ assert_equal(:internal, interrupt.type)
80
+ end
81
+
82
+ def test_interrupt_active_external
56
83
  invoke(:start)
57
- pomodori, has_output = invoke(:report, '@pom', 'has_output')
58
- assert_equal(2, pomodori.size)
59
- assert_equal(true, has_output)
84
+ pom = invoke(:interrupt, OpenStruct.new(:external => true), '@pom')
85
+ interrupt = pom.interrupts.first
86
+ assert_equal(:external, interrupt.type)
87
+ end
88
+
89
+ def test_interrupt_finished
90
+ invoke(:start)
91
+ invoke(:finish)
92
+ assert_equal(1, @backend.size)
93
+
94
+ assert_raises NotActiveError do
95
+ invoke(:interrupt)
96
+ end
97
+
98
+ assert_equal(1, @backend.size)
60
99
  end
61
100
 
62
- def test_status_idle
63
- pom, has_output = invoke(:status, '@pom', 'has_output')
64
- assert_equal(:idle, pom.status_name)
65
- assert_equal(true, has_output)
101
+ def test_cancel_idle
102
+ assert_raises NotActiveError do
103
+ invoke(:cancel)
104
+ end
66
105
  assert_equal(0, @backend.size)
67
106
  end
68
107
 
69
- def test_status_active
108
+ def test_cancel_active
70
109
  invoke(:start)
71
- pom, has_output = invoke(:status, '@pom', 'has_output')
72
- assert_equal(:active, pom.status_name)
73
- assert_equal(true, has_output)
110
+ pom, has_output = invoke(:cancel, nil, '@pom', 'has_output')
111
+ assert_equal(:canceled, pom.status_name)
112
+ assert_equal(false, has_output)
74
113
  assert_equal(1, @backend.size)
75
114
  end
76
115
 
77
- def test_status_finished
116
+ def test_cancel_finished
78
117
  invoke(:start)
79
118
  invoke(:finish)
80
- pom, has_output = invoke(:status, '@pom', 'has_output')
81
- assert_equal(:finished, pom.status_name)
82
- assert_equal(true, has_output)
83
119
  assert_equal(1, @backend.size)
120
+
121
+ assert_raises NotActiveError do
122
+ invoke(:cancel)
123
+ end
124
+
125
+ assert_equal(1, @backend.size)
126
+ end
127
+
128
+ def test_cancel_again
129
+ invoke(:start)
130
+ invoke(:cancel)
131
+ assert_equal(1, @backend.size)
132
+ invoke(:start)
133
+ assert_equal(2, @backend.size)
84
134
  end
85
135
 
86
136
  private
87
137
 
88
- def invoke(method, *attributes)
138
+ def invoke(method, options = nil, *attributes)
89
139
  controller = PomodoriController.new(method)
90
140
 
91
141
  Repository.stub :backend, @backend do
92
142
  Scheduler.stub(:add, nil) do
93
143
  Scheduler.stub(:clear, nil) do
94
- controller.call(nil, nil)
144
+ controller.call(nil, options)
95
145
  end
96
146
  end
97
147
  end
98
148
 
99
- attributes.map do |attribute|
149
+ result = attributes.map do |attribute|
100
150
  controller.get_binding.eval(attribute)
101
151
  end
152
+
153
+ if 1 == result.size
154
+ result.first
155
+ else
156
+ result
157
+ end
102
158
  end
103
159
  end
@@ -6,56 +6,6 @@ class TestPomodoriView < MiniTest::Test
6
6
  @pom.id = 1
7
7
  end
8
8
 
9
- def test_status_idle
10
- out, err = render(:status)
11
- assert_match(/^Current state is idle.$/m, out)
12
- assert_empty(err)
13
- end
14
-
15
- def test_status_active
16
- start!
17
- out, err = render(:status)
18
- assert_match(/^Pomodoro #1 is active for another \d{1,2} minutes \(started at .*\)\.$/m, out)
19
- assert_empty(err)
20
- end
21
-
22
- def test_status_finished
23
- start!
24
- finish!
25
- out, err = render(:status)
26
- assert_match(/^No active pomodoro. Last one was finished at .*\.$/m, out)
27
- assert_empty(err)
28
- end
29
-
30
- def test_report_empty
31
- @pom = []
32
- out, err = render(:report)
33
- assert_equal(1, out.lines.size)
34
- assert_match(/^ID \| Status \| Started \| Ended$/m, out.lines.first)
35
- assert_empty(err)
36
- end
37
-
38
- def test_report_one_active
39
- start!
40
- @pom = [@pom]
41
- out, err = render(:report)
42
- assert_equal(2, out.lines.size)
43
- assert_match(/^ID \| Status \| Started \| Ended$/m, out.lines[0])
44
- assert_match(/^1 \| active \| \d{1,2}:\d{1,2} \| $/m, out.lines[1])
45
- assert_empty(err)
46
- end
47
-
48
- def test_report_one_finished
49
- start!
50
- finish!
51
- @pom = [@pom]
52
- out, err = render(:report)
53
- assert_equal(2, out.lines.size)
54
- assert_match(/^ID \| Status \| Started \| Ended$/m, out.lines[0])
55
- assert_match(/^1 \| finished \| \d{1,2}:\d{1,2} \| \d{1,2}:\d{1,2}$/m, out.lines[1])
56
- assert_empty(err)
57
- end
58
-
59
9
  def test_start
60
10
  out, err = render(:start)
61
11
  assert_match(/^Starting pomodoro #1\.$/m, out)
@@ -7,15 +7,21 @@ class TestPomodoro < MiniTest::Test
7
7
 
8
8
  def test_virgin
9
9
  assert_equal(:idle, @pom.status_name)
10
+ refute(@pom.started_at)
11
+ refute(@pom.canceled_at)
12
+ refute(@pom.finished_at)
10
13
  end
11
14
 
12
15
  def test_finish_idle
13
16
  assert_raises StateMachine::InvalidTransition do
14
17
  finish!
15
18
  end
19
+ refute(@pom.started_at)
20
+ refute(@pom.canceled_at)
21
+ refute(@pom.finished_at)
16
22
  end
17
23
 
18
- def test_finish
24
+ def test_finish_active
19
25
  start!
20
26
  assert_equal(:active, @pom.status_name)
21
27
 
@@ -27,6 +33,29 @@ class TestPomodoro < MiniTest::Test
27
33
 
28
34
  assert_equal(:finished, @pom.status_name)
29
35
  assert_equal(now, @pom.finished_at.to_i)
36
+ refute(@pom.canceled_at)
37
+ end
38
+
39
+ def test_finish_finished
40
+ start!
41
+ finish!
42
+ assert_raises StateMachine::InvalidTransition do
43
+ finish!
44
+ end
45
+ refute(@pom.canceled_at)
46
+ end
47
+
48
+ def test_finish_canceled
49
+ start!
50
+ cancel!
51
+ assert_raises StateMachine::InvalidTransition do
52
+ finish!
53
+ end
54
+ refute(@pom.finished_at)
55
+ end
56
+
57
+ def test_length
58
+ assert_equal(25 * 60, @pom.length)
30
59
  end
31
60
 
32
61
  def test_duration_idle
@@ -63,12 +92,20 @@ class TestPomodoro < MiniTest::Test
63
92
  assert_equal(later - now, @pom.duration)
64
93
  end
65
94
 
66
- def test_finish_finished
67
- start!
68
- finish!
69
- assert_raises StateMachine::InvalidTransition do
70
- finish!
95
+ def test_duration_canceled
96
+ now = srand
97
+
98
+ Time.stub :now, Time.at(now) do
99
+ start!
100
+ end
101
+
102
+ later = now + rand(42)
103
+
104
+ Time.stub :now, Time.at(later) do
105
+ cancel!
71
106
  end
107
+
108
+ assert_equal(later - now, @pom.duration)
72
109
  end
73
110
 
74
111
  def test_start
@@ -82,19 +119,104 @@ class TestPomodoro < MiniTest::Test
82
119
  assert_equal(now, @pom.started_at.to_i)
83
120
  end
84
121
 
85
- def test_remaining
122
+ def test_remaining_active
86
123
  now = srand
87
124
 
88
125
  Time.stub :now, Time.at(now) do
89
126
  start!
90
- assert_equal(Pomodoro::LENGTH_SECONDS, @pom.remaining)
127
+ assert_equal(Pomodoro::MINUTES_25 * 60, @pom.remaining)
91
128
  end
92
129
 
93
130
  delta = 600
94
131
  later = now + delta
95
132
 
96
133
  Time.stub :now, Time.at(later) do
97
- assert_equal(Pomodoro::LENGTH_SECONDS - delta, @pom.remaining)
134
+ assert_equal(Pomodoro::MINUTES_25 * 60 - delta, @pom.remaining)
135
+ end
136
+ end
137
+
138
+ def test_interrupt
139
+ start!
140
+ assert_equal(0, @pom.interrupts.size)
141
+
142
+ now = srand
143
+
144
+ Time.stub :now, Time.at(now) do
145
+ interrupt!
98
146
  end
147
+
148
+ assert_equal(1, @pom.interrupts.size)
149
+
150
+ int = @pom.interrupts.first
151
+ assert_equal(now, int.created_at.to_i)
152
+ assert_equal(:internal, int.type)
153
+ end
154
+
155
+ def test_interrupt_internal
156
+ start!
157
+ interrupt!(:internal)
158
+ assert_equal(1, @pom.interrupts.size)
159
+ int = @pom.interrupts.first
160
+ assert_equal(:internal, int.type)
161
+ end
162
+
163
+ def test_interrupt_external
164
+ start!
165
+ interrupt!(:external)
166
+ assert_equal(1, @pom.interrupts.size)
167
+ int = @pom.interrupts.first
168
+ assert_equal(:external, int.type)
169
+ end
170
+
171
+ def test_interrupt_unknown
172
+ start!
173
+ assert_raises InvalidTypeError do
174
+ interrupt!(:unknown)
175
+ end
176
+ end
177
+
178
+ def test_interrupt_idle
179
+ assert_raises StateMachine::InvalidTransition do
180
+ interrupt!
181
+ end
182
+ end
183
+
184
+ def test_interrupt_finished
185
+ start!
186
+ finish!
187
+ assert_raises StateMachine::InvalidTransition do
188
+ interrupt!
189
+ end
190
+ end
191
+
192
+ def test_interrupt_canceled
193
+ start!
194
+ cancel!
195
+ assert_raises StateMachine::InvalidTransition do
196
+ interrupt!
197
+ end
198
+ end
199
+
200
+ def test_cancel_idle
201
+ assert_raises StateMachine::InvalidTransition do
202
+ cancel!
203
+ end
204
+ refute(@pom.finished_at)
205
+ refute(@pom.canceled_at)
206
+ end
207
+
208
+ def test_cancel_active
209
+ start!
210
+ assert_equal(:active, @pom.status_name)
211
+
212
+ now = srand
213
+
214
+ Time.stub :now, Time.at(now) do
215
+ cancel!
216
+ end
217
+
218
+ assert_equal(:canceled, @pom.status_name)
219
+ assert_equal(now, @pom.canceled_at.to_i)
220
+ refute(@pom.finished_at)
99
221
  end
100
222
  end
@@ -3,36 +3,47 @@ require 'tmpdir'
3
3
 
4
4
  class TestPomodoroHooks < MiniTest::Test
5
5
  def setup
6
- @orig_pom_dir = ENV['POM_DIR']
7
- ENV['POM_DIR'] = Dir.mktmpdir
6
+ # Cannot use fakefs because hooks will not execute under it, but as part of
7
+ # the real FS. Instead, we set the $PAR_DIR to point to a temp directory
8
+ @orig_PAR_DIR = ENV['PAR_DIR']
9
+ ENV['PAR_DIR'] = Dir.mktmpdir
8
10
  end
9
11
 
10
12
  def teardown
11
- FileUtils.rm_rf(Paradeiser.pom_dir)
12
- ENV['POM_DIR'] = @orig_pom_dir
13
+ FileUtils.rm_rf(Paradeiser.par_dir)
14
+ ENV['PAR_DIR'] = @orig_PAR_DIR
13
15
  end
14
16
 
15
- def test_before_finish_success
16
- hook_name = 'before-finish'
17
+ def test_before_start_pomodoro_success
18
+ hook_name = 'before-start-pomodoro'
19
+ pom = Pomodoro.new
20
+ token_file = create_hook('Pomodoro', hook_name)
21
+ refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
22
+ pom.start
23
+ assert_path_exists(token_file, "#{hook_name} hook should have created a token file")
24
+ assert_equal(:active, pom.status_name)
25
+ assert_equal("Pomodoro #{Repository.next_id} #{pom.started_at.strftime('%H:%M')}", File.read(token_file).chomp)
26
+ end
17
27
 
28
+ def test_before_finish_pomodoro_success
29
+ hook_name = 'before-finish-pomodoro'
18
30
  pom = Pomodoro.new
19
31
  pom.id = SecureRandom.random_number(1000)
20
32
  pom.start
21
- token_file = create_hook(hook_name)
33
+ token_file = create_hook('Pomodoro', hook_name)
22
34
  refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
23
35
  pom.finish
24
36
  assert_path_exists(token_file, "#{hook_name} hook should have created a token file")
25
37
  assert_equal(:finished, pom.status_name)
26
- assert_equal("Pomodoro #{pom.id} started #{pom.started_at.strftime('%H:%M')}", File.read(token_file).chomp)
38
+ assert_equal("Pomodoro #{pom.id} #{pom.started_at.strftime('%H:%M')}", File.read(token_file).chomp)
27
39
  end
28
40
 
29
- def test_before_finish_error
30
- hook_name = 'before-finish'
31
-
41
+ def test_before_finish_pomodoro_error
42
+ hook_name = 'before-finish-pomodoro'
32
43
  pom = Pomodoro.new
33
44
  pom.id = SecureRandom.random_number(1000)
34
45
  pom.start
35
- token_file = create_hook(hook_name, false)
46
+ token_file = create_hook('Pomodoro', hook_name, false)
36
47
  refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
37
48
 
38
49
  assert_raises HookFailedError do
@@ -43,19 +54,156 @@ class TestPomodoroHooks < MiniTest::Test
43
54
  assert_equal(:active, pom.status_name)
44
55
  end
45
56
 
57
+ def test_before_finish_break_success
58
+ hook_name = 'before-finish-break'
59
+ br3ak = Break.new
60
+ br3ak.id = SecureRandom.random_number(1000)
61
+ br3ak.start
62
+ token_file = create_hook('Break', hook_name)
63
+ refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
64
+ br3ak.finish
65
+ assert_path_exists(token_file, "#{hook_name} hook should have created a token file")
66
+ assert_equal(:finished, br3ak.status_name)
67
+ assert_equal("Break #{br3ak.id} #{br3ak.started_at.strftime('%H:%M')}", File.read(token_file).chomp)
68
+ end
69
+
70
+ def test_before_finish_break_error
71
+ hook_name = 'before-finish-break'
72
+ br3ak = Break.new
73
+ br3ak.id = SecureRandom.random_number(1000)
74
+ br3ak.start
75
+ token_file = create_hook('Break', hook_name, false)
76
+ refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
77
+
78
+ assert_raises HookFailedError do
79
+ br3ak.finish
80
+ end
81
+
82
+ refute_path_exists(token_file, "#{hook_name} hook should have created a token file")
83
+ assert_equal(:active, br3ak.status_name)
84
+ end
85
+
86
+ def test_before_interrupt_success
87
+ hook_name = 'before-interrupt-pomodoro'
88
+ pom = Pomodoro.new
89
+ pom.start
90
+ token_file = create_hook('Pomodoro', hook_name)
91
+ refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
92
+ pom.interrupt
93
+ assert_path_exists(token_file, "#{hook_name} hook should have created a token file")
94
+ assert_equal(:active, pom.status_name)
95
+ assert_equal("Pomodoro #{Repository.next_id} #{pom.started_at.strftime('%H:%M')}", File.read(token_file).chomp)
96
+ end
97
+
98
+ def test_before_interrupt_error
99
+ hook_name = 'before-interrupt-pomodoro'
100
+ pom = Pomodoro.new
101
+ pom.start
102
+ token_file = create_hook('Pomodoro', hook_name, false)
103
+ refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
104
+
105
+ assert_raises HookFailedError do
106
+ pom.interrupt
107
+ end
108
+
109
+ refute_path_exists(token_file, "#{hook_name} hook should have created a token file")
110
+ assert_equal(:active, pom.status_name)
111
+ end
112
+
113
+ def test_after_interrupt_success
114
+ hook_name = 'after-interrupt-pomodoro'
115
+ pom = Pomodoro.new
116
+ pom.start
117
+ token_file = create_hook('Pomodoro', hook_name, false)
118
+ refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
119
+
120
+ assert_raises HookFailedError do
121
+ pom.interrupt
122
+ end
123
+
124
+ refute_path_exists(token_file, "#{hook_name} hook should have created a token file")
125
+ assert_equal(:active, pom.status_name)
126
+ end
127
+
128
+ def test_after_interrupt_error
129
+ hook_name = 'after-interrupt-pomodoro'
130
+ pom = Pomodoro.new
131
+ pom.start
132
+ token_file = create_hook('Pomodoro', hook_name)
133
+ refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
134
+ pom.interrupt
135
+ assert_path_exists(token_file, "#{hook_name} hook should have created a token file")
136
+ assert_equal(:active, pom.status_name)
137
+ assert_equal("Pomodoro #{Repository.next_id} #{pom.started_at.strftime('%H:%M')}", File.read(token_file).chomp)
138
+ end
139
+
140
+ def test_before_cancel_success
141
+ hook_name = 'before-cancel-pomodoro'
142
+ pom = Pomodoro.new
143
+ pom.start
144
+ token_file = create_hook('Pomodoro', hook_name)
145
+ refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
146
+ pom.cancel
147
+ assert_path_exists(token_file, "#{hook_name} hook should have created a token file")
148
+ assert_equal(:canceled, pom.status_name)
149
+ assert_equal("Pomodoro #{Repository.next_id} #{pom.started_at.strftime('%H:%M')}", File.read(token_file).chomp)
150
+ end
151
+
152
+ def test_before_cancel_error
153
+ hook_name = 'before-cancel-pomodoro'
154
+ pom = Pomodoro.new
155
+ pom.start
156
+ token_file = create_hook('Pomodoro', hook_name, false)
157
+ refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
158
+
159
+ assert_raises HookFailedError do
160
+ pom.cancel
161
+ end
162
+
163
+ refute_path_exists(token_file, "#{hook_name} hook should have created a token file")
164
+ assert_equal(:active, pom.status_name)
165
+ end
166
+
167
+ def test_after_cancel_success
168
+ hook_name = 'after-cancel-pomodoro'
169
+ pom = Pomodoro.new
170
+ pom.start
171
+ token_file = create_hook('Pomodoro', hook_name, false)
172
+ refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
173
+
174
+ assert_raises HookFailedError do
175
+ pom.cancel
176
+ end
177
+
178
+ refute_path_exists(token_file, "#{hook_name} hook should have created a token file")
179
+ assert_equal(:canceled, pom.status_name)
180
+ end
181
+
182
+ def test_after_cancel_error
183
+ hook_name = 'after-cancel-pomodoro'
184
+ pom = Pomodoro.new
185
+ pom.start
186
+ token_file = create_hook('Pomodoro', hook_name)
187
+ refute_path_exists(token_file, "Token file must not exist before #{hook_name} hook is executed")
188
+ pom.cancel
189
+ assert_path_exists(token_file, "#{hook_name} hook should have created a token file")
190
+ assert_equal(:canceled, pom.status_name)
191
+ assert_equal("Pomodoro #{Repository.next_id} #{pom.started_at.strftime('%H:%M')}", File.read(token_file).chomp)
192
+ end
193
+
46
194
  private
47
195
 
48
- def create_hook(name, hook_succeeds = true)
196
+ def create_hook(thing, hook_name, hook_succeeds = true)
49
197
  token_file = File.join(Dir.tmpdir, SecureRandom.uuid)
50
198
 
51
199
  hooks_dir = Paradeiser.hooks_dir
52
200
  FileUtils.mkdir(hooks_dir)
53
201
 
54
- hook_file = File.join(hooks_dir, name)
202
+ hook_file = File.join(hooks_dir, hook_name)
55
203
 
56
204
  File.open(hook_file, 'w') do |f|
57
205
  if hook_succeeds
58
- f.write(hook_contents_success(token_file))
206
+ f.write(hook_contents_success(thing, token_file))
59
207
  else
60
208
  f.write(hook_contents_failure)
61
209
  end
@@ -67,10 +215,10 @@ private
67
215
  token_file
68
216
  end
69
217
 
70
- def hook_contents_success(token_file)
218
+ def hook_contents_success(thing, token_file)
71
219
  hook_contents =<<"EOF"
72
220
  #!/bin/sh
73
- echo "Pomodoro $POM_ID started $POM_STARTED_AT" > #{token_file}
221
+ echo "#{thing} $PAR_#{thing.upcase}_ID $PAR_#{thing.upcase}_STARTED_AT" > #{token_file}
74
222
  EOF
75
223
  end
76
224