tempo-cli 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +56 -0
- data/README.md +326 -0
- data/Rakefile +65 -0
- data/bin/tempo +477 -0
- data/features/arrange.feature +43 -0
- data/features/checkout.feature +63 -0
- data/features/end.feature +65 -0
- data/features/project.feature +246 -0
- data/features/report.feature +62 -0
- data/features/start.feature +87 -0
- data/features/step_definitions/tempo_steps.rb +138 -0
- data/features/support/env.rb +26 -0
- data/features/tempo.feature +13 -0
- data/features/update.feature +69 -0
- data/lib/file_record/directory.rb +11 -0
- data/lib/file_record/directory_structure/tempo/README.txt +4 -0
- data/lib/file_record/directory_structure/tempo/tempo_projects.yaml +6 -0
- data/lib/file_record/record.rb +120 -0
- data/lib/tempo/controllers/arrange_controller.rb +52 -0
- data/lib/tempo/controllers/base.rb +117 -0
- data/lib/tempo/controllers/checkout_controller.rb +42 -0
- data/lib/tempo/controllers/end_controller.rb +42 -0
- data/lib/tempo/controllers/projects_controller.rb +107 -0
- data/lib/tempo/controllers/records_controller.rb +21 -0
- data/lib/tempo/controllers/report_controller.rb +55 -0
- data/lib/tempo/controllers/start_controller.rb +42 -0
- data/lib/tempo/controllers/update_controller.rb +78 -0
- data/lib/tempo/models/base.rb +176 -0
- data/lib/tempo/models/composite.rb +71 -0
- data/lib/tempo/models/log.rb +194 -0
- data/lib/tempo/models/project.rb +73 -0
- data/lib/tempo/models/time_record.rb +235 -0
- data/lib/tempo/version.rb +3 -0
- data/lib/tempo/views/arrange_view.rb +27 -0
- data/lib/tempo/views/base.rb +82 -0
- data/lib/tempo/views/formatters/base.rb +30 -0
- data/lib/tempo/views/formatters/screen.rb +86 -0
- data/lib/tempo/views/projects_view.rb +82 -0
- data/lib/tempo/views/report_view.rb +26 -0
- data/lib/tempo/views/reporter.rb +70 -0
- data/lib/tempo/views/time_record_view.rb +30 -0
- data/lib/tempo/views/view_records/base.rb +117 -0
- data/lib/tempo/views/view_records/composite.rb +40 -0
- data/lib/tempo/views/view_records/log.rb +28 -0
- data/lib/tempo/views/view_records/project.rb +32 -0
- data/lib/tempo/views/view_records/time_record.rb +48 -0
- data/lib/tempo.rb +26 -0
- data/lib/time_utilities.rb +30 -0
- data/tempo-cli.gemspec +26 -0
- data/test/lib/file_record/directory_test.rb +30 -0
- data/test/lib/file_record/record_test.rb +106 -0
- data/test/lib/tempo/controllers/base_controller_test.rb +60 -0
- data/test/lib/tempo/controllers/project_controller_test.rb +24 -0
- data/test/lib/tempo/models/base_test.rb +173 -0
- data/test/lib/tempo/models/composite_test.rb +76 -0
- data/test/lib/tempo/models/log_test.rb +171 -0
- data/test/lib/tempo/models/project_test.rb +105 -0
- data/test/lib/tempo/models/time_record_test.rb +212 -0
- data/test/lib/tempo/views/base_test.rb +31 -0
- data/test/lib/tempo/views/formatters/base_test.rb +13 -0
- data/test/lib/tempo/views/formatters/screen_test.rb +94 -0
- data/test/lib/tempo/views/reporter_test.rb +40 -0
- data/test/lib/tempo/views/view_records/base_test.rb +77 -0
- data/test/lib/tempo/views/view_records/composite_test.rb +57 -0
- data/test/lib/tempo/views/view_records/log_test.rb +28 -0
- data/test/lib/tempo/views/view_records/project_test.rb +0 -0
- data/test/lib/tempo/views/view_records/time_record_test.rb +0 -0
- data/test/support/factories.rb +177 -0
- data/test/support/helpers.rb +69 -0
- data/test/test_helper.rb +31 -0
- 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,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.
|