tempo-cli 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +56 -0
  4. data/README.md +326 -0
  5. data/Rakefile +65 -0
  6. data/bin/tempo +477 -0
  7. data/features/arrange.feature +43 -0
  8. data/features/checkout.feature +63 -0
  9. data/features/end.feature +65 -0
  10. data/features/project.feature +246 -0
  11. data/features/report.feature +62 -0
  12. data/features/start.feature +87 -0
  13. data/features/step_definitions/tempo_steps.rb +138 -0
  14. data/features/support/env.rb +26 -0
  15. data/features/tempo.feature +13 -0
  16. data/features/update.feature +69 -0
  17. data/lib/file_record/directory.rb +11 -0
  18. data/lib/file_record/directory_structure/tempo/README.txt +4 -0
  19. data/lib/file_record/directory_structure/tempo/tempo_projects.yaml +6 -0
  20. data/lib/file_record/record.rb +120 -0
  21. data/lib/tempo/controllers/arrange_controller.rb +52 -0
  22. data/lib/tempo/controllers/base.rb +117 -0
  23. data/lib/tempo/controllers/checkout_controller.rb +42 -0
  24. data/lib/tempo/controllers/end_controller.rb +42 -0
  25. data/lib/tempo/controllers/projects_controller.rb +107 -0
  26. data/lib/tempo/controllers/records_controller.rb +21 -0
  27. data/lib/tempo/controllers/report_controller.rb +55 -0
  28. data/lib/tempo/controllers/start_controller.rb +42 -0
  29. data/lib/tempo/controllers/update_controller.rb +78 -0
  30. data/lib/tempo/models/base.rb +176 -0
  31. data/lib/tempo/models/composite.rb +71 -0
  32. data/lib/tempo/models/log.rb +194 -0
  33. data/lib/tempo/models/project.rb +73 -0
  34. data/lib/tempo/models/time_record.rb +235 -0
  35. data/lib/tempo/version.rb +3 -0
  36. data/lib/tempo/views/arrange_view.rb +27 -0
  37. data/lib/tempo/views/base.rb +82 -0
  38. data/lib/tempo/views/formatters/base.rb +30 -0
  39. data/lib/tempo/views/formatters/screen.rb +86 -0
  40. data/lib/tempo/views/projects_view.rb +82 -0
  41. data/lib/tempo/views/report_view.rb +26 -0
  42. data/lib/tempo/views/reporter.rb +70 -0
  43. data/lib/tempo/views/time_record_view.rb +30 -0
  44. data/lib/tempo/views/view_records/base.rb +117 -0
  45. data/lib/tempo/views/view_records/composite.rb +40 -0
  46. data/lib/tempo/views/view_records/log.rb +28 -0
  47. data/lib/tempo/views/view_records/project.rb +32 -0
  48. data/lib/tempo/views/view_records/time_record.rb +48 -0
  49. data/lib/tempo.rb +26 -0
  50. data/lib/time_utilities.rb +30 -0
  51. data/tempo-cli.gemspec +26 -0
  52. data/test/lib/file_record/directory_test.rb +30 -0
  53. data/test/lib/file_record/record_test.rb +106 -0
  54. data/test/lib/tempo/controllers/base_controller_test.rb +60 -0
  55. data/test/lib/tempo/controllers/project_controller_test.rb +24 -0
  56. data/test/lib/tempo/models/base_test.rb +173 -0
  57. data/test/lib/tempo/models/composite_test.rb +76 -0
  58. data/test/lib/tempo/models/log_test.rb +171 -0
  59. data/test/lib/tempo/models/project_test.rb +105 -0
  60. data/test/lib/tempo/models/time_record_test.rb +212 -0
  61. data/test/lib/tempo/views/base_test.rb +31 -0
  62. data/test/lib/tempo/views/formatters/base_test.rb +13 -0
  63. data/test/lib/tempo/views/formatters/screen_test.rb +94 -0
  64. data/test/lib/tempo/views/reporter_test.rb +40 -0
  65. data/test/lib/tempo/views/view_records/base_test.rb +77 -0
  66. data/test/lib/tempo/views/view_records/composite_test.rb +57 -0
  67. data/test/lib/tempo/views/view_records/log_test.rb +28 -0
  68. data/test/lib/tempo/views/view_records/project_test.rb +0 -0
  69. data/test/lib/tempo/views/view_records/time_record_test.rb +0 -0
  70. data/test/support/factories.rb +177 -0
  71. data/test/support/helpers.rb +69 -0
  72. data/test/test_helper.rb +31 -0
  73. metadata +230 -0
@@ -0,0 +1,246 @@
1
+ Feature: Project Command manages a list of projects
2
+ The project command allows time to be tracked by project
3
+ New projects can be added and deleted
4
+ Projects can also be tagged as inactive or inactive
5
+
6
+ Scenario: Listing projects before any projects exist
7
+ Given a clean installation
8
+ When I run `tempo project`
9
+ Then the stdout should contain "no projects exist"
10
+ And the project file should contain "#" at line 1
11
+
12
+ Scenario: Listing projects before any projects exist
13
+ Given a clean installation
14
+ When I run `tempo project --list`
15
+ Then the stdout should contain "no projects exist"
16
+
17
+ Scenario: Adding the first project creates a file with a current project
18
+ Given a clean installation
19
+ When I successfully run `tempo project horticulture`
20
+ Then the project file should contain ":title: horticulture" at line 5
21
+ And the project file should contain "current" at line 7
22
+
23
+ Scenario: Listing the active project by default
24
+ Given an existing project file
25
+ When I successfully run `tempo project`
26
+ Then the stdout should contain "* horticulture"
27
+
28
+ Scenario: Listing all Projects alphabetically with --list
29
+ Given an existing project file
30
+ When I successfully run `tempo project --list`
31
+ Then the stdout should contain " aquaculture"
32
+ And the stdout should contain " nano aquarium"
33
+ And the stdout should contain " reading aquaculture digest"
34
+ And the stdout should contain "* horticulture"
35
+ And the stdout should contain " backyard bonsai"
36
+ And the stdout should contain " basement mushrooms"
37
+
38
+ Scenario: Listing all Projects with --l
39
+ Given an existing project file
40
+ When I successfully run `tempo project -l`
41
+ Then the stdout should contain " aquaculture"
42
+ And the stdout should contain " nano aquarium"
43
+ And the stdout should contain " reading aquaculture digest"
44
+ And the stdout should contain "* horticulture"
45
+ And the stdout should contain " backyard bonsai"
46
+ And the stdout should contain " basement mushrooms"
47
+
48
+ Scenario: Listing all Projects with --verbose
49
+ Given an existing project file
50
+ When I successfully run `tempo -v project -l`
51
+ Then the stdout should contain " [4] aquaculture tags: [cultivation]"
52
+ And the stdout should contain " [5] nano aquarium tags: [miniaturization]"
53
+ And the stdout should contain " [6] reading aquaculture digest tags: none"
54
+ And the stdout should contain " [1] * horticulture tags: [cultivation]"
55
+ And the stdout should contain " [2] backyard bonsai tags: [miniaturization, outdoors]"
56
+ And the stdout should contain " [3] basement mushrooms tags: [fungi, indoors]"
57
+
58
+ Scenario: Listing all Projects with Ids displayed
59
+ Given an existing project file
60
+ When I successfully run `tempo project -li`
61
+ Then the stdout should contain "[4] aquaculture"
62
+ And the stdout should contain "[5] nano aquarium"
63
+ And the stdout should contain "[6] reading aquaculture digest"
64
+ And the stdout should contain "[1] * horticulture"
65
+ And the stdout should contain "[2] backyard bonsai"
66
+ And the stdout should contain "[3] basement mushrooms"
67
+
68
+ Scenario: Listing Projects by matching against arguments
69
+ Given an existing project file
70
+ When I successfully run `tempo project -l culture`
71
+ Then the stdout should contain " aquaculture"
72
+ And the stdout should contain " reading aquaculture digest"
73
+ And the stdout should contain "* horticulture"
74
+ And the stdout should not contain " backyard bonsai"
75
+
76
+ Scenario: Listing Projects by matching against regex
77
+ Given an existing project file
78
+ When I successfully run `tempo project -l ^aquaculture$`
79
+ Then the stdout should not contain " reading aquaculture digest"
80
+ And the stdout should contain " aquaculture"
81
+
82
+ Scenario: Matching Projects with an exact match
83
+ Given an existing project file
84
+ And I successfully run `tempo project -le aquaculture`
85
+ Then the stdout should not contain " reading aquaculture digest"
86
+ And the stdout should contain " aquaculture"
87
+
88
+ Scenario: Listing no Project when matching against arguments returns nothing
89
+ Given an existing project file
90
+ When I run `tempo project -l "beekeeping"`
91
+ Then the stderr should contain "no projects match the request: beekeeping"
92
+
93
+ Scenario: Adding a project
94
+ Given an existing project file
95
+ When I successfully run `tempo project "hang gliding"`
96
+ Then the stdout should contain "added project:\nhang gliding"
97
+ And the project file should contain ":title: hang gliding"
98
+
99
+ Scenario: Adding a project without quotation marks
100
+ Given an existing project file
101
+ When I successfully run `tempo project hang gliding`
102
+ Then the stdout should contain "added project:\nhang gliding\n"
103
+ And the project file should contain ":title: hang gliding"
104
+
105
+ Scenario: Attempting to add an existing project
106
+ Given an existing project file
107
+ When I run `tempo project "basement mushrooms"`
108
+ Then the stderr should contain "error: project 'basement mushrooms' already exists"
109
+
110
+ Scenario: Deleting a project by full match
111
+ Given an existing project file
112
+ When I successfully run `tempo project -d "backyard bonsai"`
113
+ Then the stdout should contain "deleted project:\nbackyard bonsai"
114
+ And the project file should not contain ":title: backyard bonsai"
115
+
116
+ Scenario: Deleting a project by partial match
117
+ Given an existing project file
118
+ When I successfully run `tempo project -d "bonsai"`
119
+ Then the stdout should contain "deleted project:\nbackyard bonsai"
120
+ And the project file should not contain ":title: backyard bonsai"
121
+
122
+ Scenario: Deleting a project without quotation marks
123
+ Given an existing project file
124
+ When I successfully run `tempo project -d backyard bonsai`
125
+ Then the stdout should contain "deleted project:\nbackyard bonsai"
126
+ And the project file should not contain ":title: backyard bonsai"
127
+
128
+ Scenario: Deleting a project with list flag works even without quotes around a partial match
129
+ Given an existing project file
130
+ When I successfully run `tempo project -d backyard bonsai -l`
131
+ Then the stdout should contain " aquaculture"
132
+ And the stdout should contain " nano aquarium"
133
+ And the stdout should contain " reading aquaculture digest"
134
+ And the stdout should contain "* horticulture"
135
+ And the stdout should not contain " backyard bonsai"
136
+ And the stdout should contain " basement mushrooms"
137
+
138
+ Scenario: Deleting a project with combined '-ld' list flag also works
139
+ Given an existing project file
140
+ When I successfully run `tempo project -ld backyard bonsai`
141
+ Then the stdout should contain " aquaculture"
142
+ And the stdout should contain " nano aquarium"
143
+ And the stdout should contain " reading aquaculture digest"
144
+ And the stdout should contain "* horticulture"
145
+ And the stdout should not contain " backyard bonsai"
146
+ And the stdout should contain " basement mushrooms"
147
+ Scenario: Deleting a project by Id
148
+ Given an existing project file
149
+ When I successfully run `tempo project -id 3`
150
+ Then the stdout should contain "deleted project:\n [3] basement mushrooms"
151
+ And the project file should not contain ":title: basement mushrooms"
152
+
153
+ Scenario: Attempting to delete a non-existing project Fails
154
+ Given an existing project file
155
+ When I run `tempo project -d "sheep hearding - lanolin extraction"`
156
+ Then the stderr should contain "error: no projects match the request: sheep hearding - lanolin extraction"
157
+
158
+ Scenario: Attempting to Delete the current project Fails
159
+ Given an existing project file
160
+ When I run `tempo project -d "horticulture"`
161
+ Then the stdout should not contain "deleted project"
162
+ And the stderr should contain "error: cannot delete the active project"
163
+
164
+ Scenario: Attempting to Delete with ambiguous match Fails
165
+ Given an existing project file
166
+ When I run `tempo project -d aquaculture`
167
+ Then the stdout should not contain "deleted project"
168
+ And the output should match /^ reading aquaculture digest$/
169
+ And the output should match /^ aquaculture$/
170
+ And the stderr should contain "error: cannot delete multiple projects"
171
+
172
+ Scenario: Tagging a project with a tag
173
+ Given an existing project file
174
+ When I successfully run `tempo project backyard bonsai -t patience`
175
+ Then the stdout should contain "backyard bonsai"
176
+ And the stdout should contain "tags: [miniaturization, outdoors, patience]"
177
+ And the project file should contain "- patience"
178
+
179
+ Scenario: Tagging a project by Id with a tag
180
+ Given an existing project file
181
+ When I successfully run `tempo project -i 3 -t patience`
182
+ Then the stdout should contain "basement mushrooms"
183
+ And the stdout should contain "tags: [fungi, indoors, patience]"
184
+ And the project file should contain "- patience"
185
+
186
+ Scenario: Tagging a project with tags
187
+ Given an existing project file
188
+ When I successfully run `tempo project backyard bonsai -t 'patience japanese'`
189
+ Then the stdout should contain "backyard bonsai"
190
+ And the stdout should contain "tags: [japanese, miniaturization, outdoors, patience]"
191
+ And the project file should contain "- patience"
192
+ And the project file should contain "- japanese"
193
+
194
+ Scenario: Attempting to tag a project with a duplicate tag
195
+ Given an existing project file
196
+ When I successfully run `tempo project backyard bonsai -t outdoors`
197
+ Then the stdout should contain "backyard bonsai"
198
+ And the stdout should contain "tags: [miniaturization, outdoors]"
199
+
200
+ Scenario: Attemting to tag a project by non-existing id
201
+ Given an existing project file
202
+ When I run `tempo project -i 30 -t patience`
203
+ Then the stderr should contain "no projects match the request: id=30"
204
+
205
+ Scenario: Untagging a project with a tag
206
+ Given an existing project file
207
+ When I successfully run `tempo project mushrooms -u fungi`
208
+ Then the stdout should contain "basement mushrooms"
209
+ And the stdout should contain "tags: [indoors]"
210
+ And the project file should not contain "- fungi"
211
+
212
+ Scenario: Untagging a project by Id
213
+ Given an existing project file
214
+ When I successfully run `tempo project -i 3 -u fungi`
215
+ Then the stdout should contain "basement mushrooms"
216
+ And the stdout should contain "tags: [indoors]"
217
+ And the project file should not contain "- fungi"
218
+
219
+ Scenario: Untagging a project with tags
220
+ Given an existing project file
221
+ When I successfully run `tempo project mushrooms -u 'indoors fungi'`
222
+ Then the stdout should contain "basement mushrooms"
223
+ And the stdout should contain "tags: none"
224
+ And the project file should not contain "- fungi"
225
+
226
+ Scenario: Tagging and Untagging a project
227
+ Given an existing project file
228
+ When I successfully run `tempo project backyard bonsai -u miniaturization -t shrubs`
229
+ Then the stdout should contain "backyard bonsai"
230
+ And the stdout should contain "tags: [outdoors, shrubs]"
231
+ And the project file should contain "- shrubs"
232
+
233
+ Scenario: Adding a new project with tags
234
+ Given an existing project file
235
+ When I successfully run `tempo project -a fly fishing -t 'patience fish'`
236
+ Then the stdout should contain "added project:"
237
+ And the stdout should contain "fly fishing tags: [fish, patience]"
238
+ And the project file should contain "- patience"
239
+ And the project file should contain "- fish"
240
+
241
+ Scenario: Attempting to tag a project with ambiguous match
242
+ Given an existing project file
243
+ When I run `tempo project 'aquaculture' -t japanese`
244
+ Then the stdout should not contain "japanese"
245
+ And the stderr should contain "error: cannot tag multiple projects"
246
+ And the project file should not contain "- japanese"
@@ -0,0 +1,62 @@
1
+ Feature: Report Command formats and outputs time records
2
+ The report command echoes time records in an easy to view format.
3
+
4
+ Scenario: Attempting to report time records before any projects exist
5
+ Given a clean installation
6
+ When I run `tempo report`
7
+ Then the stderr should contain "no projects exist"
8
+ And the project file should contain "#" at line 1
9
+
10
+ Scenario: Attempting to report time records before any time records exist
11
+ Given an existing project file
12
+ When I run `tempo report`
13
+ Then the stderr should contain "no time records exist"
14
+
15
+ Scenario: Reporting the time entries on the current day
16
+ Given an existing project file
17
+ When I run `tempo start -a 7 my new project`
18
+ And I run `tempo end -a 8`
19
+ And I run `tempo report`
20
+ Then the output should match /\d{2}:\d{2} - \d{2}:\d{2} \[\d{1,2}:\d{2}\] horticulture: my new project/
21
+
22
+ Scenario: Reporting the time entries on a specific day
23
+ Given an existing project file
24
+ And an existing time record file
25
+ When I run `tempo start --at "2014-01-02" this will add a new record file`
26
+ And I run `tempo report "2014-01-01"`
27
+ Then the output should contain "Records for 01/01/2014:"
28
+ And the output should not contain "Records for 01/02/2014:"
29
+ And the output should contain "horticulture: putting on overalls and straw hat"
30
+
31
+ Scenario: Reporting the time entries for multipe days
32
+ Given an existing project file
33
+ And an existing time record file
34
+ When I run `tempo start --at "2014-01-02" this will add a newer record file`
35
+ When I run `tempo start --at "2014-01-03" and an even newer record file`
36
+ And I run `tempo report --from "2014-01-01" --to "2014-01-03"`
37
+ Then the output should contain "Records for 01/01/2014:"
38
+ And the output should contain "Records for 01/02/2014:"
39
+ And the output should contain "Records for 01/03/2014:"
40
+
41
+ @pending
42
+ Scenario: Reporting the time entries for multipe days using d_ids
43
+ Given an existing project file
44
+ And an existing time record file
45
+ When I run `tempo start --at "2014-01-02" this will add a newer record file`
46
+ When I run `tempo start --at "2014-01-03" and an even newer record file`
47
+ And I run `tempo report --from "20140101" --to "20140103"`
48
+ Then the output should contain "Records for 01/01/2014:"
49
+ And the output should contain "Records for 01/2/2014:"
50
+ And the output should contain "Records for 01/03/2014:"
51
+
52
+ Scenario: Reporting the time entries with ids
53
+ Given an existing project file
54
+ And an existing time record file
55
+ And I run `tempo -i report "2014-01-01"`
56
+ And the output should contain "[1] 05:00 - 05:15 [0:15] horticulture: putting on overalls and straw hat"
57
+ And the output should contain "[2] 05:15 - 08:15 [3:00] backyard bonsai: trimming the trees"
58
+ And the output should contain "[3] 08:15 - 10:38 [2:23] backyard bonsai: mixing up a batch of potting soil"
59
+ And the output should contain "[4] 12:52 - 13:26 [0:34] aquaculture: putting on the wetsuit"
60
+ And the output should contain "[5] 13:32 - 16:46 [3:14] nano aquarium: trimming the coral"
61
+
62
+
@@ -0,0 +1,87 @@
1
+ Feature: Start Command starts a new time record
2
+ The start command starts a time record referencing the current project
3
+ It records projects in log files by day. Only one time entry will be
4
+ running at any given time; new entries close out the last running time record.
5
+
6
+ Scenario: Attempting to add time before any projects exist
7
+ Given a clean installation
8
+ When I run `tempo start`
9
+ Then the stderr should contain "no projects exist"
10
+ And the project file should contain "#" at line 1
11
+
12
+ Scenario: Adding a time record for the current time
13
+ Given an existing project file
14
+ When I run `tempo start`
15
+ Then the stdout should contain "time record started"
16
+
17
+ Scenario: Adding a time record for the current time with a description
18
+ Given an existing project file
19
+ When I run `tempo start my new project`
20
+ Then the stdout should contain "time record started"
21
+ And the stdout should contain "horticulture: my new project"
22
+
23
+ Scenario: Attempting to add an invalid start time
24
+ Given an existing project file
25
+ When I run `tempo start --at "invalid time"`
26
+ Then the stderr should contain "no valid timeframe matches the request: invalid time"
27
+
28
+ Scenario: Adding a time record for a specific time
29
+ Given an existing project file
30
+ When I run `tempo start --at "15:00 today"`
31
+ Then the stdout should contain "time record started"
32
+ And the output should match /15:00 - \d{2}:\d{2}\*/
33
+
34
+ Scenario: Adding a time record with an end time
35
+ Given an existing project file
36
+ When I run `tempo start --end "1 hour from now"`
37
+ Then the stdout should contain "time record started"
38
+ And the output should match /\d{2}:\d{2} - \d{2}:\d{2}/
39
+ @pending
40
+ Scenario: Adding a time record with tags
41
+ Given an existing project file
42
+
43
+ Scenario: Attempting to add time that collides with an existing record
44
+ Given an existing project file
45
+ When I run `tempo start --at "1-1-2014 7:00"`
46
+ And I run `tempo end --at "1-1-2014 10:00"`
47
+ And I run `tempo start --at "1-1-2014 8:00"`
48
+ Then the stderr should contain "error: Time conflict with existing record"
49
+
50
+ Scenario: Adding a time record and closing out the last one
51
+ Given an existing project file
52
+ When I run `tempo start --at "1-1-2014 7:00"`
53
+ And I run `tempo start --at "1-1-2014 8:00"`
54
+ Then the stdout should contain "time record started"
55
+ And the time record 20140101 should contain ":end_time: 2014-01-01 08:00:00" at line 5
56
+
57
+ Scenario: Adding a time record and closing out the previous day
58
+ Given an existing project file
59
+ When I run `tempo start --at "1-1-2014 7:00"`
60
+ And I run `tempo start --at "1-3-2014 10:00"`
61
+ Then the stdout should contain "time record started"
62
+ And the time record 20140101 should contain ":end_time: 2014-01-01 23:59" at line 5
63
+ @pending
64
+ Scenario: Adding an evening time record should compensate for local time
65
+ # need to mock entering time in the evening, 21:26:46 -0400
66
+ # make sure --at "5:00" is recorded for the local day, not GMC
67
+
68
+ # Adding a time record at the beginning of the day seems to close out at the last time record
69
+ # check on and fix this bug.
70
+ @pending
71
+ Scenario: Adding an earlier time record should immediately close out
72
+ Given an existing project file
73
+ When I run `tempo start --at "1-1-2014 9:00"`
74
+ And I run `tempo start --at "1-1-2014 17:00"`
75
+ And I run `tempo start --at "1-1-2014 6:00"`
76
+ Then the stdout should contain "time record started"
77
+ And the time record 20140101 should contain ":end_time: 2014-01-01 9:00" at line 5
78
+
79
+ Scenario: Adding an earlier day time record should immediately close out
80
+ Given an existing project file
81
+ When I run `tempo start --at "1-5-2014 7:00"`
82
+ And I run `tempo start --at "1-1-2014 7:00"`
83
+ Then the stdout should contain "time record started"
84
+ And the time record 20140101 should contain ":end_time: 2014-01-01 23:59" at line 5
85
+
86
+
87
+
@@ -0,0 +1,138 @@
1
+ When /^I get help for "([^""]*)"$/ do |app_name|
2
+ @app_name = app_name
3
+ step %(I run `#{app_name} help`)
4
+ end
5
+
6
+ Given /^a clean installation$/ do
7
+ @testing_env = File.join( ENV['HOME'], 'tempo' )
8
+ FileUtils.rm_r( @testing_env ) if File.exists?( @testing_env )
9
+ end
10
+
11
+ Given /^an existing project file$/ do
12
+ @testing_env = File.join( ENV['HOME'], 'tempo' )
13
+ FileUtils.rm_r( @testing_env ) if File.exists?( @testing_env )
14
+ Dir.mkdir( @testing_env, 0700 )
15
+ projects_file = File.join( @testing_env, 'tempo_projects.yaml' )
16
+
17
+ File.open( projects_file,'w' ) do |f|
18
+ projects = ["---", ":id: 1", ":parent: :root", ":children:", "- 2", "- 3", ":title: horticulture", ":tags:", "- cultivation", ":current: true",
19
+ "---", ":id: 2", ":parent: 1", ":children: []", ":title: backyard bonsai", ":tags:", "- miniaturization", "- outdoors",
20
+ "---", ":id: 3", ":parent: 1", ":children: []", ":title: basement mushrooms", ":tags:", "- fungi", "- indoors",
21
+ "---", ":id: 4", ":parent: :root", ":children:", "- 5", "- 6", ":title: aquaculture", ":tags:", "- cultivation",
22
+ "---", ":id: 5", ":parent: 4", ":children: []", ":title: nano aquarium", ":tags:", "- miniaturization",
23
+ "---", ":id: 6", ":parent: 4", ":children: []", ":title: reading aquaculture digest", ":tags: []"]
24
+
25
+ projects.each do |p|
26
+ f.puts p
27
+ end
28
+ end
29
+ end
30
+
31
+ Given /^an existing time record file$/ do
32
+ @records_directory = File.join( ENV['HOME'], 'tempo/tempo_time_records' )
33
+ FileUtils.rm_r( @records_directory ) if File.exists?( @records_directory )
34
+ Dir.mkdir( @records_directory, 0700 )
35
+ projects_file = File.join( @records_directory, '20140101.yaml' )
36
+
37
+ File.open( projects_file,'w' ) do |f|
38
+ records = [ ":description: putting on overalls and straw hat",
39
+ ":start_time: 2014-01-01 05:00:00.000000000 -05:00",
40
+ ":end_time: 2014-01-01 05:15:00.000000000 -05:00",
41
+ ":id: 1",
42
+ ":project: 1",
43
+ ":tags: []",
44
+ "---",
45
+ ":project_title: backyard bonsai",
46
+ ":description: trimming the trees",
47
+ ":start_time: 2014-01-01 05:15:00.000000000 -05:00",
48
+ ":end_time: 2014-01-01 08:15:00.000000000 -05:00",
49
+ ":id: 2",
50
+ ":project: 2",
51
+ ":tags: []",
52
+ "---",
53
+ ":project_title: backyard bonsai",
54
+ ":description: mixing up a batch of potting soil",
55
+ ":start_time: 2014-01-01 08:15:00.000000000 -05:00",
56
+ ":end_time: 2014-01-01 10:38:00.000000000 -05:00",
57
+ ":id: 3",
58
+ ":project: 2",
59
+ ":tags: []",
60
+ "---",
61
+ ":project_title: aquaculture",
62
+ ":description: putting on the wetsuit",
63
+ ":start_time: 2014-01-01 12:52:00.000000000 -05:00",
64
+ ":end_time: 2014-01-01 13:26:00.000000000 -05:00",
65
+ ":id: 4",
66
+ ":project: 4",
67
+ ":tags: []",
68
+ "---",
69
+ ":project_title: nano aquarium",
70
+ ":description: trimming the coral",
71
+ ":start_time: 2014-01-01 13:32:00.000000000 -05:00",
72
+ ":end_time: 2014-01-01 16:46:00.000000000 -05:00",
73
+ ":id: 5",
74
+ ":project: 5",
75
+ ":tags: []" ]
76
+ records.each do |p|
77
+ f.puts p
78
+ end
79
+ end
80
+ end
81
+
82
+
83
+
84
+
85
+ Then /^the time record (.*?) should contain "(.*?)" at line (\d+)$/ do |arg1, arg2, arg3|
86
+ file = File.join( ENV['HOME'], 'tempo/tempo_time_records', "#{arg1}.yaml")
87
+ contents = []
88
+ File.open(file, "r") do |f|
89
+ f.readlines.each do |line|
90
+ contents << line.chomp
91
+ end
92
+ end
93
+ contents[arg3.to_i - 1].should include arg2
94
+ end
95
+
96
+ Then /^the time record (.*?) should not contain "(.*?)"$/ do |arg1, arg2|
97
+ file = File.join( ENV['HOME'], 'tempo/tempo_time_records', "#{arg1}.yaml")
98
+ contents = []
99
+ File.open(file, "r") do |f|
100
+ f.readlines.each do |line|
101
+ contents << line.chomp
102
+ end
103
+ end
104
+ contents.should_not include arg2
105
+ end
106
+
107
+ Then /^the (.*?) file should contain "(.*?)" at line (\d+)$/ do |arg1, arg2, arg3|
108
+ file = File.join( ENV['HOME'], 'tempo', "tempo_#{arg1}s.yaml")
109
+ contents = []
110
+ File.open(file, "r") do |f|
111
+ f.readlines.each do |line|
112
+ contents << line.chomp
113
+ end
114
+ end
115
+ contents[arg3.to_i - 1].should include arg2
116
+ end
117
+
118
+ Then /^the (.*?) file should contain "(.*?)"$/ do |arg1, arg2|
119
+ file = File.join( ENV['HOME'], 'tempo', "tempo_#{arg1}s.yaml")
120
+ contents = []
121
+ File.open(file, "r") do |f|
122
+ f.readlines.each do |line|
123
+ contents << line.chomp
124
+ end
125
+ end
126
+ contents.should include arg2
127
+ end
128
+
129
+ Then /^the (.*?) file should not contain "(.*?)"$/ do |arg1, arg2|
130
+ file = File.join( ENV['HOME'], 'tempo', "tempo_#{arg1}s.yaml")
131
+ contents = []
132
+ File.open(file, "r") do |f|
133
+ f.readlines.each do |line|
134
+ contents << line.chomp
135
+ end
136
+ end
137
+ contents.should_not include arg2
138
+ end
@@ -0,0 +1,26 @@
1
+ require 'aruba/cucumber'
2
+
3
+ ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
4
+ LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
5
+
6
+ Before do
7
+
8
+ ## Using "announce" causes massive warnings on 1.9.2
9
+ # @puts = true
10
+ # @original_rubylib = ENV['RUBYLIB']
11
+ # ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
12
+
13
+ # switch home environment for testing in Rakefile
14
+ # example for doing this within cucumber:
15
+ #
16
+ @real_home = ENV['HOME']
17
+ @testing_env = File.join(ENV['HOME'], 'testing_features')
18
+ #FileUtils.rm_rf @testing_env, :secure => true
19
+ Dir.mkdir(@testing_env, 0700) unless File.exists?(@testing_env)
20
+ ENV['HOME'] = @testing_env
21
+ end
22
+
23
+ After do
24
+ #FileUtils.rm_rf @testing_env, :secure => true
25
+ ENV['HOME'] = @real_home
26
+ end
@@ -0,0 +1,13 @@
1
+ Feature: GLI bootstrapping sets up cucumber
2
+ GLI scaffold includes aruba and cucumber setup
3
+ Running the tempo project for the first time sets up the folder stucture
4
+
5
+ Scenario: App just runs
6
+ When I get help for "tempo"
7
+ Then the exit status should be 0
8
+
9
+ Scenario: App initialization creates all necessary files
10
+ Given a clean installation
11
+ When I successfully run `tempo project new project`
12
+ Then the exit status should be 0
13
+ And the project file should contain ":title: new project"
@@ -0,0 +1,69 @@
1
+ Feature: Update Command manages edits to the time records
2
+ Time record start and end times, descriptions, and projects can be changed,
3
+ or whole records can be deleted. Time records can be chosen by id and day
4
+
5
+ Scenario: Attempting to update on a day with no records
6
+ Given an existing project file
7
+ And an existing time record file
8
+ When I run `tempo update --on 1/1/2015 practicing banjo`
9
+ Then the stderr should contain "no time records on 01/01/2015 exist"
10
+
11
+ Scenario: Attempting to update by id with no matching records
12
+ Given an existing project file
13
+ And an existing time record file
14
+ When I run `tempo update --id 22 practicing banjo`
15
+ Then the stderr should contain "no time record on 01/01/2014 matches the request: id = 22"
16
+
17
+ Scenario: Deleting the last record
18
+ Given an existing project file
19
+ And an existing time record file
20
+ When I successfully run `tempo update --delete`
21
+ Then the stdout should contain "time record deleted:\n13:32 - 16:46 [3:14] nano aquarium: trimming the coral"
22
+ And the time record 20140101 should not contain "nano aquarium"
23
+
24
+ Scenario: Updating the description for the last time record
25
+ Given an existing project file
26
+ And an existing time record file
27
+ When I successfully run `tempo update anemone feeding`
28
+ Then the stdout should contain "time record updated:\n13:32 - 16:46 [3:14] nano aquarium: anemone feeding"
29
+ And the time record 20140101 should contain ":description: anemone feeding" at line 35
30
+
31
+ Scenario: Updating the start time for the last time record
32
+ Given an existing project file
33
+ And an existing time record file
34
+ When I successfully run `tempo update --start "2014-01-01 13:45"`
35
+ Then the stdout should contain "time record updated:\n13:45 - 16:46 [3:01] nano aquarium: trimming the coral"
36
+ And the time record 20140101 should contain ":start_time: 2014-01-01 13:45:00" at line 36
37
+
38
+ Scenario: Updating the end time for the last time record
39
+ Given an existing project file
40
+ And an existing time record file
41
+ When I successfully run `tempo update --end "2014-01-01 16:35"`
42
+ Then the stdout should contain "time record updated:\n13:32 - 16:35 [3:03] nano aquarium: trimming the coral"
43
+ And the time record 20140101 should contain ":end_time: 2014-01-01 16:35:00" at line 37
44
+
45
+ Scenario: Updating to the project for the last time record
46
+ Given an existing project file
47
+ And an existing time record file
48
+ When I successfully run `tempo update --project`
49
+ Then the stdout should contain "time record updated:\n13:32 - 16:46 [3:14] horticulture: trimming the coral"
50
+ And the time record 20140101 should contain ":description: trimming the coral" at line 35
51
+
52
+ Scenario: Updating a time record on an earlier day
53
+ Given an existing project file
54
+ And an existing time record file
55
+ When I run `tempo start --at "12/1/2013 7:00" --end "12/1/2013 8:00" raking leaves`
56
+ And I run `tempo start --at "12/1/2013 8:00" --end "12/1/2013 9:00" counting rosebuds`
57
+ When I successfully run `tempo update --on "12/1/2013" --id 1 feeding flytraps`
58
+ Then the stdout should contain "time record updated:\n07:00 - 08:00 [1:00] horticulture: feeding flytraps"
59
+ And the time record 20131201 should contain ":description: feeding flytraps" at line 3
60
+
61
+ Scenario: Updating the end time on a time record on an earlier day
62
+ Given an existing project file
63
+ And an existing time record file
64
+ When I run `tempo start --at "12/1/2013 7:00" --end "12/1/2013 8:00" raking leaves`
65
+ And I run `tempo start --at "12/1/2013 9:00" --end "12/1/2013 10:00" counting rosebuds`
66
+ When I successfully run `tempo update --on "12/1/2013" --id 1 --end "12/1/2013 8:35"`
67
+ Then the stdout should contain "time record updated:\n07:00 - 08:35 [1:35] horticulture: raking leaves"
68
+ And the time record 20131201 should contain ":end_time: 2013-12-01 08:35:00" at line 5
69
+
@@ -0,0 +1,11 @@
1
+ module FileRecord
2
+ class Directory
3
+ class << self
4
+ def create_new
5
+ cwd = File.expand_path File.dirname(__FILE__)
6
+ source = File.join(cwd, "directory_structure/tempo")
7
+ FileUtils.cp_r( source, Dir.home )
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ Tempo is a command line time tracking application for creating time sheets based on a project hierarchy.
2
+
3
+
4
+ All records will be stored in the tempo folder in the users home directory. Records are stored in yaml, and can be edited by hand, with discretion. Be aware that editing by hand could create unresolvable conflicts, especially when it comes to the ids assigned to projects.
@@ -0,0 +1,6 @@
1
+ # Tempo projects file for tempo command line time tracker
2
+ # No projects have been created yet, run
3
+ #
4
+ # `tempo projects 'my new project name'
5
+ #
6
+ # to create a new project that will replace this message