Pratt 1.6.5 → 1.6.8
Sign up to get free protection for your applications and to get access to all the features.
- data/Pratt.gemspec +16 -4
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/config.rb +0 -1
- data/lib/pratt.rb +1 -1
- data/lib/pratt/core_ext/array.rb +5 -1
- data/lib/pratt/core_ext/float.rb +1 -0
- data/lib/pratt/dialogs.rb +2 -1
- data/lib/pratt/formatting.rb +1 -1
- data/lib/pratt/reports.rb +16 -9
- data/models/customer.rb +5 -1
- data/models/pratt.rb +5 -0
- data/models/project.rb +8 -7
- data/models/whence.rb +1 -3
- data/spec/array_spec.rb +24 -0
- data/spec/fixtures/empty_graph.expectation +8 -0
- data/spec/fixtures/graph.expectation +8 -8
- data/spec/fixtures/proportions.expectation +4 -4
- data/spec/formatting_spec.rb +7 -0
- data/spec/money_spec.rb +9 -0
- data/spec/nil_class_spec.rb +8 -0
- data/spec/pratt_spec.rb +12 -61
- data/spec/project_spec.rb +6 -3
- data/spec/report_action_spec.rb +83 -0
- data/spec/report_spec.rb +205 -0
- data/spec/spec_helper.rb +34 -28
- data/views/general-invoice.eruby +3 -3
- data/views/invoice.eruby +1 -1
- metadata +16 -4
- data/Session.vim +0 -1010
data/Pratt.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{Pratt}
|
8
|
-
s.version = "1.6.
|
8
|
+
s.version = "1.6.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Scott Noel-Hemming"]
|
12
|
-
s.date = %q{2010-05-
|
12
|
+
s.date = %q{2010-05-31}
|
13
13
|
s.default_executable = %q{pratt.rb}
|
14
14
|
s.description = %q{
|
15
15
|
Need a way to keep track of your time, but get caught up in work? Or constant interruptions?
|
@@ -40,7 +40,6 @@ Gem::Specification.new do |s|
|
|
40
40
|
"README.html",
|
41
41
|
"README.txt",
|
42
42
|
"Rakefile",
|
43
|
-
"Session.vim",
|
44
43
|
"TODO",
|
45
44
|
"VERSION",
|
46
45
|
"bin/pratt.rb",
|
@@ -315,15 +314,22 @@ Gem::Specification.new do |s|
|
|
315
314
|
"reports/travel.log",
|
316
315
|
"reports/travel.log.2009",
|
317
316
|
"spec/app_spec.rb",
|
317
|
+
"spec/array_spec.rb",
|
318
318
|
"spec/customer_spec.rb",
|
319
|
+
"spec/fixtures/empty_graph.expectation",
|
319
320
|
"spec/fixtures/graph.expectation",
|
320
321
|
"spec/fixtures/proportions.expectation",
|
321
322
|
"spec/float_spec.rb",
|
323
|
+
"spec/formatting_spec.rb",
|
324
|
+
"spec/money_spec.rb",
|
325
|
+
"spec/nil_class_spec.rb",
|
322
326
|
"spec/numeric_spec.rb",
|
323
327
|
"spec/payment_spec.rb",
|
324
328
|
"spec/pratt_spec.rb",
|
325
329
|
"spec/project_spec.rb",
|
326
330
|
"spec/rcov.opts",
|
331
|
+
"spec/report_action_spec.rb",
|
332
|
+
"spec/report_spec.rb",
|
327
333
|
"spec/spec.opts",
|
328
334
|
"spec/spec_helper.rb",
|
329
335
|
"spec/string_ext_spec.rb",
|
@@ -348,15 +354,21 @@ Gem::Specification.new do |s|
|
|
348
354
|
s.rubygems_version = %q{1.3.6}
|
349
355
|
s.summary = %q{Pro/Re-Active Time Tracker. Track time based on what you expect to be working on, with frequent prompts to ensure accuracy.}
|
350
356
|
s.test_files = [
|
351
|
-
"spec/
|
357
|
+
"spec/nil_class_spec.rb",
|
358
|
+
"spec/whence_spec.rb",
|
359
|
+
"spec/array_spec.rb",
|
352
360
|
"spec/spec_helper.rb",
|
353
361
|
"spec/float_spec.rb",
|
354
362
|
"spec/pratt_spec.rb",
|
355
363
|
"spec/project_spec.rb",
|
356
364
|
"spec/numeric_spec.rb",
|
357
365
|
"spec/app_spec.rb",
|
366
|
+
"spec/formatting_spec.rb",
|
358
367
|
"spec/string_ext_spec.rb",
|
359
368
|
"spec/customer_spec.rb",
|
369
|
+
"spec/report_spec.rb",
|
370
|
+
"spec/money_spec.rb",
|
371
|
+
"spec/report_action_spec.rb",
|
360
372
|
"spec/payment_spec.rb"
|
361
373
|
]
|
362
374
|
|
data/Rakefile
CHANGED
@@ -42,6 +42,7 @@ Spec::Rake::SpecTask.new(:rcov) do |spec|
|
|
42
42
|
spec.libs << 'lib' << 'spec'
|
43
43
|
spec.pattern = 'spec/**/*_spec.rb'
|
44
44
|
spec.rcov = true
|
45
|
+
spec.rcov_opts = %w(--text-report --exclude=activerecord,ruby-debug,shifty_week,sqlite3-ruby,rspec,mocha,erubis,chronic,colored,columnize,builder,activesupport,i18n,linecache,json_pure,rcov,abstract,spec_helper.rb,config.rb,spec)
|
45
46
|
end
|
46
47
|
|
47
48
|
task :spec => :check_dependencies
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.6.
|
1
|
+
1.6.8
|
data/config.rb
CHANGED
data/lib/pratt.rb
CHANGED
data/lib/pratt/core_ext/array.rb
CHANGED
@@ -7,7 +7,11 @@ class Pratt
|
|
7
7
|
# @param [String] conjunction
|
8
8
|
# @return [String]
|
9
9
|
def to_sentence conjunction = 'and'
|
10
|
-
|
10
|
+
if self.size >= 2
|
11
|
+
self[0..-2].join(", ") << (self.size > 2 ? ',' : '') << " #{conjunction} #{self.last}"
|
12
|
+
elsif self.size <= 1
|
13
|
+
self.first.to_s
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
13
17
|
end
|
data/lib/pratt/core_ext/float.rb
CHANGED
data/lib/pratt/dialogs.rb
CHANGED
@@ -61,8 +61,9 @@ class Pratt
|
|
61
61
|
def pop
|
62
62
|
reload_and_detect_lock 'pop'
|
63
63
|
self.project = Whence.last_unended.project
|
64
|
+
project_time = project.formatted_time_spent_totals( project.time_spent(scale, when_to) )
|
64
65
|
defork do
|
65
|
-
command = "ruby views/pop.rb --project '#{project.name}' --start '#{project.whences.last_unended.start_at}' --project_time '#{
|
66
|
+
command = "ruby views/pop.rb --project '#{project.name}' --start '#{project.whences.last_unended.start_at}' --project_time '#{project_time}'"
|
66
67
|
system command
|
67
68
|
end
|
68
69
|
end
|
data/lib/pratt/formatting.rb
CHANGED
@@ -17,7 +17,7 @@ class Pratt
|
|
17
17
|
end
|
18
18
|
|
19
19
|
# Calculate totals. I think this should be an instance method on Projects/?/Whences
|
20
|
-
def totals hr
|
20
|
+
def totals hr
|
21
21
|
"#{(hr / 24).format_integer.cyan} day #{(hr % 24).format_integer.yellow} hour #{(60*(hr -= hr.to_i)).format_integer.green} min"
|
22
22
|
end
|
23
23
|
end
|
data/lib/pratt/reports.rb
CHANGED
@@ -5,7 +5,7 @@ class Pratt
|
|
5
5
|
self.template = 'graph'
|
6
6
|
|
7
7
|
if project?
|
8
|
-
@projects = [project]
|
8
|
+
@projects = [ project ]
|
9
9
|
else
|
10
10
|
@projects = Project.all
|
11
11
|
end
|
@@ -21,7 +21,7 @@ class Pratt
|
|
21
21
|
@projects = [project]
|
22
22
|
|
23
23
|
@primary = project.time_spent(scale, when_to)
|
24
|
-
@scaled_total = project.
|
24
|
+
@scaled_total = project.time_spent(scale, when_to)
|
25
25
|
else
|
26
26
|
@projects = Project.all
|
27
27
|
|
@@ -30,13 +30,13 @@ class Pratt
|
|
30
30
|
@off_total = proj.time_spent(scale, when_to) if proj.name == Project.off.name
|
31
31
|
@rest_total += proj.time_spent(scale, when_to) if Project.rest.collect(&:name).include?(proj.name)
|
32
32
|
end
|
33
|
-
@scaled_total = Whence.time_spent(scale, when_to)
|
33
|
+
@scaled_total = Whence.time_spent(scale, when_to) - @off_total
|
34
34
|
end
|
35
35
|
|
36
36
|
if @primary + @off_total + @rest_total > 0.0
|
37
37
|
process_template!
|
38
38
|
else
|
39
|
-
"No data to report"
|
39
|
+
$stdout.puts "No data to report"
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -47,13 +47,13 @@ class Pratt
|
|
47
47
|
if project?
|
48
48
|
@projects = [project]
|
49
49
|
|
50
|
-
@total = project.amount(scale, when_to)
|
50
|
+
@total = project.amount( project.time_spent(scale, when_to) )
|
51
51
|
else
|
52
52
|
@projects = (Project.all - [Project.primary, Project.off])
|
53
|
-
@projects.select
|
53
|
+
@projects = @projects.select {|proj| show_all or ( !show_all and proj.time_spent(scale, when_to) != 0.0 ) }
|
54
54
|
|
55
55
|
@total = @projects.inject 0.0 do |total, proj|
|
56
|
-
total += proj.amount(scale, when_to)
|
56
|
+
total += proj.amount( proj.time_spent(scale, when_to) )
|
57
57
|
total
|
58
58
|
end
|
59
59
|
end
|
@@ -64,7 +64,7 @@ class Pratt
|
|
64
64
|
if @total > 0.0
|
65
65
|
process_template!
|
66
66
|
else
|
67
|
-
puts "No data to report"
|
67
|
+
$stdout.puts "No data to report in Pratt#invoice"
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -118,10 +118,17 @@ class Pratt
|
|
118
118
|
end
|
119
119
|
|
120
120
|
private
|
121
|
+
def output
|
122
|
+
# for testing
|
123
|
+
@__output
|
124
|
+
end
|
125
|
+
|
121
126
|
def process_template!
|
122
127
|
input = File.open(Pratt.root("views", "#{template}.eruby").first).read
|
123
128
|
erubis = Erubis::Eruby.new(input)
|
124
|
-
|
129
|
+
@__output = erubis.evaluate(self)
|
130
|
+
$stdout.puts @__output
|
131
|
+
nil
|
125
132
|
end
|
126
133
|
|
127
134
|
end
|
data/models/customer.rb
CHANGED
@@ -13,7 +13,11 @@ class Customer < ActiveRecord::Base
|
|
13
13
|
phone = read_attribute(:phone)
|
14
14
|
class << phone
|
15
15
|
def pretty_print sep = '.'
|
16
|
-
self.
|
16
|
+
if self.blank?
|
17
|
+
""
|
18
|
+
else
|
19
|
+
self.split(/(\d{3})(\d{3})(\d{4})/)[1,3] * sep
|
20
|
+
end
|
17
21
|
end
|
18
22
|
end
|
19
23
|
phone
|
data/models/pratt.rb
CHANGED
@@ -6,5 +6,10 @@ class Pratt
|
|
6
6
|
cond = [(cond << "start_at BETWEEN ? AND ?").join(' AND ')] | [when_to.send("beginning_of_#{scale}"), when_to.send("end_of_#{scale}")] unless scale.nil?
|
7
7
|
cond
|
8
8
|
end
|
9
|
+
|
10
|
+
def total_whences whences_since
|
11
|
+
seconds = whences_since.inject(0.0) {|total, whence| total += ( whence.end_at - whence.start_at ) }
|
12
|
+
hour = seconds / 3600
|
13
|
+
end
|
9
14
|
end
|
10
15
|
end
|
data/models/project.rb
CHANGED
@@ -25,19 +25,20 @@ class Project < ActiveRecord::Base
|
|
25
25
|
self.start! at
|
26
26
|
end
|
27
27
|
|
28
|
-
def time_spent scale = nil, when_to = DateTime.now
|
28
|
+
def time_spent scale = nil, when_to = DateTime.now, &block
|
29
29
|
whences_since = self.whences.find :all, :conditions => conditions_for_time_spent(scale, when_to)
|
30
|
-
whences_since
|
31
|
-
total += ( whence.end_at - whence.start_at )
|
32
|
-
} / 3600
|
30
|
+
total_whences whences_since
|
33
31
|
end
|
34
32
|
|
35
|
-
def amount
|
36
|
-
amount =
|
37
|
-
amount *= payment.rate / 100.0
|
33
|
+
def amount hour
|
34
|
+
amount = hour * ( payment.rate / 100.0 )
|
38
35
|
amount.to_money
|
39
36
|
end
|
40
37
|
|
38
|
+
def formatted_time_spent_totals hour
|
39
|
+
"#{(hour / 24).format_integer.cyan} day #{(hour % 24).format_integer.yellow} hour #{(60*(hour -= hour.to_i)).format_integer.green} min"
|
40
|
+
end
|
41
|
+
|
41
42
|
class << self
|
42
43
|
def named name
|
43
44
|
first :conditions => { :name => name }
|
data/models/whence.rb
CHANGED
@@ -45,9 +45,7 @@ class Whence < ActiveRecord::Base
|
|
45
45
|
|
46
46
|
def time_spent scale = nil, when_to = Time.now
|
47
47
|
whences_since = Whence.find :all, :conditions => conditions_for_time_spent(scale, when_to)
|
48
|
-
whences_since
|
49
|
-
total += ( whence.end_at - whence.start_at )
|
50
|
-
} / 3600
|
48
|
+
total_whences whences_since
|
51
49
|
end
|
52
50
|
|
53
51
|
def last_unended
|
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
|
@@ -1,13 +1,13 @@
|
|
1
1
|
Project detail
|
2
2
|
by week from
|
3
3
|
Mon 00:00:00 Sep 28 2009 to Sun 23:59:59 Oct 04 2009
|
4
|
-
|
5
|
-
|
4
|
+
dys hrs min total
|
5
|
+
-------------------------------------------------------------------
|
6
6
|
|
7
|
-
Lunch/Break| 00 day 01 hour 21 min
|
8
|
-
Task1| 00 day 01 hour
|
9
|
-
Task2| 00 day 00 hour 58 min
|
10
|
-
Another Task| 00 day 00 hour 05 min
|
11
|
-
Task3| 01 day 17 hour
|
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
12
|
|
13
|
-
|
13
|
+
-------------------------------------------------------------------
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
Total 43.65 hrs
|
2
|
+
Refactor 0.00%
|
3
|
+
Lunch/Break 3.09%
|
4
|
+
Other 100.00%
|
data/spec/money_spec.rb
ADDED
data/spec/pratt_spec.rb
CHANGED
@@ -81,59 +81,7 @@ describe Pratt do
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
describe "graph" do
|
85
|
-
before :each do
|
86
|
-
@when_to = Chronic.parse('last week').beginning_of_week
|
87
|
-
@pratt.scale = 'week'
|
88
|
-
@pratt.when_to = @when_to
|
89
|
-
@customer = Customer.create :name => 'Bob Hope', :address => '123 Where St', :zip => '22222'
|
90
|
-
@tasks = []
|
91
|
-
end
|
92
|
-
|
93
|
-
after :each do
|
94
|
-
Whence.delete_all
|
95
|
-
@customer.destroy
|
96
|
-
@tasks.each(&:destroy)
|
97
|
-
end
|
98
|
-
|
99
|
-
def task name, time_spent
|
100
|
-
task = Project.find_or_create_by_name :name => name, :customer => @customer
|
101
|
-
task.start! @when_to
|
102
|
-
task.stop! @when_to+time_spent
|
103
|
-
@tasks << task
|
104
|
-
end
|
105
|
-
|
106
|
-
def populate_with_data
|
107
|
-
@tasks << Project.find_or_create_by_name( :name => '**** ********', :weight => 1, :customer => @customer )
|
108
|
-
task 'Lunch/Break', 1.hour+21.minutes
|
109
|
-
task 'Task1', 1.hour+4.minutes
|
110
|
-
task 'Task2', 58.minutes
|
111
|
-
task 'Another Task', 5.minutes
|
112
|
-
task 'Task3', 1.day+17.hours+32.minutes
|
113
|
-
end
|
114
|
-
|
115
|
-
def get_expected_display
|
116
|
-
e = ''
|
117
|
-
Pratt.root('spec', 'fixtures', 'graph.expectation') {|file| e = File.open(file).read }
|
118
|
-
e
|
119
|
-
end
|
120
|
-
|
121
|
-
it "report no data" do
|
122
|
-
Project.expects(:all).returns([])
|
123
|
-
@pratt.expects(:process_template!).never
|
124
|
-
@pratt.graph.should == "No data to report"
|
125
|
-
end
|
126
|
-
|
127
|
-
it "should look right with data" do
|
128
|
-
populate_with_data
|
129
|
-
@pratt.expects(:process_template!)
|
130
|
-
|
131
|
-
@pratt.graph.should == get_expected_display
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
84
|
describe "parse" do
|
136
|
-
it "handles cli arg -n setting appropriate environment config"
|
137
85
|
# do
|
138
86
|
## Pratt.expects(:connect).with('staging')
|
139
87
|
## lambda {
|
@@ -142,14 +90,17 @@ describe Pratt do
|
|
142
90
|
# ENV['PRATT_ENV'].should == 'staging'
|
143
91
|
# end
|
144
92
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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
|
154
105
|
end
|
155
106
|
end
|