one_inch_punch 0.5.1 → 0.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/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ == 0.6.0 2012-04-10
2
+
3
+ * 1 minor enhancement:
4
+ * adding 'entry' command:
5
+ * combines in+out into one command, requiring from (in) and to (out) times
6
+ * has 'clock' alias
7
+
1
8
  == 0.5.1 2012-03-19
2
9
 
3
10
  * 1 tiny bugfix:
data/bin/punch CHANGED
@@ -33,6 +33,10 @@ BANNER
33
33
  "Restrict command to only on the given date") { |date| OPTIONS[:on] = Date.parse(date) }
34
34
  opts.on('--at [TIME]', '--time [TIME]', String,
35
35
  "Use the given time") { |time| OPTIONS[:time] = Time.parse(time) }
36
+ opts.on('--from [TIME]', String,
37
+ "Use the given time") { |time| OPTIONS[:from] = Time.parse(time) }
38
+ opts.on('--to [TIME]', String,
39
+ "Use the given time") { |time| OPTIONS[:to] = Time.parse(time) }
36
40
  opts.on('-m', '--message [MESSAGE]', String,
37
41
  "Use the given log message") { |message| OPTIONS[:message] = message }
38
42
  opts.on('--full',
@@ -104,6 +108,17 @@ commands = {
104
108
  puts message
105
109
  end
106
110
  end,
111
+ 'entry' => lambda do |project|
112
+ if project
113
+ if Punch.entry(project, OPTIONS)
114
+ Punch.write
115
+ else
116
+ puts "Cannot create entry for '#{project}'"
117
+ end
118
+ else
119
+ puts "Project required"
120
+ end
121
+ end,
107
122
  'log' => lambda do |project|
108
123
  if project
109
124
  if message = OPTIONS.delete(:message) || ARGV[2]
@@ -136,6 +151,7 @@ commands = {
136
151
  end
137
152
  end
138
153
  }
154
+ commands['clock'] = commands['entry']
139
155
 
140
156
  if command_code = commands[command]
141
157
  command_code.call(project)
data/lib/punch.rb CHANGED
@@ -108,7 +108,19 @@ class Punch
108
108
  end
109
109
  true
110
110
  end
111
-
111
+
112
+ def entry(project, options = {})
113
+ raise ArgumentError, 'both :from and :to time are needed' unless options[:from] and options[:to]
114
+
115
+ in_options = { :time => options[:from] }
116
+ in_options[:message] = options[:message] if options[:message]
117
+ result = self.in(project, in_options)
118
+ return result unless result
119
+
120
+ out(project, :time => options[:to])
121
+ end
122
+ alias_method :clock, :entry
123
+
112
124
  def delete(project)
113
125
  return nil unless data.delete(project)
114
126
  true
@@ -24,7 +24,12 @@ class Punch
24
24
  def out(options = {})
25
25
  self.class.out(project, options)
26
26
  end
27
-
27
+
28
+ def entry(options = {})
29
+ self.class.entry(project, options)
30
+ end
31
+ alias_method :clock, :entry
32
+
28
33
  def list(options = {})
29
34
  self.class.list(project, options)
30
35
  end
data/lib/punch/version.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  class Punch
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 5
5
- TINY = 1
4
+ MINOR = 6
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -467,7 +467,127 @@ describe 'punch command' do
467
467
  end
468
468
  end
469
469
  end
470
-
470
+
471
+ describe "when the command is 'entry'" do
472
+ before do
473
+ Punch.stub!(:entry)
474
+ @from_option = '2012-04-10 14:39'
475
+ @to_option = '2012-04-10 17:43'
476
+ end
477
+
478
+ it 'should load punch data' do
479
+ Punch.should.receive(:load)
480
+ run_command('entry', @project)
481
+ end
482
+
483
+ it 'should make a punch entry for the given project' do
484
+ from_option = '2012-04-10 14:39'
485
+ from_time = Time.local(2012, 4, 10, 14, 39)
486
+ to_option = '2012-04-10 17:43'
487
+ to_time = Time.local(2012, 4, 10, 17, 43)
488
+
489
+ Punch.should.receive(:entry) do |proj, options|
490
+ proj.should == @project
491
+ options[:from].should == from_time
492
+ options[:to ].should == to_time
493
+ end
494
+
495
+ run_command('entry', @project, '--from', from_option, '--to', to_option)
496
+ end
497
+
498
+ it 'should pass a message if specified on the command line (with --message)' do
499
+ message = 'About to do some amazing work'
500
+
501
+ Punch.should.receive(:entry) do |proj, options|
502
+ proj.should == @project
503
+ options[:message].should == message
504
+ end
505
+
506
+ run_command('entry', @project, '--from', @from_option, '--to', @to_option, '--message', message)
507
+ end
508
+
509
+ it 'should pass a message if specified on the command line (with -m)' do
510
+ message = 'About to do some amazing work'
511
+
512
+ Punch.should.receive(:entry) do |proj, options|
513
+ proj.should == @project
514
+ options[:message].should == message
515
+ end
516
+
517
+ run_command('entry', @project, '--from', @from_option, '--to', @to_option, '-m', message)
518
+ end
519
+
520
+ describe 'when entry created successfully' do
521
+ before do
522
+ Punch.stub!(:entry).and_return(true)
523
+ end
524
+
525
+ it 'should write the data' do
526
+ Punch.should.receive(:write)
527
+ run_command('entry', @project, '--from', @from_option, '--to', @to_option)
528
+ end
529
+
530
+ it 'should not print anything' do
531
+ self.should.receive(:puts).never
532
+ run_command('entry', @project, '--from', @from_option, '--to', @to_option)
533
+ end
534
+ end
535
+
536
+ describe 'when entry not created successfully' do
537
+ before do
538
+ Punch.stub!(:entry).and_return(false)
539
+ end
540
+
541
+ it 'should not write the data' do
542
+ Punch.should.receive(:write).never
543
+ run_command('entry', @project, '--from', @from_option, '--to', @to_option)
544
+ end
545
+
546
+ it 'should print a message' do
547
+ self.should.receive(:puts) do |output|
548
+ output.should.match(/cannot.+entry/i)
549
+ end
550
+ run_command('entry', @project, '--from', @from_option, '--to', @to_option)
551
+ end
552
+ end
553
+
554
+ describe 'when no project given' do
555
+ it 'should display an error message' do
556
+ self.should.receive(:puts) do |output|
557
+ output.should.match(/project.+require/i)
558
+ end
559
+ run_command('entry')
560
+ end
561
+
562
+ it 'should not create an entry' do
563
+ Punch.stub!(:write)
564
+ Punch.should.receive(:entry).never
565
+ run_command('entry')
566
+ end
567
+
568
+ it 'should not write the data' do
569
+ Punch.should.receive(:write).never
570
+ run_command('entry')
571
+ end
572
+ end
573
+
574
+ it "should have 'clock' as an alias" do
575
+ from_option = '2012-04-10 14:39'
576
+ from_time = Time.local(2012, 4, 10, 14, 39)
577
+ to_option = '2012-04-10 17:43'
578
+ to_time = Time.local(2012, 4, 10, 17, 43)
579
+
580
+ Punch.should.receive(:entry) do |proj, options|
581
+ proj.should == @project
582
+ options[:from].should == from_time
583
+ options[:to ].should == to_time
584
+ end
585
+
586
+ run_command('clock', @project, '--from', from_option, '--to', to_option)
587
+ end
588
+
589
+ end
590
+
471
591
  describe "when the command is 'delete'" do
472
592
  before do
473
593
  Punch.stub!(:delete)
@@ -220,6 +220,60 @@ describe Punch, 'instance' do
220
220
  end
221
221
  end
222
222
 
223
+ it 'should make a punch entry' do
224
+ @punch.should.respond_to(:entry)
225
+ end
226
+
227
+ describe 'making a punch entry' do
228
+ before do
229
+ @entry = 'entry val'
230
+ Punch.stub!(:entry).and_return(@entry)
231
+ end
232
+
233
+ it 'should accept options' do
234
+ lambda { @punch.entry(:time => Time.now) }.should.not.raise(ArgumentError)
235
+ end
236
+
237
+ it 'should not require options' do
238
+ lambda { @punch.entry }.should.not.raise(ArgumentError)
239
+ end
240
+
241
+ it 'should delegate to the class' do
242
+ Punch.should.receive(:entry)
243
+ @punch.entry
244
+ end
245
+
246
+ it 'should pass the project when delegating to the class' do
247
+ Punch.should.receive(:entry) do |proj, _|
248
+ proj.should == @project
249
+ end
250
+ @punch.entry
251
+ end
252
+
253
+ it 'should pass the options when delegating to the class' do
254
+ options = { :time => Time.now }
255
+ Punch.should.receive(:entry) do |_, opts|
256
+ opts.should == options
257
+ end
258
+ @punch.entry(options)
259
+ end
260
+
261
+ it 'should pass an empty hash if no options given' do
262
+ Punch.should.receive(:entry) do |_, opts|
263
+ opts.should == {}
264
+ end
265
+ @punch.entry
266
+ end
267
+
268
+ it 'should return the value returned by the class method' do
269
+ @punch.entry.should == @entry
270
+ end
271
+
272
+ it 'should have clock as an alias' do
273
+ @punch.clock.should == @entry
274
+ end
275
+ end
276
+
223
277
  it 'should list the project data' do
224
278
  @punch.should.respond_to(:list)
225
279
  end
data/spec/punch_spec.rb CHANGED
@@ -990,6 +990,84 @@ describe Punch do
990
990
  end
991
991
  end
992
992
 
993
+ it 'should create a full punch entry' do
994
+ Punch.should.respond_to(:entry)
995
+ end
996
+
997
+ describe 'creating a full punch entry' do
998
+ before do
999
+ Punch.stub!(:in)
1000
+ Punch.stub!(:out)
1001
+
1002
+ @now = Time.now
1003
+ @from_time = @now - 1000
1004
+ @to_time = @now - 100
1005
+ @project = 'myproj'
1006
+ end
1007
+
1008
+ it 'should require a project name' do
1009
+ lambda { Punch.entry }.should.raise(ArgumentError)
1010
+ end
1011
+
1012
+ it 'should accept a project name and options' do
1013
+ lambda { Punch.entry('proj', :from => Time.now - 500, :to => Time.now - 20) }.should.not.raise(ArgumentError)
1014
+ end
1015
+
1016
+ it 'should require :from and :to options' do
1017
+ lambda { Punch.entry('proj') }.should.raise(ArgumentError)
1018
+ end
1019
+
1020
+ it 'should punch the project in with the given :from time' do
1021
+ Punch.should.receive(:in).with(@project, :time => @from_time)
1022
+ Punch.entry(@project, :from => @from_time, :to => @to_time)
1023
+ end
1024
+
1025
+ it 'should pass any given message when punching in' do
1026
+ msg = 'just some work'
1027
+ Punch.should.receive(:in).with(@project, :time => @from_time, :message => msg)
1028
+ Punch.entry(@project, :from => @from_time, :to => @to_time, :message => msg)
1029
+ end
1030
+
1031
+ describe 'when punching in is successful' do
1032
+ before do
1033
+ Punch.stub!(:in).and_return(true)
1034
+ end
1035
+
1036
+ it 'should punch the project out with the given :to time' do
1037
+ Punch.should.receive(:out).with(@project, :time => @to_time)
1038
+ Punch.entry(@project, :from => @from_time, :to => @to_time)
1039
+ end
1040
+
1041
+ it 'should return the result from punching out' do
1042
+ result = Object.new
1043
+ Punch.stub!(:out).and_return(result)
1044
+ Punch.entry(@project, :from => @from_time, :to => @to_time).should == result
1045
+ end
1046
+ end
1047
+
1048
+ describe 'when punching in is unsuccesful' do
1049
+ before do
1050
+ Punch.stub!(:in).and_return(false)
1051
+ end
1052
+
1053
+ it 'should not attempt the punch the project out' do
1054
+ Punch.should.receive(:out).never
1055
+ Punch.entry(@project, :from => @from_time, :to => @to_time)
1056
+ end
1057
+
1058
+ it 'should return false' do
1059
+ Punch.entry(@project, :from => @from_time, :to => @to_time).should == false
1060
+ end
1061
+ end
1062
+
1063
+ it 'should have .clock as an alias' do
1064
+ msg = 'just some work'
1065
+ Punch.should.receive(:in).with(@project, :time => @from_time, :message => msg).and_return(true)
1066
+ Punch.should.receive(:out).with(@project, :time => @to_time)
1067
+ Punch.clock(@project, :from => @from_time, :to => @to_time, :message => msg)
1068
+ end
1069
+ end
1070
+
993
1071
  it 'should delete a project' do
994
1072
  Punch.should.respond_to(:delete)
995
1073
  end
metadata CHANGED
@@ -1,57 +1,80 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: one_inch_punch
3
- version: !ruby/object:Gem::Version
4
- version: 0.5.1
3
+ version: !ruby/object:Gem::Version
4
+ hash: 7
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 6
9
+ - 0
10
+ version: 0.6.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Yossef Mendelssohn
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-03-19 00:00:00.000000000Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-04-10 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: bacon
16
- requirement: &2157947500 !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
17
24
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 19
29
+ segments:
30
+ - 1
31
+ - 1
32
+ - 0
21
33
  version: 1.1.0
22
34
  type: :development
23
- prerelease: false
24
- version_requirements: *2157947500
25
- - !ruby/object:Gem::Dependency
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
26
37
  name: facon
27
- requirement: &2157947000 !ruby/object:Gem::Requirement
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
28
40
  none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ hash: 11
45
+ segments:
46
+ - 0
47
+ - 5
48
+ - 0
32
49
  version: 0.5.0
33
50
  type: :development
34
- prerelease: false
35
- version_requirements: *2157947000
36
- - !ruby/object:Gem::Dependency
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
37
53
  name: timely
38
- requirement: &2157946540 !ruby/object:Gem::Requirement
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
39
56
  none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 29
61
+ segments:
62
+ - 0
63
+ - 0
64
+ - 1
43
65
  version: 0.0.1
44
66
  type: :runtime
45
- prerelease: false
46
- version_requirements: *2157946540
67
+ version_requirements: *id003
47
68
  description: A simple time-tracking tool, compatible with Ara T. Howard's punch gem.
48
- email:
69
+ email:
49
70
  - ymendel@pobox.com
50
- executables:
71
+ executables:
51
72
  - punch
52
73
  extensions: []
74
+
53
75
  extra_rdoc_files: []
54
- files:
76
+
77
+ files:
55
78
  - License.txt
56
79
  - History.txt
57
80
  - README.txt
@@ -68,26 +91,36 @@ files:
68
91
  - bin/punch
69
92
  homepage: http://github.com/ymendel/one_inch_punch/
70
93
  licenses: []
94
+
71
95
  post_install_message:
72
96
  rdoc_options: []
73
- require_paths:
97
+
98
+ require_paths:
74
99
  - lib
75
- required_ruby_version: !ruby/object:Gem::Requirement
100
+ required_ruby_version: !ruby/object:Gem::Requirement
76
101
  none: false
77
- requirements:
78
- - - ! '>='
79
- - !ruby/object:Gem::Version
80
- version: '0'
81
- required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ hash: 3
106
+ segments:
107
+ - 0
108
+ version: "0"
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
110
  none: false
83
- requirements:
84
- - - ! '>='
85
- - !ruby/object:Gem::Version
86
- version: '0'
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ hash: 3
115
+ segments:
116
+ - 0
117
+ version: "0"
87
118
  requirements: []
119
+
88
120
  rubyforge_project:
89
121
  rubygems_version: 1.8.10
90
122
  signing_key:
91
123
  specification_version: 3
92
124
  summary: Track your time locally.
93
125
  test_files: []
126
+