Skip to content

Commit

Permalink
Merge branch 'inout'
Browse files Browse the repository at this point in the history
  • Loading branch information
ymendel committed Apr 10, 2012
2 parents 1d5101d + 1d865eb commit 787d4e6
Show file tree
Hide file tree
Showing 6 changed files with 288 additions and 3 deletions.
16 changes: 16 additions & 0 deletions bin/punch
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ BANNER
"Restrict command to only on the given date") { |date| OPTIONS[:on] = Date.parse(date) }
opts.on('--at [TIME]', '--time [TIME]', String,
"Use the given time") { |time| OPTIONS[:time] = Time.parse(time) }
opts.on('--from [TIME]', String,
"Use the given time") { |time| OPTIONS[:from] = Time.parse(time) }
opts.on('--to [TIME]', String,
"Use the given time") { |time| OPTIONS[:to] = Time.parse(time) }
opts.on('-m', '--message [MESSAGE]', String,
"Use the given log message") { |message| OPTIONS[:message] = message }
opts.on('--full',
Expand Down Expand Up @@ -104,6 +108,17 @@ commands = {
puts message
end
end,
'entry' => lambda do |project|
if project
if Punch.entry(project, OPTIONS)
Punch.write
else
puts "Cannot create entry for '#{project}'"
end
else
puts "Project required"
end
end,
'log' => lambda do |project|
if project
if message = OPTIONS.delete(:message) || ARGV[2]
Expand Down Expand Up @@ -136,6 +151,7 @@ commands = {
end
end
}
commands['clock'] = commands['entry']

if command_code = commands[command]
command_code.call(project)
Expand Down
14 changes: 13 additions & 1 deletion lib/punch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,19 @@ def out(*args)
end
true
end


def entry(project, options = {})
raise ArgumentError, 'both :from and :to time are needed' unless options[:from] and options[:to]

in_options = { :time => options[:from] }
in_options[:message] = options[:message] if options[:message]
result = self.in(project, in_options)
return result unless result

out(project, :time => options[:to])
end
alias_method :clock, :entry

def delete(project)
return nil unless data.delete(project)
true
Expand Down
7 changes: 6 additions & 1 deletion lib/punch/instance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ def in(options = {})
def out(options = {})
self.class.out(project, options)
end


def entry(options = {})
self.class.entry(project, options)
end
alias_method :clock, :entry

def list(options = {})
self.class.list(project, options)
end
Expand Down
122 changes: 121 additions & 1 deletion spec/punch_command_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,127 @@ def run_command(*args)
end
end
end


describe "when the command is 'entry'" do
before do
Punch.stub!(:entry)
@from_option = '2012-04-10 14:39'
@to_option = '2012-04-10 17:43'
end

it 'should load punch data' do
Punch.should.receive(:load)
run_command('entry', @project)
end

it 'should make a punch entry for the given project' do
from_option = '2012-04-10 14:39'
from_time = Time.local(2012, 4, 10, 14, 39)
to_option = '2012-04-10 17:43'
to_time = Time.local(2012, 4, 10, 17, 43)

Punch.should.receive(:entry) do |proj, options|
proj.should == @project
options[:from].should == from_time
options[:to ].should == to_time
end

run_command('entry', @project, '--from', from_option, '--to', to_option)
end

it 'should pass a message if specified on the command line (with --message)' do
message = 'About to do some amazing work'

Punch.should.receive(:entry) do |proj, options|
proj.should == @project
options[:message].should == message
end

run_command('entry', @project, '--from', @from_option, '--to', @to_option, '--message', message)
end

it 'should pass a message if specified on the command line (with -m)' do
message = 'About to do some amazing work'

Punch.should.receive(:entry) do |proj, options|
proj.should == @project
options[:message].should == message
end

run_command('entry', @project, '--from', @from_option, '--to', @to_option, '-m', message)
end

describe 'when entry created successfully' do
before do
Punch.stub!(:entry).and_return(true)
end

it 'should write the data' do
Punch.should.receive(:write)
run_command('entry', @project, '--from', @from_option, '--to', @to_option)
end

it 'should not print anything' do
self.should.receive(:puts).never
run_command('entry', @project, '--from', @from_option, '--to', @to_option)
end
end

describe 'when entry not created successfully' do
before do
Punch.stub!(:entry).and_return(false)
end

it 'should not write the data' do
Punch.should.receive(:write).never
run_command('entry', @project, '--from', @from_option, '--to', @to_option)
end

it 'should print a message' do
self.should.receive(:puts) do |output|
output.should.match(/cannot.+entry/i)
end
run_command('entry', @project, '--from', @from_option, '--to', @to_option)
end
end

describe 'when no project given' do
it 'should display an error message' do
self.should.receive(:puts) do |output|
output.should.match(/project.+require/i)
end
run_command('entry')
end

it 'should not create an entry' do
Punch.stub!(:write)
Punch.should.receive(:entry).never
run_command('entry')
end

it 'should not write the data' do
Punch.should.receive(:write).never
run_command('entry')
end
end

it "should have 'clock' as an alias" do
from_option = '2012-04-10 14:39'
from_time = Time.local(2012, 4, 10, 14, 39)
to_option = '2012-04-10 17:43'
to_time = Time.local(2012, 4, 10, 17, 43)

Punch.should.receive(:entry) do |proj, options|
proj.should == @project
options[:from].should == from_time
options[:to ].should == to_time
end

run_command('clock', @project, '--from', from_option, '--to', to_option)
end

end

describe "when the command is 'delete'" do
before do
Punch.stub!(:delete)
Expand Down
54 changes: 54 additions & 0 deletions spec/punch_instance_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,60 @@
end
end

it 'should make a punch entry' do
@punch.should.respond_to(:entry)
end

describe 'making a punch entry' do
before do
@entry = 'entry val'
Punch.stub!(:entry).and_return(@entry)
end

it 'should accept options' do
lambda { @punch.entry(:time => Time.now) }.should.not.raise(ArgumentError)
end

it 'should not require options' do
lambda { @punch.entry }.should.not.raise(ArgumentError)
end

it 'should delegate to the class' do
Punch.should.receive(:entry)
@punch.entry
end

it 'should pass the project when delegating to the class' do
Punch.should.receive(:entry) do |proj, _|
proj.should == @project
end
@punch.entry
end

it 'should pass the options when delegating to the class' do
options = { :time => Time.now }
Punch.should.receive(:entry) do |_, opts|
opts.should == options
end
@punch.entry(options)
end

it 'should pass an empty hash if no options given' do
Punch.should.receive(:entry) do |_, opts|
opts.should == {}
end
@punch.entry
end

it 'should return the value returned by the class method' do
@punch.entry.should == @entry
end

it 'should have clock as an alias' do
@punch.clock.should == @entry
end
end

it 'should list the project data' do
@punch.should.respond_to(:list)
end
Expand Down
78 changes: 78 additions & 0 deletions spec/punch_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,84 @@ class << self
end
end

it 'should create a full punch entry' do
Punch.should.respond_to(:entry)
end

describe 'creating a full punch entry' do
before do
Punch.stub!(:in)
Punch.stub!(:out)

@now = Time.now
@from_time = @now - 1000
@to_time = @now - 100
@project = 'myproj'
end

it 'should require a project name' do
lambda { Punch.entry }.should.raise(ArgumentError)
end

it 'should accept a project name and options' do
lambda { Punch.entry('proj', :from => Time.now - 500, :to => Time.now - 20) }.should.not.raise(ArgumentError)
end

it 'should require :from and :to options' do
lambda { Punch.entry('proj') }.should.raise(ArgumentError)
end

it 'should punch the project in with the given :from time' do
Punch.should.receive(:in).with(@project, :time => @from_time)
Punch.entry(@project, :from => @from_time, :to => @to_time)
end

it 'should pass any given message when punching in' do
msg = 'just some work'
Punch.should.receive(:in).with(@project, :time => @from_time, :message => msg)
Punch.entry(@project, :from => @from_time, :to => @to_time, :message => msg)
end

describe 'when punching in is successful' do
before do
Punch.stub!(:in).and_return(true)
end

it 'should punch the project out with the given :to time' do
Punch.should.receive(:out).with(@project, :time => @to_time)
Punch.entry(@project, :from => @from_time, :to => @to_time)
end

it 'should return the result from punching out' do
result = Object.new
Punch.stub!(:out).and_return(result)
Punch.entry(@project, :from => @from_time, :to => @to_time).should == result
end
end

describe 'when punching in is unsuccesful' do
before do
Punch.stub!(:in).and_return(false)
end

it 'should not attempt the punch the project out' do
Punch.should.receive(:out).never
Punch.entry(@project, :from => @from_time, :to => @to_time)
end

it 'should return false' do
Punch.entry(@project, :from => @from_time, :to => @to_time).should == false
end
end

it 'should have .clock as an alias' do
msg = 'just some work'
Punch.should.receive(:in).with(@project, :time => @from_time, :message => msg).and_return(true)
Punch.should.receive(:out).with(@project, :time => @to_time)
Punch.clock(@project, :from => @from_time, :to => @to_time, :message => msg)
end
end

it 'should delete a project' do
Punch.should.respond_to(:delete)
end
Expand Down

0 comments on commit 787d4e6

Please sign in to comment.