timetrap 1.5.3 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/README.md +114 -92
- data/VERSION.yml +2 -2
- data/lib/timetrap.rb +1 -61
- data/lib/timetrap/cli.rb +89 -64
- data/lib/timetrap/config.rb +2 -2
- data/lib/timetrap/helpers.rb +14 -6
- data/lib/timetrap/timer.rb +55 -0
- data/spec/spec.opts +1 -0
- data/spec/timetrap_spec.rb +201 -164
- data/timetrap.gemspec +3 -2
- metadata +6 -5
data/lib/timetrap/config.rb
CHANGED
data/lib/timetrap/helpers.rb
CHANGED
@@ -7,7 +7,7 @@ module Timetrap
|
|
7
7
|
elsif sheet =~ /.+/
|
8
8
|
Timetrap::Entry.filter('sheet = ?', sheet)
|
9
9
|
else
|
10
|
-
Timetrap::Entry.filter('sheet = ?',
|
10
|
+
Timetrap::Entry.filter('sheet = ?', Timer.current_sheet)
|
11
11
|
end
|
12
12
|
ee = ee.filter('start >= ?', Date.parse(args['-s'])) if args['-s']
|
13
13
|
ee = ee.filter('start <= ?', Date.parse(args['-e']) + 1) if args['-e']
|
@@ -49,11 +49,19 @@ module Timetrap
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def sheet_name_from_string string
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
string = string.strip
|
53
|
+
case string
|
54
|
+
when /^\W*all\W*$/ then "all"
|
55
|
+
when /^$/ then Timer.current_sheet
|
56
|
+
else
|
57
|
+
entry = DB[:entries].filter(:sheet.like("#{string}")).first ||
|
58
|
+
DB[:entries].filter(:sheet.like("#{string}%")).first
|
59
|
+
if entry
|
60
|
+
entry[:sheet]
|
61
|
+
else
|
62
|
+
raise "Can't find sheet matching #{string.inspect}"
|
63
|
+
end
|
64
|
+
end
|
57
65
|
end
|
58
66
|
end
|
59
67
|
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Timetrap
|
2
|
+
module Timer
|
3
|
+
class AlreadyRunning < StandardError
|
4
|
+
def message
|
5
|
+
"Timetrap is already running"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
extend self
|
10
|
+
|
11
|
+
def current_sheet= sheet
|
12
|
+
m = Meta.find_or_create(:key => 'current_sheet')
|
13
|
+
m.value = sheet
|
14
|
+
m.save
|
15
|
+
end
|
16
|
+
|
17
|
+
def current_sheet
|
18
|
+
unless Meta.find(:key => 'current_sheet')
|
19
|
+
Meta.create(:key => 'current_sheet', :value => 'default')
|
20
|
+
end
|
21
|
+
Meta.find(:key => 'current_sheet').value
|
22
|
+
end
|
23
|
+
|
24
|
+
def entries sheet = nil
|
25
|
+
Entry.filter(:sheet => sheet).order_by(:start)
|
26
|
+
end
|
27
|
+
|
28
|
+
def running?
|
29
|
+
!!active_entry
|
30
|
+
end
|
31
|
+
|
32
|
+
def active_entry(sheet=nil)
|
33
|
+
Entry.find(:sheet => (sheet || Timer.current_sheet), :end => nil)
|
34
|
+
end
|
35
|
+
|
36
|
+
def running_entries
|
37
|
+
Entry.filter(:end => nil)
|
38
|
+
end
|
39
|
+
|
40
|
+
def stop sheet, time = nil
|
41
|
+
if a = active_entry(sheet)
|
42
|
+
time ||= Time.now
|
43
|
+
a.end = time
|
44
|
+
a.save
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def start note, time = nil
|
49
|
+
raise AlreadyRunning if running?
|
50
|
+
time ||= Time.now
|
51
|
+
Entry.create(:sheet => Timer.current_sheet, :note => note, :start => time).save
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
data/spec/spec.opts
CHANGED
data/spec/timetrap_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
TEST_MODE = true
|
2
|
-
require File.join(File.dirname(__FILE__), '..', 'lib', 'timetrap')
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'timetrap'))
|
3
3
|
require 'spec'
|
4
4
|
require 'fakefs/safe'
|
5
5
|
|
@@ -27,6 +27,7 @@ describe Timetrap do
|
|
27
27
|
Timetrap::Meta.create_table!
|
28
28
|
$stdout = StringIO.new
|
29
29
|
$stdin = StringIO.new
|
30
|
+
$stderr = StringIO.new
|
30
31
|
end
|
31
32
|
|
32
33
|
describe 'CLI' do
|
@@ -36,6 +37,13 @@ describe Timetrap do
|
|
36
37
|
Timetrap::CLI.invoke
|
37
38
|
end
|
38
39
|
|
40
|
+
describe 'with no command' do
|
41
|
+
it "should invoke --help" do
|
42
|
+
invoke ''
|
43
|
+
$stdout.string.should include "Usage"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
39
47
|
describe 'archive' do
|
40
48
|
before do
|
41
49
|
3.times do |i|
|
@@ -80,64 +88,64 @@ describe Timetrap do
|
|
80
88
|
|
81
89
|
describe 'edit' do
|
82
90
|
before do
|
83
|
-
Timetrap.start "running entry", nil
|
91
|
+
Timetrap::Timer.start "running entry", nil
|
84
92
|
end
|
85
93
|
|
86
94
|
it "should edit the description of the active period" do
|
87
|
-
Timetrap.active_entry.note.should == 'running entry'
|
95
|
+
Timetrap::Timer.active_entry.note.should == 'running entry'
|
88
96
|
invoke 'edit new description'
|
89
|
-
Timetrap.active_entry.note.should == 'new description'
|
97
|
+
Timetrap::Timer.active_entry.note.should == 'new description'
|
90
98
|
end
|
91
99
|
|
92
100
|
it "should allow you to move an entry to another sheet" do
|
93
101
|
invoke 'edit --move blahblah'
|
94
|
-
Timetrap.active_entry[:sheet].should == 'blahblah'
|
102
|
+
Timetrap::Timer.active_entry[:sheet].should == 'blahblah'
|
95
103
|
invoke 'edit -m blahblahblah'
|
96
|
-
Timetrap.active_entry[:sheet].should == 'blahblahblah'
|
104
|
+
Timetrap::Timer.active_entry[:sheet].should == 'blahblahblah'
|
97
105
|
end
|
98
106
|
|
99
107
|
it "should change the current sheet if the current entry's sheet is changed" do
|
100
|
-
Timetrap.current_sheet.should_not == 'blahblahblah'
|
108
|
+
Timetrap::Timer.current_sheet.should_not == 'blahblahblah'
|
101
109
|
invoke 'edit -m blahblahblah'
|
102
|
-
Timetrap.active_entry[:sheet].should == 'blahblahblah'
|
103
|
-
Timetrap.current_sheet.should == 'blahblahblah'
|
110
|
+
Timetrap::Timer.active_entry[:sheet].should == 'blahblahblah'
|
111
|
+
Timetrap::Timer.current_sheet.should == 'blahblahblah'
|
104
112
|
end
|
105
113
|
|
106
114
|
it "should change the current sheet if a non current entry's sheet is changed" do
|
107
|
-
sheet = Timetrap.current_sheet
|
108
|
-
id = Timetrap.active_entry[:id]
|
115
|
+
sheet = Timetrap::Timer.current_sheet
|
116
|
+
id = Timetrap::Timer.active_entry[:id]
|
109
117
|
invoke 'out'
|
110
118
|
invoke "edit -m blahblahblah -i #{id}"
|
111
|
-
Timetrap.current_sheet.should == sheet
|
119
|
+
Timetrap::Timer.current_sheet.should == sheet
|
112
120
|
Timetrap::Entry[id][:sheet].should == 'blahblahblah'
|
113
121
|
end
|
114
122
|
|
115
123
|
it "should allow appending to the description of the active period" do
|
116
124
|
with_stubbed_config('append_notes_delimiter' => '//')
|
117
|
-
Timetrap.active_entry.note.should == 'running entry'
|
125
|
+
Timetrap::Timer.active_entry.note.should == 'running entry'
|
118
126
|
invoke 'edit --append new'
|
119
|
-
Timetrap.active_entry.note.should == 'running entry//new'
|
127
|
+
Timetrap::Timer.active_entry.note.should == 'running entry//new'
|
120
128
|
invoke 'edit -z more'
|
121
|
-
Timetrap.active_entry.note.should == 'running entry//new//more'
|
129
|
+
Timetrap::Timer.active_entry.note.should == 'running entry//new//more'
|
122
130
|
end
|
123
131
|
|
124
132
|
it "should edit the start time of the active period" do
|
125
133
|
invoke 'edit --start "yesterday 10am"'
|
126
|
-
Timetrap.active_entry.start.should == Chronic.parse("yesterday 10am")
|
127
|
-
Timetrap.active_entry.note.should == 'running entry'
|
134
|
+
Timetrap::Timer.active_entry.start.should == Chronic.parse("yesterday 10am")
|
135
|
+
Timetrap::Timer.active_entry.note.should == 'running entry'
|
128
136
|
end
|
129
137
|
|
130
138
|
it "should edit the end time of the active period" do
|
131
|
-
entry = Timetrap.active_entry
|
139
|
+
entry = Timetrap::Timer.active_entry
|
132
140
|
invoke 'edit --end "yesterday 10am"'
|
133
141
|
entry.refresh.end.should == Chronic.parse("yesterday 10am")
|
134
142
|
entry.refresh.note.should == 'running entry'
|
135
143
|
end
|
136
144
|
|
137
145
|
it "should edit a non running entry based on id" do
|
138
|
-
not_running = Timetrap.active_entry
|
139
|
-
Timetrap.stop
|
140
|
-
Timetrap.start "another entry", nil
|
146
|
+
not_running = Timetrap::Timer.active_entry
|
147
|
+
Timetrap::Timer.stop(Timetrap::Timer.current_sheet)
|
148
|
+
Timetrap::Timer.start "another entry", nil
|
141
149
|
invoke "edit --id #{not_running.id} a new description"
|
142
150
|
not_running.refresh.note.should == 'a new description'
|
143
151
|
end
|
@@ -219,30 +227,39 @@ Grand Total 10:00:00
|
|
219
227
|
end
|
220
228
|
|
221
229
|
it "should display the current timesheet" do
|
222
|
-
Timetrap.current_sheet = 'SpecSheet'
|
230
|
+
Timetrap::Timer.current_sheet = 'SpecSheet'
|
223
231
|
invoke 'display'
|
224
232
|
$stdout.string.should == @desired_output
|
225
233
|
end
|
226
234
|
|
227
235
|
it "should display a non current timesheet" do
|
228
|
-
Timetrap.current_sheet = 'another'
|
236
|
+
Timetrap::Timer.current_sheet = 'another'
|
229
237
|
invoke 'display SpecSheet'
|
230
238
|
$stdout.string.should == @desired_output
|
231
239
|
end
|
232
240
|
|
233
241
|
it "should display a non current timesheet based on a partial name match" do
|
234
|
-
Timetrap.current_sheet = 'another'
|
242
|
+
Timetrap::Timer.current_sheet = 'another'
|
235
243
|
invoke 'display S'
|
236
244
|
$stdout.string.should == @desired_output
|
237
245
|
end
|
238
246
|
|
247
|
+
it "should prefer an exact match of a named sheet to a partial match" do
|
248
|
+
Timetrap::Timer.current_sheet = 'Spec'
|
249
|
+
Timetrap::Entry.create( :sheet => 'Spec',
|
250
|
+
:note => 'entry 5', :start => '2008-10-05 18:00:00'
|
251
|
+
)
|
252
|
+
invoke 'display Spec'
|
253
|
+
$stdout.string.should include("entry 5")
|
254
|
+
end
|
255
|
+
|
239
256
|
it "should display a timesheet with ids" do
|
240
257
|
invoke 'display S --ids'
|
241
258
|
$stdout.string.should == @desired_output_with_ids
|
242
259
|
end
|
243
260
|
|
244
261
|
it "should display all timesheets" do
|
245
|
-
Timetrap.current_sheet = 'another'
|
262
|
+
Timetrap::Timer.current_sheet = 'another'
|
246
263
|
invoke 'display all'
|
247
264
|
$stdout.string.should == @desired_output_for_all
|
248
265
|
end
|
@@ -352,7 +369,7 @@ END:VCALENDAR
|
|
352
369
|
end
|
353
370
|
|
354
371
|
it "should not start the time if the timetrap is running" do
|
355
|
-
Timetrap.stub!(:running?).and_return true
|
372
|
+
Timetrap::Timer.stub!(:running?).and_return true
|
356
373
|
lambda do
|
357
374
|
invoke 'in'
|
358
375
|
end.should_not change(Timetrap::Entry, :count)
|
@@ -368,7 +385,7 @@ END:VCALENDAR
|
|
368
385
|
Time.stub!(:now).and_return now
|
369
386
|
invoke 'in work --at="18 minutes ago"'
|
370
387
|
Timetrap::Entry.order_by(:id).last.should be_nil
|
371
|
-
$
|
388
|
+
$stderr.string.should =~ /\w+/
|
372
389
|
end
|
373
390
|
|
374
391
|
it "should fail with a time argurment of total garbage" do
|
@@ -376,7 +393,7 @@ END:VCALENDAR
|
|
376
393
|
Time.stub!(:now).and_return now
|
377
394
|
invoke 'in work --at "total garbage"'
|
378
395
|
Timetrap::Entry.order_by(:id).last.should be_nil
|
379
|
-
$
|
396
|
+
$stderr.string.should =~ /\w+/
|
380
397
|
end
|
381
398
|
end
|
382
399
|
|
@@ -418,9 +435,9 @@ END:VCALENDAR
|
|
418
435
|
|
419
436
|
describe "list" do
|
420
437
|
describe "with no sheets defined" do
|
421
|
-
it "should
|
438
|
+
it "should list the default sheet" do
|
422
439
|
invoke 'list'
|
423
|
-
$stdout.string.chomp.should ==
|
440
|
+
$stdout.string.chomp.should == " Timesheet Running Today Total Time\n*default 0:00:00 0:00:00 0:00:00"
|
424
441
|
end
|
425
442
|
end
|
426
443
|
|
@@ -437,13 +454,25 @@ END:VCALENDAR
|
|
437
454
|
:end => nil)
|
438
455
|
create_entry( :sheet => 'Sheet 1', :start => '2008-10-03 16:00:00',
|
439
456
|
:end => '2008-10-03 18:00:00')
|
440
|
-
Timetrap.current_sheet = 'A Longly Named Sheet 2'
|
457
|
+
Timetrap::Timer.current_sheet = 'A Longly Named Sheet 2'
|
441
458
|
end
|
442
459
|
it "should list available timesheets" do
|
443
460
|
invoke 'list'
|
444
461
|
$stdout.string.should == <<-OUTPUT
|
445
462
|
Timesheet Running Today Total Time
|
446
463
|
*A Longly Named Sheet 2 4:00:00 6:00:00 10:00:00
|
464
|
+
Sheet 1 0:00:00 0:00:00 2:00:00
|
465
|
+
OUTPUT
|
466
|
+
end
|
467
|
+
|
468
|
+
it "should include the active timesheet even if it has no entries" do
|
469
|
+
invoke 'sheet empty sheet'
|
470
|
+
$stdout.string = ''
|
471
|
+
invoke 'list'
|
472
|
+
$stdout.string.should == <<-OUTPUT
|
473
|
+
Timesheet Running Today Total Time
|
474
|
+
A Longly Named Sheet 2 4:00:00 6:00:00 10:00:00
|
475
|
+
*empty sheet 0:00:00 0:00:00 0:00:00
|
447
476
|
Sheet 1 0:00:00 0:00:00 2:00:00
|
448
477
|
OUTPUT
|
449
478
|
end
|
@@ -452,14 +481,14 @@ END:VCALENDAR
|
|
452
481
|
|
453
482
|
describe "now" do
|
454
483
|
before do
|
455
|
-
Timetrap.current_sheet = 'current sheet'
|
484
|
+
Timetrap::Timer.current_sheet = 'current sheet'
|
456
485
|
end
|
457
486
|
|
458
487
|
describe "when the current timesheet isn't running" do
|
459
488
|
it "should show that it isn't running" do
|
460
489
|
invoke 'now'
|
461
490
|
$stdout.string.should == <<-OUTPUT
|
462
|
-
current sheet: not running
|
491
|
+
*current sheet: not running
|
463
492
|
OUTPUT
|
464
493
|
end
|
465
494
|
end
|
@@ -467,25 +496,44 @@ current sheet: not running
|
|
467
496
|
describe "when the current timesheet is running" do
|
468
497
|
before do
|
469
498
|
invoke 'in a timesheet that is running'
|
470
|
-
@entry = Timetrap.active_entry
|
471
|
-
@entry.
|
499
|
+
@entry = Timetrap::Timer.active_entry
|
500
|
+
@entry.start = Time.at(0)
|
501
|
+
@entry.save
|
472
502
|
Time.stub!(:now).and_return Time.at(60)
|
473
|
-
Timetrap.stub!(:active_entry).and_return @entry
|
474
503
|
end
|
475
504
|
|
476
505
|
it "should show how long the current item is running for" do
|
477
506
|
invoke 'now'
|
478
507
|
$stdout.string.should == <<-OUTPUT
|
479
|
-
current sheet: 0:01:00 (a timesheet that is running)
|
508
|
+
*current sheet: 0:01:00 (a timesheet that is running)
|
480
509
|
OUTPUT
|
481
510
|
end
|
511
|
+
|
512
|
+
describe "and another timesheet is running too" do
|
513
|
+
before do
|
514
|
+
invoke 'sheet another-sheet'
|
515
|
+
invoke 'in also running'
|
516
|
+
@entry = Timetrap::Timer.active_entry
|
517
|
+
@entry.start = Time.at(0)
|
518
|
+
@entry.save
|
519
|
+
Time.stub!(:now).and_return Time.at(60)
|
520
|
+
end
|
521
|
+
|
522
|
+
it "should show both entries" do
|
523
|
+
invoke 'now'
|
524
|
+
$stdout.string.should == <<-OUTPUT
|
525
|
+
current sheet: 0:01:00 (a timesheet that is running)
|
526
|
+
*another-sheet: 0:01:00 (also running)
|
527
|
+
OUTPUT
|
528
|
+
end
|
529
|
+
end
|
482
530
|
end
|
483
531
|
end
|
484
532
|
|
485
533
|
describe "out" do
|
486
534
|
before :each do
|
487
535
|
invoke 'in'
|
488
|
-
@active = Timetrap.active_entry
|
536
|
+
@active = Timetrap::Timer.active_entry
|
489
537
|
@now = Time.now
|
490
538
|
Time.stub!(:now).and_return @now
|
491
539
|
end
|
@@ -504,36 +552,32 @@ current sheet: 0:01:00 (a timesheet that is running)
|
|
504
552
|
|
505
553
|
it "should allow the sheet to be stopped at a certain time" do
|
506
554
|
invoke 'out --at "10am 2008-10-03"'
|
507
|
-
|
555
|
+
@active.refresh.end.should == Time.parse('2008-10-03 10:00')
|
508
556
|
end
|
509
|
-
end
|
510
557
|
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
invoke '
|
517
|
-
|
518
|
-
|
519
|
-
it "should show no runnig timesheets" do
|
520
|
-
invoke 'running'
|
521
|
-
$stdout.string.should == "Running Timesheets:\n"
|
558
|
+
it "should allow you to check out of a non active sheet" do
|
559
|
+
invoke 'sheet SomeOtherSheet'
|
560
|
+
invoke 'in'
|
561
|
+
@new_active = Timetrap::Timer.active_entry
|
562
|
+
@active.should_not == @new_active
|
563
|
+
invoke %'out #{@active.sheet} --at "10am 2008-10-03"'
|
564
|
+
@active.refresh.end.should == Time.parse('2008-10-03 10:00')
|
565
|
+
@new_active.refresh.end.should be_nil
|
522
566
|
end
|
523
567
|
end
|
524
568
|
|
525
|
-
describe "
|
569
|
+
describe "sheet" do
|
526
570
|
it "should switch to a new timesheet" do
|
527
|
-
invoke '
|
528
|
-
Timetrap.current_sheet.should == 'sheet 1'
|
529
|
-
invoke '
|
530
|
-
Timetrap.current_sheet.should == 'sheet 2'
|
571
|
+
invoke 'sheet sheet 1'
|
572
|
+
Timetrap::Timer.current_sheet.should == 'sheet 1'
|
573
|
+
invoke 'sheet sheet 2'
|
574
|
+
Timetrap::Timer.current_sheet.should == 'sheet 2'
|
531
575
|
end
|
532
576
|
|
533
577
|
it "should not switch to an blank timesheet" do
|
534
|
-
invoke '
|
535
|
-
invoke '
|
536
|
-
Timetrap.current_sheet.should == 'sheet 1'
|
578
|
+
invoke 'sheet sheet 1'
|
579
|
+
invoke 'sheet'
|
580
|
+
Timetrap::Timer.current_sheet.should == 'sheet 1'
|
537
581
|
end
|
538
582
|
end
|
539
583
|
end
|
@@ -542,7 +586,7 @@ current sheet: 0:01:00 (a timesheet that is running)
|
|
542
586
|
describe "entries" do
|
543
587
|
it "should give the entires for a sheet" do
|
544
588
|
e = create_entry :sheet => 'sheet'
|
545
|
-
Timetrap.entries('sheet').all.should include(e)
|
589
|
+
Timetrap::Timer.entries('sheet').all.should include(e)
|
546
590
|
end
|
547
591
|
|
548
592
|
end
|
@@ -550,9 +594,9 @@ current sheet: 0:01:00 (a timesheet that is running)
|
|
550
594
|
describe "start" do
|
551
595
|
it "should start an new entry" do
|
552
596
|
@time = Time.now
|
553
|
-
Timetrap.current_sheet = 'sheet1'
|
597
|
+
Timetrap::Timer.current_sheet = 'sheet1'
|
554
598
|
lambda do
|
555
|
-
Timetrap.start 'some work', @time
|
599
|
+
Timetrap::Timer.start 'some work', @time
|
556
600
|
end.should change(Timetrap::Entry, :count).by(1)
|
557
601
|
Timetrap::Entry.order(:id).last.sheet.should == 'sheet1'
|
558
602
|
Timetrap::Entry.order(:id).last.note.should == 'some work'
|
@@ -561,156 +605,149 @@ current sheet: 0:01:00 (a timesheet that is running)
|
|
561
605
|
end
|
562
606
|
|
563
607
|
it "should be running if it is started" do
|
564
|
-
Timetrap.should_not be_running
|
565
|
-
Timetrap.start 'some work', @time
|
566
|
-
Timetrap.should be_running
|
608
|
+
Timetrap::Timer.should_not be_running
|
609
|
+
Timetrap::Timer.start 'some work', @time
|
610
|
+
Timetrap::Timer.should be_running
|
567
611
|
end
|
568
612
|
|
569
|
-
it "should raise
|
613
|
+
it "should raise an error if it is already running" do
|
570
614
|
lambda do
|
571
|
-
Timetrap.start 'some work', @time
|
572
|
-
Timetrap.start 'some work', @time
|
573
|
-
end.should
|
615
|
+
Timetrap::Timer.start 'some work', @time
|
616
|
+
Timetrap::Timer.start 'some work', @time
|
617
|
+
end.should raise_error(Timetrap::Timer::AlreadyRunning)
|
574
618
|
end
|
575
619
|
end
|
576
620
|
|
577
621
|
describe "stop" do
|
578
622
|
it "should stop a new entry" do
|
579
623
|
@time = Time.now
|
580
|
-
Timetrap.start 'some work', @time
|
581
|
-
entry = Timetrap.active_entry
|
624
|
+
Timetrap::Timer.start 'some work', @time
|
625
|
+
entry = Timetrap::Timer.active_entry
|
582
626
|
entry.end.should be_nil
|
583
|
-
Timetrap.stop @time
|
627
|
+
Timetrap::Timer.stop Timetrap::Timer.current_sheet, @time
|
584
628
|
entry.refresh.end.to_i.should == @time.to_i
|
585
629
|
end
|
586
630
|
|
587
631
|
it "should not be running if it is stopped" do
|
588
|
-
Timetrap.should_not be_running
|
589
|
-
Timetrap.start 'some work', @time
|
590
|
-
Timetrap.stop
|
591
|
-
Timetrap.should_not be_running
|
632
|
+
Timetrap::Timer.should_not be_running
|
633
|
+
Timetrap::Timer.start 'some work', @time
|
634
|
+
Timetrap::Timer.stop Timetrap::Timer.current_sheet
|
635
|
+
Timetrap::Timer.should_not be_running
|
592
636
|
end
|
593
637
|
|
594
638
|
it "should not stop it twice" do
|
595
|
-
Timetrap.start 'some work'
|
596
|
-
e = Timetrap.active_entry
|
597
|
-
Timetrap.stop
|
639
|
+
Timetrap::Timer.start 'some work'
|
640
|
+
e = Timetrap::Timer.active_entry
|
641
|
+
Timetrap::Timer.stop Timetrap::Timer.current_sheet
|
598
642
|
time = e.refresh.end
|
599
|
-
Timetrap.stop
|
643
|
+
Timetrap::Timer.stop Timetrap::Timer.current_sheet
|
600
644
|
time.to_i.should == e.refresh.end.to_i
|
601
645
|
end
|
602
646
|
|
603
647
|
end
|
604
648
|
|
605
|
-
describe 'switch' do
|
606
|
-
it "should switch to a new sheet" do
|
607
|
-
Timetrap.switch 'sheet1'
|
608
|
-
Timetrap.current_sheet.should == 'sheet1'
|
609
|
-
Timetrap.switch 'sheet2'
|
610
|
-
Timetrap.current_sheet.should == 'sheet2'
|
611
|
-
end
|
612
|
-
end
|
613
649
|
|
614
|
-
|
615
|
-
|
616
|
-
describe Timetrap::Entry do
|
617
|
-
|
618
|
-
include Timetrap::StubConfig
|
619
|
-
describe "with an instance" do
|
620
|
-
before do
|
621
|
-
@time = Time.now
|
622
|
-
@entry = Timetrap::Entry.new
|
623
|
-
end
|
650
|
+
describe Timetrap::Entry do
|
624
651
|
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
@
|
652
|
+
include Timetrap::StubConfig
|
653
|
+
describe "with an instance" do
|
654
|
+
before do
|
655
|
+
@time = Time.now
|
656
|
+
@entry = Timetrap::Entry.new
|
629
657
|
end
|
630
658
|
|
631
|
-
|
632
|
-
|
633
|
-
|
659
|
+
describe '.sheets' do
|
660
|
+
it "should output a list of all the available sheets" do
|
661
|
+
Timetrap::Entry.create( :sheet => 'another',
|
662
|
+
:note => 'entry 4', :start => '2008-10-05 18:00:00'
|
663
|
+
)
|
664
|
+
Timetrap::Entry.create( :sheet => 'SpecSheet',
|
665
|
+
:note => 'entry 2', :start => '2008-10-03 16:00:00', :end => '2008-10-03 18:00:00'
|
666
|
+
)
|
667
|
+
Timetrap::Entry.sheets.should == %w(another SpecSheet).sort
|
668
|
+
end
|
634
669
|
end
|
635
670
|
|
636
|
-
it "should have a end" do
|
637
|
-
@entry.end = @time
|
638
|
-
@entry.end.to_i.should == @time.to_i
|
639
|
-
end
|
640
671
|
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
672
|
+
describe 'attributes' do
|
673
|
+
it "should have a note" do
|
674
|
+
@entry.note = "world takeover"
|
675
|
+
@entry.note.should == "world takeover"
|
676
|
+
end
|
677
|
+
|
678
|
+
it "should have a start" do
|
679
|
+
@entry.start = @time
|
680
|
+
@entry.start.to_i.should == @time.to_i
|
681
|
+
end
|
645
682
|
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
Timetrap::Entry.round = true
|
650
|
-
block_return_value = yield
|
651
|
-
ensure
|
652
|
-
Timetrap::Entry.round = old_val
|
683
|
+
it "should have a end" do
|
684
|
+
@entry.end = @time
|
685
|
+
@entry.end.to_i.should == @time.to_i
|
653
686
|
end
|
654
|
-
end
|
655
687
|
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
688
|
+
it "should have a sheet" do
|
689
|
+
@entry.sheet= 'name'
|
690
|
+
@entry.sheet.should == 'name'
|
691
|
+
end
|
692
|
+
|
693
|
+
def with_rounding_on
|
694
|
+
old_val = Timetrap::Entry.round
|
695
|
+
begin
|
696
|
+
Timetrap::Entry.round = true
|
697
|
+
block_return_value = yield
|
698
|
+
ensure
|
699
|
+
Timetrap::Entry.round = old_val
|
662
700
|
end
|
663
701
|
end
|
664
|
-
end
|
665
702
|
|
666
|
-
|
667
|
-
|
703
|
+
it "should use round start if the global round attribute is set" do
|
704
|
+
with_rounding_on do
|
705
|
+
with_stubbed_config('round_in_seconds' => 900) do
|
706
|
+
@time = Chronic.parse("12:55am")
|
707
|
+
@entry.start = @time
|
708
|
+
@entry.start.should == Chronic.parse("1am")
|
709
|
+
end
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
713
|
+
it "should use round start if the global round attribute is set" do
|
714
|
+
with_rounding_on do
|
715
|
+
with_stubbed_config('round_in_seconds' => 900) do
|
716
|
+
@time = Chronic.parse("12:50am")
|
717
|
+
@entry.start = @time
|
718
|
+
@entry.start.should == Chronic.parse("12:45am")
|
719
|
+
end
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
723
|
+
it "should have a rounded start" do
|
668
724
|
with_stubbed_config('round_in_seconds' => 900) do
|
669
725
|
@time = Chronic.parse("12:50am")
|
670
726
|
@entry.start = @time
|
671
|
-
@entry.
|
727
|
+
@entry.rounded_start.should == Chronic.parse("12:45am")
|
672
728
|
end
|
673
729
|
end
|
674
|
-
end
|
675
730
|
|
676
|
-
|
677
|
-
|
678
|
-
@
|
679
|
-
@entry.start = @time
|
680
|
-
@entry.rounded_start.should == Chronic.parse("12:45am")
|
731
|
+
it "should not round nil times" do
|
732
|
+
@entry.start = nil
|
733
|
+
@entry.rounded_start.should be_nil
|
681
734
|
end
|
682
735
|
end
|
683
736
|
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
describe "parsing natural language times" do
|
691
|
-
it "should set start time using english" do
|
692
|
-
@entry.start = "yesterday 10am"
|
693
|
-
@entry.start.should_not be_nil
|
694
|
-
@entry.start.should == Chronic.parse("yesterday 10am")
|
695
|
-
end
|
737
|
+
describe "parsing natural language times" do
|
738
|
+
it "should set start time using english" do
|
739
|
+
@entry.start = "yesterday 10am"
|
740
|
+
@entry.start.should_not be_nil
|
741
|
+
@entry.start.should == Chronic.parse("yesterday 10am")
|
742
|
+
end
|
696
743
|
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
744
|
+
it "should set end time using english" do
|
745
|
+
@entry.end = "tomorrow 1pm"
|
746
|
+
@entry.end.should_not be_nil
|
747
|
+
@entry.end.should == Chronic.parse("tomorrow 1pm")
|
748
|
+
end
|
701
749
|
end
|
702
750
|
end
|
703
|
-
end
|
704
751
|
|
705
|
-
describe '::sheets' do
|
706
|
-
it "should output a list of all the available sheets" do
|
707
|
-
Timetrap::Entry.create( :sheet => 'another',
|
708
|
-
:note => 'entry 4', :start => '2008-10-05 18:00:00'
|
709
|
-
)
|
710
|
-
Timetrap::Entry.create( :sheet => 'SpecSheet',
|
711
|
-
:note => 'entry 2', :start => '2008-10-03 16:00:00', :end => '2008-10-03 18:00:00'
|
712
|
-
)
|
713
|
-
Timetrap::Entry.sheets.should == %w(another SpecSheet).sort
|
714
|
-
end
|
715
752
|
end
|
716
753
|
end
|