one_inch_punch 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,424 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Punch do
4
+ it 'should load data' do
5
+ Punch.should respond_to(:load)
6
+ end
7
+
8
+ describe 'when loading data' do
9
+ before :each do
10
+ @data = <<-EOD
11
+ ---
12
+ rip:
13
+ - out: 2008-05-19T18:34:39.00-05:00
14
+ log:
15
+ - punch in @ 2008-05-19T17:09:05-05:00
16
+ - punch out @ 2008-05-19T18:34:39-05:00
17
+ total: "01:25:34"
18
+ in: 2008-05-19T17:09:05.00-05:00
19
+ - out: 2008-05-19T21:04:03.00-05:00
20
+ total: "00:50:22"
21
+ log:
22
+ - punch in @ 2008-05-19T20:13:41-05:00
23
+ - punch out @ 2008-05-19T21:04:03-05:00
24
+ in: 2008-05-19T20:13:41.00-05:00
25
+ ps:
26
+ - out: 2008-05-19T12:18:52.00-05:00
27
+ log:
28
+ - punch in @ 2008-05-19T11:23:35-05:00
29
+ - punch out @ 2008-05-19T12:18:52-05:00
30
+ total: "00:55:17"
31
+ in: 2008-05-19T11:23:35.00-05:00
32
+ EOD
33
+ File.stubs(:read).returns(@data)
34
+
35
+ Punch.instance_eval do
36
+ class << self
37
+ public :data
38
+ end
39
+ end
40
+
41
+ Punch.reset
42
+ end
43
+
44
+ it 'should read the ~/.punch.yml file' do
45
+ File.expects(:read).with(File.expand_path('~/.punch.yml')).returns(@data)
46
+ Punch.load
47
+ end
48
+
49
+ describe 'when the file is found' do
50
+ it 'should load the data as yaml' do
51
+ Punch.load
52
+ Punch.data.should == YAML.load(@data)
53
+ end
54
+
55
+ it 'should return true' do
56
+ Punch.load.should == true
57
+ end
58
+ end
59
+
60
+ describe 'when no file is found' do
61
+ before :each do
62
+ File.stubs(:read).raises(Errno::ENOENT)
63
+ end
64
+
65
+ it 'should leave the data blank' do
66
+ Punch.load
67
+ Punch.data.should be_nil
68
+ end
69
+
70
+ it 'should return false' do
71
+ Punch.load.should == false
72
+ end
73
+ end
74
+ end
75
+
76
+ it 'should reset itself' do
77
+ Punch.should respond_to(:reset)
78
+ end
79
+
80
+ describe 'when resetting itself' do
81
+ before :each do
82
+ Punch.instance_eval do
83
+ class << self
84
+ public :data, :data=
85
+ end
86
+ end
87
+ end
88
+
89
+ it 'should set its data to nil' do
90
+ Punch.data = { 'proj' => 'lots of stuff here' }
91
+ Punch.reset
92
+ Punch.data.should be_nil
93
+ end
94
+ end
95
+
96
+ it 'should write data' do
97
+ Punch.should respond_to(:write)
98
+ end
99
+
100
+ describe 'when writing data' do
101
+ before :each do
102
+ @file = stub('file')
103
+ File.stubs(:open).yields(@file)
104
+ @data = { 'proj' => 'data goes here' }
105
+
106
+ Punch.instance_eval do
107
+ class << self
108
+ public :data=
109
+ end
110
+ end
111
+ Punch.data = @data
112
+ end
113
+
114
+ it 'should open the data file for writing' do
115
+ File.expects(:open).with(File.expand_path('~/.punch.yml'), 'w')
116
+ Punch.write
117
+ end
118
+
119
+ it 'should write the data to the file in YAML form' do
120
+ @file.expects(:puts).with(@data.to_yaml)
121
+ Punch.write
122
+ end
123
+ end
124
+
125
+ it "should give a project's status" do
126
+ Punch.should respond_to(:status)
127
+ end
128
+
129
+ describe "giving a project's status" do
130
+ before :each do
131
+ @now = Time.now
132
+ @projects = { 'out' => 'test-o', 'in' => 'testshank' }
133
+ @data = {
134
+ @projects['out'] => [ { 'in' => @now, 'out' => @now + 12 } ],
135
+ @projects['in'] => [ { 'in' => @now } ]
136
+ }
137
+
138
+ Punch.instance_eval do
139
+ class << self
140
+ public :data=
141
+ end
142
+ end
143
+ Punch.data = @data
144
+ end
145
+
146
+ it 'should accept a project name' do
147
+ lambda { Punch.status('proj') }.should_not raise_error(ArgumentError)
148
+ end
149
+
150
+ it 'should require a project name' do
151
+ lambda { Punch.status }.should raise_error(ArgumentError)
152
+ end
153
+
154
+ it "should return 'out' if the project is currently punched out" do
155
+ Punch.status(@projects['out']).should == 'out'
156
+ end
157
+
158
+ it "should return 'in' if the project is currently punched in" do
159
+ Punch.status(@projects['in']).should == 'in'
160
+ end
161
+
162
+ it 'should return nil if the project does not exist' do
163
+ Punch.status('other project').should be_nil
164
+ end
165
+
166
+ it 'should return nil if the project has no time data' do
167
+ project = 'empty project'
168
+ @data[project] = []
169
+ Punch.data = @data
170
+ Punch.status(project).should be_nil
171
+ end
172
+
173
+ it 'should use the last time entry for the status' do
174
+ @data[@projects['out']].unshift *[{ 'in' => @now - 100 }, { 'in' => @now - 90, 'out' => @now - 50 }]
175
+ @data[@projects['in']].unshift *[{ 'in' => @now - 100, 'out' => @now - 90 }, { 'in' => @now - 50 }]
176
+ Punch.data = @data
177
+
178
+ Punch.status(@projects['out']).should == 'out'
179
+ Punch.status(@projects['in']).should == 'in'
180
+ end
181
+ end
182
+
183
+ it 'should indicate whether a project is punched out' do
184
+ Punch.should respond_to(:out?)
185
+ end
186
+
187
+ describe 'indicating whether a project is punched out' do
188
+ before :each do
189
+ @project = 'testola'
190
+ end
191
+
192
+ it 'should accept a project name' do
193
+ lambda { Punch.out?('proj') }.should_not raise_error(ArgumentError)
194
+ end
195
+
196
+ it 'should require a project name' do
197
+ lambda { Punch.out? }.should raise_error(ArgumentError)
198
+ end
199
+
200
+ it "should get the project's status" do
201
+ Punch.expects(:status).with(@project)
202
+ Punch.out?(@project)
203
+ end
204
+
205
+ it "should return true if the project's status is 'out'" do
206
+ Punch.stubs(:status).returns('out')
207
+ Punch.out?(@project).should == true
208
+ end
209
+
210
+ it "should return false if the project's status is 'in'" do
211
+ Punch.stubs(:status).returns('in')
212
+ Punch.out?(@project).should == false
213
+ end
214
+
215
+ it "should return true if the project's status is nil" do
216
+ Punch.stubs(:status).returns(nil)
217
+ Punch.out?(@project).should == true
218
+ end
219
+ end
220
+
221
+ it 'should indicate whether a project is punched in' do
222
+ Punch.should respond_to(:in?)
223
+ end
224
+
225
+ describe 'indicating whether a project is punched in' do
226
+ before :each do
227
+ @project = 'testola'
228
+ end
229
+
230
+ it 'should accept a project name' do
231
+ lambda { Punch.in?('proj') }.should_not raise_error(ArgumentError)
232
+ end
233
+
234
+ it 'should require a project name' do
235
+ lambda { Punch.in? }.should raise_error(ArgumentError)
236
+ end
237
+
238
+ it "should get the project's status" do
239
+ Punch.expects(:status).with(@project)
240
+ Punch.in?(@project)
241
+ end
242
+
243
+ it "should return false if the project's status is 'out'" do
244
+ Punch.stubs(:status).returns('out')
245
+ Punch.in?(@project).should == false
246
+ end
247
+
248
+ it "should return true if the project's status is 'in'" do
249
+ Punch.stubs(:status).returns('in')
250
+ Punch.in?(@project).should == true
251
+ end
252
+
253
+ it "should return false if the project's status is nil" do
254
+ Punch.stubs(:status).returns(nil)
255
+ Punch.in?(@project).should == false
256
+ end
257
+ end
258
+
259
+ it 'should punch a project in' do
260
+ Punch.should respond_to(:in)
261
+ end
262
+
263
+ describe 'punching a project in' do
264
+ before :each do
265
+ @now = Time.now
266
+ Time.stubs(:now).returns(@now)
267
+ @project = 'test project'
268
+ @data = { @project => [ {'in' => @now - 50, 'out' => @now - 25} ] }
269
+
270
+ Punch.instance_eval do
271
+ class << self
272
+ public :data, :data=
273
+ end
274
+ end
275
+ Punch.data = @data
276
+
277
+ @test = states('test').starts_as('setup')
278
+ Punch.stubs(:write).when(@test.is('setup'))
279
+ end
280
+
281
+ it 'should accept a project name' do
282
+ lambda { Punch.in('proj') }.should_not raise_error(ArgumentError)
283
+ end
284
+
285
+ it 'should require a project name' do
286
+ lambda { Punch.in }.should raise_error(ArgumentError)
287
+ end
288
+
289
+ it 'should check whether the project is already punched in' do
290
+ Punch.expects(:in?).with(@project)
291
+ Punch.in(@project)
292
+ end
293
+
294
+ describe 'when the project is already punched in' do
295
+ before :each do
296
+ Punch.stubs(:in?).returns(true)
297
+ end
298
+
299
+ it 'should not change the project data' do
300
+ Punch.in(@project)
301
+ Punch.data.should == @data
302
+ end
303
+
304
+ it 'should not write the data' do
305
+ @test.become('test')
306
+ Punch.expects(:write).never.when(@test.is('test'))
307
+ Punch.in(@project)
308
+ end
309
+
310
+ it 'should return false' do
311
+ Punch.in(@project).should == false
312
+ end
313
+ end
314
+
315
+ describe 'when the project is not already punched in' do
316
+ before :each do
317
+ Punch.stubs(:in?).returns(false)
318
+ end
319
+
320
+ it 'should add a time entry to the project data' do
321
+ Punch.in(@project)
322
+ Punch.data[@project].length.should == 2
323
+ end
324
+
325
+ it 'should use now for the punch-in time' do
326
+ Punch.in(@project)
327
+ Punch.data[@project].last['in'].should == @now
328
+ end
329
+
330
+ it 'should write the data' do
331
+ @test.become('test')
332
+ Punch.expects(:write).when(@test.is('test'))
333
+ Punch.in(@project)
334
+ end
335
+
336
+ it 'should return true' do
337
+ Punch.in(@project).should == true
338
+ end
339
+ end
340
+ end
341
+
342
+ it 'should punch a project out' do
343
+ Punch.should respond_to(:out)
344
+ end
345
+
346
+ describe 'punching a project out' do
347
+ before :each do
348
+ @now = Time.now
349
+ Time.stubs(:now).returns(@now)
350
+ @project = 'test project'
351
+ @data = { @project => [ {'in' => @now - 50, 'out' => @now - 25} ] }
352
+
353
+ Punch.instance_eval do
354
+ class << self
355
+ public :data, :data=
356
+ end
357
+ end
358
+ Punch.data = @data
359
+
360
+ @test = states('test').starts_as('setup')
361
+ Punch.stubs(:write).when(@test.is('setup'))
362
+ end
363
+
364
+ it 'should accept a project name' do
365
+ lambda { Punch.out('proj') }.should_not raise_error(ArgumentError)
366
+ end
367
+
368
+ it 'should require a project name' do
369
+ lambda { Punch.out }.should raise_error(ArgumentError)
370
+ end
371
+
372
+ it 'should check whether the project is already punched out' do
373
+ Punch.expects(:out?).with(@project)
374
+ Punch.out(@project)
375
+ end
376
+
377
+ describe 'when the project is already punched out' do
378
+ before :each do
379
+ Punch.stubs(:out?).returns(true)
380
+ end
381
+
382
+ it 'should not change the project data' do
383
+ Punch.out(@project)
384
+ Punch.data.should == @data
385
+ end
386
+
387
+ it 'should not write the data' do
388
+ @test.become('test')
389
+ Punch.expects(:write).never.when(@test.is('test'))
390
+ Punch.out(@project)
391
+ end
392
+
393
+ it 'should return false' do
394
+ Punch.out(@project).should == false
395
+ end
396
+ end
397
+
398
+ describe 'when the project is not already punched out' do
399
+ before :each do
400
+ Punch.stubs(:out?).returns(false)
401
+ end
402
+
403
+ it 'should not add a time entry to the project data' do
404
+ Punch.out(@project)
405
+ Punch.data[@project].length.should == 1
406
+ end
407
+
408
+ it 'should use now for the punch-out time' do
409
+ Punch.out(@project)
410
+ Punch.data[@project].last['out'].should == @now
411
+ end
412
+
413
+ it 'should write the data' do
414
+ @test.become('test')
415
+ Punch.expects(:write).when(@test.is('test'))
416
+ Punch.out(@project)
417
+ end
418
+
419
+ it 'should return true' do
420
+ Punch.out(@project).should == true
421
+ end
422
+ end
423
+ end
424
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,23 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ # this is my favorite way to require ever
10
+ begin
11
+ require 'mocha'
12
+ rescue LoadError
13
+ require 'rubygems'
14
+ gem 'mocha'
15
+ require 'mocha'
16
+ end
17
+
18
+ Spec::Runner.configure do |config|
19
+ config.mock_with :mocha
20
+ end
21
+
22
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
23
+ require 'punch'
@@ -0,0 +1,34 @@
1
+ desc 'Release the website and new gem version'
2
+ task :deploy => [:check_version, :website, :release] do
3
+ puts "Remember to create SVN tag:"
4
+ puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
5
+ "svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
6
+ puts "Suggested comment:"
7
+ puts "Tagging release #{CHANGES}"
8
+ end
9
+
10
+ desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
11
+ task :local_deploy => [:website_generate, :install_gem]
12
+
13
+ task :check_version do
14
+ unless ENV['VERSION']
15
+ puts 'Must pass a VERSION=x.y.z release version'
16
+ exit
17
+ end
18
+ unless ENV['VERSION'] == VERS
19
+ puts "Please update your version.rb to match the release version, currently #{VERS}"
20
+ exit
21
+ end
22
+ end
23
+
24
+ desc 'Install the package as a gem, without generating documentation(ri/rdoc)'
25
+ task :install_gem_no_doc => [:clean, :package] do
26
+ sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri"
27
+ end
28
+
29
+ namespace :manifest do
30
+ desc 'Recreate Manifest.txt to include ALL files'
31
+ task :refresh do
32
+ `rake check_manifest | patch -p0 > Manifest.txt`
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ task :ruby_env do
2
+ RUBY_APP = if RUBY_PLATFORM =~ /java/
3
+ "jruby"
4
+ else
5
+ "ruby"
6
+ end unless defined? RUBY_APP
7
+ end
data/tasks/rspec.rake ADDED
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
@@ -0,0 +1,9 @@
1
+ # stubs for the website generation
2
+ # To install the website framework:
3
+ # script/generate website
4
+
5
+ task :website_generate
6
+
7
+ task :website_upload
8
+
9
+ task :website => :publish_docs
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: one_inch_punch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Yossef Mendelssohn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-08-18 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.7.0
24
+ version:
25
+ description: a simple time-tracking tool
26
+ email:
27
+ - ymendel@pobox.com
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - History.txt
34
+ - License.txt
35
+ - Manifest.txt
36
+ - README.txt
37
+ files:
38
+ - History.txt
39
+ - License.txt
40
+ - Manifest.txt
41
+ - README.txt
42
+ - Rakefile
43
+ - config/hoe.rb
44
+ - config/requirements.rb
45
+ - lib/punch.rb
46
+ - lib/punch/version.rb
47
+ - script/console
48
+ - script/destroy
49
+ - script/generate
50
+ - setup.rb
51
+ - spec/punch_spec.rb
52
+ - spec/spec.opts
53
+ - spec/spec_helper.rb
54
+ - tasks/deployment.rake
55
+ - tasks/environment.rake
56
+ - tasks/rspec.rake
57
+ - tasks/website.rake
58
+ has_rdoc: true
59
+ homepage: http://yomendel.rubyforge.org
60
+ post_install_message: ""
61
+ rdoc_options:
62
+ - --main
63
+ - README.txt
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ version:
78
+ requirements: []
79
+
80
+ rubyforge_project: yomendel
81
+ rubygems_version: 1.2.0
82
+ signing_key:
83
+ specification_version: 2
84
+ summary: a simple time-tracking tool
85
+ test_files: []
86
+