Pratt 1.6.8-x86-linux
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/.exrc +61 -0
- data/.gitignore +6 -0
- data/History.txt +6 -0
- data/Manifest.txt +46 -0
- data/Pratt.gemspec +173 -0
- data/Pratt.mm +1867 -0
- data/README.txt +67 -0
- data/Rakefile +96 -0
- data/TODO +56 -0
- data/VERSION +1 -0
- data/bin/pratt +13 -0
- data/config.rb +19 -0
- data/db/sqlite_databases_go_here +0 -0
- data/db/zips.csv.zip +0 -0
- data/lib/models.rb +8 -0
- data/lib/pratt.rb +308 -0
- data/lib/pratt/core_ext.rb +6 -0
- data/lib/pratt/core_ext/array.rb +20 -0
- data/lib/pratt/core_ext/float.rb +29 -0
- data/lib/pratt/core_ext/nil.rb +5 -0
- data/lib/pratt/core_ext/numeric.rb +9 -0
- data/lib/pratt/core_ext/string.rb +31 -0
- data/lib/pratt/core_ext/time.rb +20 -0
- data/lib/pratt/dialogs.rb +81 -0
- data/lib/pratt/formatting.rb +19 -0
- data/lib/pratt/project_actions.rb +25 -0
- data/lib/pratt/reports.rb +140 -0
- data/models/app.rb +39 -0
- data/models/customer.rb +50 -0
- data/models/invoice.rb +28 -0
- data/models/invoice_whence.rb +18 -0
- data/models/payment.rb +22 -0
- data/models/pratt.rb +15 -0
- data/models/project.rb +89 -0
- data/models/whence.rb +77 -0
- data/models/zip.rb +27 -0
- data/pratt.mm +1875 -0
- data/spec/app_spec.rb +48 -0
- data/spec/array_spec.rb +24 -0
- data/spec/customer_spec.rb +31 -0
- data/spec/fixtures/empty_graph.expectation +8 -0
- data/spec/fixtures/graph.expectation +13 -0
- data/spec/fixtures/proportions.expectation +4 -0
- data/spec/float_spec.rb +24 -0
- data/spec/formatting_spec.rb +7 -0
- data/spec/money_spec.rb +9 -0
- data/spec/nil_class_spec.rb +8 -0
- data/spec/numeric_spec.rb +30 -0
- data/spec/payment_spec.rb +19 -0
- data/spec/pratt_spec.rb +106 -0
- data/spec/project_spec.rb +182 -0
- data/spec/rcov.opts +0 -0
- data/spec/report_action_spec.rb +83 -0
- data/spec/report_spec.rb +205 -0
- data/spec/seed_data.rb +33 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/string_ext_spec.rb +33 -0
- data/spec/whence_spec.rb +54 -0
- data/tasks/pratt.rb +87 -0
- data/templates/model.eruby +12 -0
- data/templates/spec.eruby +8 -0
- data/views/current.eruby +5 -0
- data/views/general-invoice.eruby +538 -0
- data/views/graph.eruby +16 -0
- data/views/invoice.eruby +148 -0
- data/views/main.rb +90 -0
- data/views/pid.eruby +3 -0
- data/views/pop.rb +78 -0
- data/views/proportions.eruby +4 -0
- data/views/raw.eruby +11 -0
- metadata +275 -0
data/spec/app_spec.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe App do
|
4
|
+
context "instances" do
|
5
|
+
it "should only have one" do
|
6
|
+
App.last.should_not be_nil
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have log" do
|
10
|
+
@app = App.last
|
11
|
+
@app.expects(:log).with('pop').returns(@app)
|
12
|
+
@app.log 'pop'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should say it has something logged" do
|
16
|
+
@app = App.new
|
17
|
+
@app.gui?('main').should be_false
|
18
|
+
@app.gui?('pop').should be_false
|
19
|
+
|
20
|
+
@app.gui = 'main'
|
21
|
+
@app.gui?('main').should be_true
|
22
|
+
|
23
|
+
@app.gui = 'pop'
|
24
|
+
@app.gui?('main').should be_false
|
25
|
+
|
26
|
+
@app.gui = 'pop'
|
27
|
+
@app.gui?('pop').should be_true
|
28
|
+
|
29
|
+
@app.gui = 'pop'
|
30
|
+
@app.gui?('bob').should be_false
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should remove the gui when expected" do
|
34
|
+
@app = App.create :gui => 'pop'
|
35
|
+
|
36
|
+
@app.gui?('pop').should be_true
|
37
|
+
@app.unlock
|
38
|
+
@app.gui?('pop').should be_false
|
39
|
+
|
40
|
+
@app.gui = 'main'
|
41
|
+
@app.save
|
42
|
+
@app.gui?('pop').should be_false
|
43
|
+
@app.gui?('main').should be_true
|
44
|
+
|
45
|
+
@app.destroy
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/spec/array_spec.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pratt'
|
3
|
+
|
4
|
+
describe Array do
|
5
|
+
it "to_sentence concatenates each element correctly with no elements" do
|
6
|
+
[].to_sentence.should eql('')
|
7
|
+
end
|
8
|
+
|
9
|
+
it "to_sentence concatenates each element correctly with one element" do
|
10
|
+
%w(a).to_sentence.should eql('a')
|
11
|
+
end
|
12
|
+
|
13
|
+
it "to_sentence concatenates each element correctly with two elements" do
|
14
|
+
%w(a b).to_sentence.should eql('a and b')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "to_sentence concatenates each element correctly with >= three elements" do
|
18
|
+
%w(a b c d).to_sentence.should eql('a, b, c, and d')
|
19
|
+
end
|
20
|
+
|
21
|
+
it "to_sentence concatenates each element correctly with >= three elements and a different conjunction" do
|
22
|
+
%w(a b c d).to_sentence('&').should eql('a, b, c, & d')
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pratt'
|
3
|
+
|
4
|
+
describe Customer do
|
5
|
+
it_should_behave_like "being a billable item"
|
6
|
+
|
7
|
+
describe "instance" do
|
8
|
+
before :each do
|
9
|
+
@customer = Customer.create :name => "frogstarr78", :address => '312 NW 7th', :zip => '97862'
|
10
|
+
end
|
11
|
+
|
12
|
+
after :each do
|
13
|
+
Customer.find_by_name('frogstarr78').destroy
|
14
|
+
end
|
15
|
+
|
16
|
+
it "responds to :projects" do
|
17
|
+
Customer.new.should respond_to(:projects)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "responds to :payment" do
|
21
|
+
Customer.new.should respond_to(:payment)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "calculates amount correctly" do
|
25
|
+
payment = mock('payment')
|
26
|
+
payment.expects(:rate).once.returns(31500)
|
27
|
+
@customer.expects(:payment).once.returns(payment)
|
28
|
+
@customer.amount.should == 315.0
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Project detail
|
2
|
+
by week from
|
3
|
+
Mon 00:00:00 Sep 28 2009 to Sun 23:59:59 Oct 04 2009
|
4
|
+
dys hrs min total
|
5
|
+
-------------------------------------------------------------------
|
6
|
+
|
7
|
+
Lunch/Break | 00 day 01 hour 21 min 1.35
|
8
|
+
Task1 | 00 day 01 hour 03 min 1.07
|
9
|
+
Task2 | 00 day 00 hour 58 min 0.97
|
10
|
+
Another Task | 00 day 00 hour 05 min 0.08
|
11
|
+
Task3 | 01 day 17 hour 31 min 41.53
|
12
|
+
|
13
|
+
-------------------------------------------------------------------
|
data/spec/float_spec.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pratt'
|
3
|
+
|
4
|
+
describe Float do
|
5
|
+
it { 2.0.should respond_to(:format_integer) }
|
6
|
+
it { 2.0.should respond_to(:percentage) }
|
7
|
+
|
8
|
+
it "should format correctly" do
|
9
|
+
2.0.format_integer.should eql("02")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "shows percentage correctly with no total" do
|
13
|
+
2.3.percentage.should eql("230.00%")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "shows percentage correctly with total" do
|
17
|
+
2.5.percentage(5).should eql("50.00%")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "handles with_label as expected" do
|
21
|
+
Project.expects(:longest_project_name).returns 21
|
22
|
+
3.5.with_label("label").should eql(" label 3.5")
|
23
|
+
end
|
24
|
+
end
|
data/spec/money_spec.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pratt'
|
3
|
+
|
4
|
+
describe Numeric do
|
5
|
+
it { 1.should respond_to(:format_integer) }
|
6
|
+
it { 1.should respond_to(:with_label) }
|
7
|
+
|
8
|
+
it "should format correctly" do
|
9
|
+
Pratt.color = false
|
10
|
+
1.format_integer.should eql("01")
|
11
|
+
end
|
12
|
+
|
13
|
+
it '"format" with with_label' do
|
14
|
+
Pratt.color = false
|
15
|
+
Project.expects(:longest_project_name).returns(11)
|
16
|
+
1.with_label(:blue).should eql(" blue 1")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "recursively applies formatting without color" do
|
20
|
+
Pratt.color = false
|
21
|
+
Project.expects(:longest_project_name).returns(11)
|
22
|
+
1.format_integer.blue.with_label("#").should eql(" # 01")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "recursively applies formatting with color" do
|
26
|
+
Pratt.color = true
|
27
|
+
Project.expects(:longest_project_name).returns(11)
|
28
|
+
1.format_integer.blue.with_label("#").should eql(" # \e[34m01\e[0m")
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pratt'
|
3
|
+
|
4
|
+
describe Payment do
|
5
|
+
describe "instances" do
|
6
|
+
before :each do
|
7
|
+
@payment = Payment.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "responds to :pretty_print" do
|
11
|
+
@payment.should respond_to(:pretty_print)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "pretty_print is the expected format " do
|
15
|
+
@payment.rate = '100'
|
16
|
+
@payment.pretty_print.should == '$1.00'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/spec/pratt_spec.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'pratt'
|
3
|
+
|
4
|
+
describe Pratt do
|
5
|
+
before :each do
|
6
|
+
@pratt = Pratt.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should act like an array" do
|
10
|
+
@pratt.should respond_to(:<<)
|
11
|
+
lambda {
|
12
|
+
@pratt << :this
|
13
|
+
}.should change(@pratt.todo, :size).by(1)
|
14
|
+
@pratt.todo.should == [:this]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "correctly report i_should?" do
|
18
|
+
@pratt.send(:i_should?, :this).should be_false
|
19
|
+
@pratt << :this
|
20
|
+
@pratt.send(:i_should?, :this).should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should start a new project when calling begin" do
|
24
|
+
@pratt.project = mock('Refactor')
|
25
|
+
@pratt.when_to = Time.now
|
26
|
+
@pratt.project.expects(:start!).with(@pratt.when_to)
|
27
|
+
|
28
|
+
@pratt.begin
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should allow project to be set by object" do
|
32
|
+
primary = Project.new :name => 'project', :weight => 1
|
33
|
+
Project.expects(:find_or_create_by_name).never
|
34
|
+
@pratt.project = primary
|
35
|
+
@pratt.project.should == primary
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should allow project to be set by a string" do
|
39
|
+
Project.expects(:find_or_create_by_name).with( { :name => 'Refactor' } )
|
40
|
+
@pratt.project = 'Refactor'
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "color" do
|
44
|
+
|
45
|
+
it "should color when expected" do
|
46
|
+
Pratt.color = true
|
47
|
+
'this'.red.should == 'this'.red
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should not color when not expected" do
|
51
|
+
Pratt.color = false
|
52
|
+
'this'.red.should == 'this'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "\b#root" do
|
57
|
+
before :each do
|
58
|
+
@expected_root = File.dirname( File.expand_path( '..', __FILE__ ) ).to_s
|
59
|
+
Dir.stubs(:pwd).returns(@expected_root)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "is correct without arguments" do
|
63
|
+
Pratt.root.should == [Pathname.new(@expected_root)]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "is correct with a block but no argument" do
|
67
|
+
received = []
|
68
|
+
Pratt.root {|model| received << model }
|
69
|
+
received.should == [Pathname.new(@expected_root)]
|
70
|
+
end
|
71
|
+
|
72
|
+
it "is correct with an argument but no block" do
|
73
|
+
Pratt.root('models').should == [Pathname.new(File.join(@expected_root, "models"))]
|
74
|
+
end
|
75
|
+
|
76
|
+
it "is correct with an argument and block" do
|
77
|
+
received = []
|
78
|
+
expected = %w(app.rb customer.rb project.rb payment.rb pratt.rb whence.rb invoice.rb invoice_whence.rb zip.rb)
|
79
|
+
Pratt.root('models', '*.rb') {|model| received << model }
|
80
|
+
received.to_set.should == expected.collect {|model| Pathname.new File.join(@expected_root, "models", model) }.to_set
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "parse" do
|
85
|
+
# do
|
86
|
+
## Pratt.expects(:connect).with('staging')
|
87
|
+
## lambda {
|
88
|
+
# Pratt.parse %w(--env staging)
|
89
|
+
## }.should change(ENV['PRATT_ENV']).from('test').to('staging')
|
90
|
+
# ENV['PRATT_ENV'].should == 'staging'
|
91
|
+
# end
|
92
|
+
|
93
|
+
it "inits an irb console when given console argument" do
|
94
|
+
Pratt.any_instance.stubs(:i_should?).returns false
|
95
|
+
# ^ to bypass actually calling the code
|
96
|
+
Pratt.any_instance.expects(:<<).with(:console)
|
97
|
+
Pratt.parse %w(console)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should start IRB when console method is called" do
|
102
|
+
ARGV.expects(:clear)
|
103
|
+
IRB.expects(:start)
|
104
|
+
@pratt.console
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# enable laziness
|
4
|
+
class Mocha::Mock
|
5
|
+
def name
|
6
|
+
@name.instance_variable_get("@name")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe Project do
|
11
|
+
it_should_behave_like "being a billable item"
|
12
|
+
|
13
|
+
it{ Project.should respond_to(:primary) }
|
14
|
+
it{ Project.should respond_to(:off) }
|
15
|
+
it{ Project.should respond_to(:rest) }
|
16
|
+
it{ Project.should respond_to(:longest_project_name) }
|
17
|
+
|
18
|
+
context "scopes" do
|
19
|
+
it "named primary" do
|
20
|
+
Project.expects(:first).with(:conditions => { :weight => 1 }).returns(mock('Refactor'))
|
21
|
+
Project.primary.name.should == 'Refactor'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "named off" do
|
25
|
+
Project.expects(:first).with(:conditions => { :name => 'Lunch/Break' }).returns(mock('Lunch/Break'))
|
26
|
+
Project.off.name.should == 'Lunch/Break'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "named rest" do
|
30
|
+
prim = mock('Refactor')
|
31
|
+
off = mock('Lunch/Break')
|
32
|
+
other = mock('Other')
|
33
|
+
|
34
|
+
Project.expects(:primary).returns prim
|
35
|
+
Project.expects(:off).returns off
|
36
|
+
Project.expects(:all).returns([prim, off, other])
|
37
|
+
Project.rest.should == [other]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "named named" do
|
41
|
+
Project.expects(:first).with(:conditions => { :name => 'Refactor' }).returns(mock('Refactor'))
|
42
|
+
Project.named('Refactor').name.should == 'Refactor'
|
43
|
+
|
44
|
+
Project.expects(:named).with(nil).returns nil
|
45
|
+
Project.named(nil).should be_nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "instances" do
|
50
|
+
include SeedData
|
51
|
+
|
52
|
+
before :each do
|
53
|
+
load_seed_data
|
54
|
+
@project = Project.primary
|
55
|
+
@log_count = @project.whences.size
|
56
|
+
end
|
57
|
+
|
58
|
+
after :each do
|
59
|
+
@project.whences.destroy_all
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should correctly log entries using start! and stop!" do
|
63
|
+
lambda {
|
64
|
+
@project.start!
|
65
|
+
}.should change(@project.whences, :count).by(1)
|
66
|
+
@project.whences.last.end_at.should be_nil
|
67
|
+
|
68
|
+
sleep 1
|
69
|
+
lambda {
|
70
|
+
@project.stop!
|
71
|
+
}.should_not change(@project.whences, :count)
|
72
|
+
@project.should be_valid
|
73
|
+
@project.whences.reload
|
74
|
+
@project.whences.last.end_at.should > @project.whences.last.start_at
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should log correct time if given (not the default)" do
|
78
|
+
lambda {
|
79
|
+
@project.start!
|
80
|
+
}.should change(@project.whences, :count).by(1)
|
81
|
+
@project.whences.last.end_at.should be_nil
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should do nothing if attempting to start a project when there is one that has not been finished" do
|
85
|
+
@project.start!
|
86
|
+
@project.reload
|
87
|
+
|
88
|
+
$stdout.expects(:puts).with "Unable to start a new Project when there is an existing project #{@project.name} that hasn't been finished"
|
89
|
+
lambda {
|
90
|
+
@project.start!
|
91
|
+
}.should_not change(@project.whences, :count)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should do nothing if attempting to stop a project that hasn't been started" do
|
95
|
+
lambda {
|
96
|
+
@project.stop!
|
97
|
+
}.should_not change(@project.whences, :count)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should stop! then start! when calling restart!" do
|
101
|
+
@project.start!
|
102
|
+
first_started_id = @project.whences.last.id
|
103
|
+
|
104
|
+
lambda {
|
105
|
+
@project.restart!
|
106
|
+
}.should change(@project.whences, :count).by(1)
|
107
|
+
@project.whences.last.end_at.should be_nil
|
108
|
+
@project.whences.last.id.should_not == first_started_id
|
109
|
+
end
|
110
|
+
|
111
|
+
it "has a customer association" do
|
112
|
+
@project.should respond_to(:customer)
|
113
|
+
end
|
114
|
+
|
115
|
+
context "amount calculation" do
|
116
|
+
before :each do
|
117
|
+
Payment.create :rate => '315.0', :billable => @project
|
118
|
+
|
119
|
+
@now = Time.parse("2009-10-04 17:53:58")
|
120
|
+
Time.stubs(:now).returns(@now.beginning_of_week)
|
121
|
+
|
122
|
+
whence = Time.now-1.day
|
123
|
+
@project.start! whence
|
124
|
+
@project.stop! whence+3.hours
|
125
|
+
|
126
|
+
whence = Time.now
|
127
|
+
@project.start! whence
|
128
|
+
@project.stop! whence+3.hours
|
129
|
+
|
130
|
+
@project.reload
|
131
|
+
end
|
132
|
+
|
133
|
+
it "is correct with no arguments" do
|
134
|
+
@project.amount(@project.time_spent).should == 6*3.15
|
135
|
+
end
|
136
|
+
|
137
|
+
it "is correct with a scale" do
|
138
|
+
@project.amount(@project.time_spent(:month)).should == 6*3.15
|
139
|
+
end
|
140
|
+
|
141
|
+
it "is correct with a scale and time" do
|
142
|
+
@project.amount(@project.time_spent(:week, @now)).should == 3*3.15
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "time_spent" do
|
148
|
+
before :each do
|
149
|
+
@project = Project.new
|
150
|
+
end
|
151
|
+
|
152
|
+
it "correctly calculates with no data" do
|
153
|
+
@project.expects(:time_spent).returns 0
|
154
|
+
@project.time_spent.should == 0.0
|
155
|
+
end
|
156
|
+
|
157
|
+
it "correctly calculates with time argument" do
|
158
|
+
now = Time.now.beginning_of_day
|
159
|
+
Whence.expects(:find).returns [mock('whence1', :start_at => now, :end_at => now+=1.hour), mock('whence2', :start_at => now+=2.hours, :end_at => now+=2.hour+30.minutes)]
|
160
|
+
@project.time_spent.should == 3.5
|
161
|
+
end
|
162
|
+
|
163
|
+
it "correctly calculates with string time argument" do
|
164
|
+
whence = mock('whence', :start_at => Chronic.parse('last monday 12:00 pm'), :end_at => Chronic.parse('last monday 12:00:05 pm'))
|
165
|
+
Whence.expects(:find).returns [whence]
|
166
|
+
@project.time_spent.should == 5.0/3600
|
167
|
+
end
|
168
|
+
|
169
|
+
it "correctly calculates with a scale" do
|
170
|
+
whence = mock('whence', :start_at => Time.parse('2009-10-04 23:53:32'), :end_at => Time.parse('2009-10-05 00:10:32'))
|
171
|
+
Whence.expects(:find).returns [whence]
|
172
|
+
@project.time_spent('month').should == 17.0/60
|
173
|
+
end
|
174
|
+
|
175
|
+
it "correctly calculates with a scale and specific time" do
|
176
|
+
whence = mock('whence', :start_at => Time.parse('2009-10-05 23:54:32'), :end_at => Time.parse('2009-10-06 00:12:32'))
|
177
|
+
Whence.expects(:find).returns [whence]
|
178
|
+
@project.time_spent('day', Chronic.parse('yesterday')).should == 18.0/60
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|