goal 0.0.3 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2a84abf9125ab94f0ab2cf6eebf7efdf4490198d
4
- data.tar.gz: 5561546fb4f5db03c667c5131b4ce0e9340bf377
3
+ metadata.gz: 3a273a57258b55e11c3d0f61514950efb5026ffa
4
+ data.tar.gz: 9e98c87c2cee48f8617f609acdf7388d6f9ede4f
5
5
  SHA512:
6
- metadata.gz: 7594268927070c99251e58107215c3e552f1f3ef136d994f32ac741e3213031317fc21a9dd1ef3c16eaa05c6b817f502f4f4449fd4761eacf036da27519a2845
7
- data.tar.gz: 553291d1fdab8f007e69368a7eee93aec75f1f6dbab323c0d5f42441d51f0de63cb69918c80d655e4cc5b94514fca8209b8f0d8f292fb020a6a18f6852118c88
6
+ metadata.gz: 2674f99af748b9e286bf9b04316816e6561c7f3b5599ccf466d8ecfcf7723901f4abb7ed9bd3d2634ea69991827f74523463f78f75d1e90b2e8ac0807fe26bb0
7
+ data.tar.gz: 964867d39e49b6d1a4a31ed4aa87fd62f9eaeedc34becd4e6ae54cc36d5110f822ed9ed86417f8f77d1409f33ed575701468b063e14a01555539ff81e0d44e1a
data/CHANGELOG.md CHANGED
@@ -1,3 +1,16 @@
1
+ ### 0.1.0
2
+
3
+ * bug fix
4
+ * Fix typo "Left days" => "Days left" on report
5
+ * Now -h or -u and -t are required options for the binary file
6
+
7
+ * new
8
+ * Removes the Base class, now there is a Calculator class reponsible to make
9
+ the main calculations and generate data to the report
10
+ * Add a report class to print the report
11
+ * Add a new option -h(--hours)
12
+
13
+
1
14
  ### 0.0.3
2
15
 
3
16
  * bug fix
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- goal (0.0.3)
4
+ goal (0.1.0)
5
5
  colorize (~> 0.6.0)
6
6
  ruby-freshbooks (~> 0.4.1)
7
7
 
data/README.md CHANGED
@@ -8,28 +8,44 @@ Goal
8
8
  the month that have 23 business days.
9
9
 
10
10
  ```ruby
11
- g = Goal.new
11
+ calculator = Goal::HourCalculator.new
12
12
 
13
- g.calculate_goal(160) # => 97.39130434782608
13
+ calculator.estimated_for(160) # => 97.39130434782608
14
14
  ```
15
15
 
16
16
  So I need to have 97.39 hours to be within my goal.
17
17
 
18
18
 
19
- ## Using the bin
19
+ ## Using the binary file
20
20
 
21
21
  ```bash
22
22
  $ goal -u freshbooks_user -t freshbooks_token
23
23
 
24
- | Goals | Estimate | Avg. to Goal |
25
- | 160 | 97 | 4.93 |
26
- | 200 | 121 | 9.37 |
27
- | 250 | 152 | 14.93 |
28
- | 300 | 182 | 20.48 |
29
- |_________________________________|
24
+ | Goals | Expected | Average |
25
+ | 160 | 97 | 4.93 |
26
+ | 200 | 121 | 9.37 |
27
+ | 250 | 152 | 14.93 |
28
+ | 300 | 182 | 20.48 |
29
+ |____________________________|
30
30
  | Current: 115.66h
31
31
  | Average: 8.26h
32
- | Left days: 9
32
+ | Days left: 9
33
+ ```
34
+
35
+ or
36
+
37
+ ```bash
38
+ $ goal -h 115.66
39
+
40
+ | Goals | Expected | Average |
41
+ | 160 | 97 | 4.93 |
42
+ | 200 | 121 | 9.37 |
43
+ | 250 | 152 | 14.93 |
44
+ | 300 | 182 | 20.48 |
45
+ |____________________________|
46
+ | Current: 115.66h
47
+ | Average: 8.26h
48
+ | Days left: 9
33
49
  ```
34
50
 
35
51
  ### Available options
@@ -39,9 +55,10 @@ Usage: goal [options]
39
55
  -u, --username=USERNAME Freshbooks username
40
56
  -t, --token=TOKEN Freshbooks token
41
57
  -g, --goals=[GOALS] Your goal list. Ex 160:200:300
58
+ -h, --hours=HOURS Worked time in hours.
42
59
  ```
43
60
 
44
61
  Options `-u` and `-t` are required and specify the user and token to access the
45
- Freshbooks hours.
62
+ Freshbooks hours. But you can use the -h option to specify manually the hours.
46
63
 
47
64
  The `-g` is optional, by default it has the following value `160:200:250:300`
data/bin/goal CHANGED
@@ -1,85 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'goal'
4
- require 'colorize'
5
4
  require 'optparse'
6
5
 
7
- class MyGoals
8
- def initialize(options = {})
9
- @base = Goal::Base.new
10
- @calculator = Goal::HourCalculator.new
11
- @goal_list = options.fetch(:goal_list, [160, 200, 250, 300])
12
- @username = options[:username]
13
- @token = options[:token]
14
- end
15
-
16
- def print
17
- puts
18
- print_header
19
- print_data
20
- print_footer
21
- puts
22
- end
23
-
24
- private
25
-
26
- attr_reader :base, :calculator, :goal_list, :username, :token
27
-
28
- def print_header
29
- puts '| Goals | Estimate | Avg. to Goal |'
30
- end
31
-
32
- def print_data
33
- goals.each do |goal|
34
- avg = calculator.rate_to_goal(goal[:goal], current_time).round(2)
35
-
36
- puts '| ' + goal[:goal].to_s.ljust(5) + ' | ' + goal[:expected].to_i.to_s.ljust(8) + ' | ' + avg.to_s.ljust(12).colorize(average_color(avg)) + ' |'
37
- end
38
- end
39
-
40
- def print_footer
41
- puts '|_________________________________|'
42
- puts "| Current: " + "#{current_time}h".colorize(current_color)
43
- puts "| Average: " + "#{rate}h".colorize(current_color)
44
- puts "| Left days: #{calculator.days_left}"
45
- end
46
-
47
- def current_time
48
- @current_time ||= base.worked_time(username, token).round(2)
49
- end
50
-
51
- def rate
52
- @rate ||= calculator.hour_rate(current_time).round(2)
53
- end
54
-
55
- def goals
56
- base.calculate_goals goal_list
57
- end
58
-
59
- def current_color
60
- if rate < 8
61
- :red
62
- elsif rate >= 8 && rate < 9
63
- :yellow
64
- else
65
- :green
66
- end
67
- end
68
-
69
- def average_color(avg)
70
- if avg < 8
71
- :green
72
- elsif avg >= 8 && avg < 9
73
- :yellow
74
- else
75
- :red
76
- end
77
- end
78
- end
79
-
80
6
  options = {}
81
7
 
82
- OptionParser.new do |opts|
8
+ optparse = OptionParser.new do |opts|
83
9
  opts.banner = "Usage: goal [options]"
84
10
 
85
11
  opts.on("-u", "--username=USERNAME", "Freshbooks username") do |u|
@@ -93,6 +19,20 @@ OptionParser.new do |opts|
93
19
  opts.on("-g", "--goals=[GOALS]", "Your goal list. Ex 160:200:300") do |g|
94
20
  options[:goal_list] = g.split(':').map(&:to_i)
95
21
  end
96
- end.parse!
97
22
 
98
- MyGoals.new(options).print
23
+ opts.on("-h", "--hours=HOURS", "Worked time in hours.") do |h|
24
+ options[:hours] = h.to_f
25
+ end
26
+ end
27
+
28
+ optparse.parse!
29
+
30
+ unless options[:hours] || (options[:username] && options[:token])
31
+ puts 'Arguments -h or -u and -t are required.'
32
+ puts optparse
33
+ exit
34
+ end
35
+
36
+ calculator = Goal::Calculator.new(options)
37
+ puts Goal::Report.new(calculator.generate_data)
38
+
@@ -0,0 +1,47 @@
1
+ module Goal
2
+ class Report
3
+ def initialize(data, options = {})
4
+ @data = data
5
+ @column_width = options.fetch(:column_width, 8)
6
+ end
7
+
8
+ def to_s
9
+ output = row(header) + "\n"
10
+
11
+ data[:rows].each do |r|
12
+ output += row([r[:goal], r[:expected], r[:average]]) + "\n"
13
+ end
14
+
15
+ output += footer
16
+
17
+ output
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :data, :column_width
23
+
24
+ def header
25
+ %w(Goals Expected Average)
26
+ end
27
+
28
+ def footer
29
+ "|" + ('-' * ((column_width * 3) + 8)) + "|\n" +
30
+ "| Current time: #{data[:summary][:total_time]}\n" +
31
+ "| Current rate: #{data[:summary][:rate]}\n" +
32
+ "| Days left: #{data[:summary][:days_left]}"
33
+ end
34
+
35
+ def row(columns)
36
+ prepared_columns = prepare_columns(columns)
37
+
38
+ "| #{prepared_columns.join(' | ')} |"
39
+ end
40
+
41
+ def prepare_columns(columns)
42
+ columns.map do |c|
43
+ c.to_s.ljust(column_width)
44
+ end
45
+ end
46
+ end
47
+ end
data/lib/goal/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Goal
2
- VERSION = '0.0.3'.freeze
2
+ VERSION = '0.1.0'.freeze
3
3
  end
data/lib/goal.rb CHANGED
@@ -1,6 +1,69 @@
1
1
  require 'goal/hour_calculator'
2
2
  require 'goal/freshbooks_calculator'
3
- require 'goal/base'
3
+ require 'goal/report'
4
4
 
5
5
  module Goal
6
+ class Calculator
7
+ def initialize(options = {})
8
+ @calculator = Goal::HourCalculator.new
9
+ @goal_list = options.fetch(:goal_list, [160, 200, 250, 300])
10
+ @username = options[:username]
11
+ @token = options[:token]
12
+ @hours = options[:hours]
13
+ end
14
+
15
+ def worked_time
16
+ if hours
17
+ hours
18
+ elsif username && token
19
+ freshbooks.hours
20
+ else
21
+ 0
22
+ end.round(2)
23
+ end
24
+
25
+ # It calculates the current hour rate
26
+ def rate
27
+ calculator.hour_rate(worked_time).round(2)
28
+ end
29
+
30
+ def generate_data
31
+ data = {}
32
+
33
+ data[:rows] = goals
34
+ data[:summary] = summary
35
+
36
+ data
37
+ end
38
+
39
+ private
40
+
41
+ attr_reader :base, :calculator, :goal_list, :username, :token, :hours
42
+
43
+ def freshbooks
44
+ Goal::FreshbooksCalculator.new(username, token)
45
+ end
46
+
47
+ def goals
48
+ calculated_goals = []
49
+
50
+ goal_list.each do |goal|
51
+ calculated_goals.push({
52
+ goal: goal,
53
+ expected: calculator.estimated_for(goal).round(2),
54
+ average: calculator.rate_to_goal(goal, worked_time).round(2)
55
+ })
56
+ end
57
+
58
+ calculated_goals
59
+ end
60
+
61
+ def summary
62
+ {
63
+ total_time: worked_time,
64
+ rate: rate,
65
+ days_left: calculator.days_left
66
+ }
67
+ end
68
+ end
6
69
  end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe Goal::Calculator do
4
+ describe '#worked_time' do
5
+ context 'with hours' do
6
+ subject do
7
+ described_class.new(hours: 90)
8
+ end
9
+
10
+ it 'should return hours' do
11
+ expect(subject.worked_time).to eq 90
12
+ end
13
+ end
14
+
15
+ context 'with hours' do
16
+ subject do
17
+ described_class.new(username: 'username', token: 'token')
18
+ end
19
+
20
+ it 'should return the freshbooks hours' do
21
+ instance = double(:instance)
22
+
23
+ Goal::FreshbooksCalculator.should_receive(:new).with('username', 'token').and_return(instance)
24
+ instance.should_receive(:hours).and_return 55.55
25
+
26
+ expect(subject.worked_time).to eq 55.55
27
+ end
28
+ end
29
+ end
30
+
31
+ describe '#rate' do
32
+ subject do
33
+ described_class.new(hours: 90)
34
+ end
35
+
36
+ it 'should return calculate the rate' do
37
+ Date.stub(today: Date.new(2013, 10, 20))
38
+
39
+ expect(subject.rate).to eq 6.43
40
+ end
41
+ end
42
+
43
+ describe '#generate_data' do
44
+ subject do
45
+ described_class.new(hours: 90, goal_list: [160, 200])
46
+ end
47
+
48
+ it 'should return the generated data' do
49
+ Date.stub(today: Date.new(2013, 10, 20))
50
+
51
+ expect(subject.generate_data).to eq({
52
+ rows: [
53
+ {
54
+ goal: 160,
55
+ expected: 97.39,
56
+ average: 7.78
57
+ },
58
+ {
59
+ goal: 200,
60
+ expected: 121.74,
61
+ average: 12.22
62
+ }
63
+ ],
64
+ summary: {
65
+ total_time: 90.0,
66
+ rate: 6.43,
67
+ days_left: 9
68
+ }
69
+ })
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe Goal::Report do
4
+ let(:data) do
5
+ {
6
+ rows: [
7
+ {
8
+ goal: 160,
9
+ expected: 97.39,
10
+ average: 7.78
11
+ },
12
+ {
13
+ goal: 200,
14
+ expected: 121.74,
15
+ average: 12.22
16
+ }
17
+ ],
18
+ summary: {
19
+ total_time: 90.0,
20
+ rate: 6.43,
21
+ days_left: 9
22
+ }
23
+ }
24
+ end
25
+
26
+ subject do
27
+ described_class.new(data)
28
+ end
29
+
30
+ describe '#to_s' do
31
+ it 'should build the report' do
32
+ report = "| Goals | Expected | Average |\n"
33
+ report += "| 160 | 97.39 | 7.78 |\n"
34
+ report += "| 200 | 121.74 | 12.22 |\n"
35
+ report += "|--------------------------------|\n"
36
+ report += "| Current time: 90.0\n"
37
+ report += "| Current rate: 6.43\n"
38
+ report += "| Days left: 9"
39
+
40
+ expect(subject.to_s).to eq report
41
+ end
42
+ end
43
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: goal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mateus Lorandi dos Santos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-21 00:00:00.000000000 Z
11
+ date: 2013-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-freshbooks
@@ -83,13 +83,14 @@ files:
83
83
  - bin/goal
84
84
  - goal.gemspec
85
85
  - lib/goal.rb
86
- - lib/goal/base.rb
87
86
  - lib/goal/freshbooks_calculator.rb
88
87
  - lib/goal/hour_calculator.rb
88
+ - lib/goal/report.rb
89
89
  - lib/goal/version.rb
90
- - spec/base_spec.rb
90
+ - spec/calculator_spec.rb
91
91
  - spec/freshbooks_calculator_spec.rb
92
92
  - spec/hour_calculator_spec.rb
93
+ - spec/report_spec.rb
93
94
  - spec/spec_helper.rb
94
95
  homepage: http://github.com/comogo/goal
95
96
  licenses:
@@ -111,9 +112,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
112
  version: '0'
112
113
  requirements: []
113
114
  rubyforge_project:
114
- rubygems_version: 2.1.5
115
+ rubygems_version: 2.1.9
115
116
  signing_key:
116
117
  specification_version: 4
117
118
  summary: Keep track of your hour goals
118
119
  test_files: []
119
- has_rdoc:
data/lib/goal/base.rb DELETED
@@ -1,32 +0,0 @@
1
- module Goal
2
- class Base
3
- def initialize
4
- @calculator = HourCalculator.new
5
- end
6
-
7
- def worked_time(username, token)
8
- FreshbooksCalculator.new(username, token).hours
9
- end
10
-
11
- def calculate_goal(goal)
12
- calculator.estimated_for(goal)
13
- end
14
-
15
- def calculate_goals(goals)
16
- calculated_goals = []
17
-
18
- goals.each do |goal|
19
- calculated_goals.push({
20
- goal: goal,
21
- expected: calculate_goal(goal)
22
- })
23
- end
24
-
25
- calculated_goals
26
- end
27
-
28
- private
29
-
30
- attr_reader :calculator
31
- end
32
- end
data/spec/base_spec.rb DELETED
@@ -1,40 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Goal::Base do
4
- describe '#worked_time' do
5
- it 'should get the worked_time from freshbooks' do
6
- freshbooks_instance = double(:freshbooks_instance)
7
-
8
- Goal::FreshbooksCalculator.should_receive(:new).with('username', 'token').and_return(freshbooks_instance)
9
- freshbooks_instance.should_receive(:hours).and_return(30)
10
-
11
- expect(subject.worked_time('username', 'token')).to eq 30
12
- end
13
- end
14
-
15
- describe '#calculate_goal' do
16
- it 'should calculate goal using the hour calculator' do
17
- Goal::HourCalculator.any_instance.should_receive(:estimated_for).with(200).and_return 10
18
-
19
- expect(subject.calculate_goal(200)).to eq 10
20
- end
21
- end
22
-
23
- describe '#calculate_goals' do
24
- it 'should calculate goals using the hour calculator' do
25
- Goal::HourCalculator.any_instance.should_receive(:estimated_for).with(160).and_return 10
26
- Goal::HourCalculator.any_instance.should_receive(:estimated_for).with(200).and_return 20
27
-
28
- expect(subject.calculate_goals([160, 200])).to eq([
29
- {
30
- goal: 160,
31
- expected: 10
32
- },
33
- {
34
- goal: 200,
35
- expected: 20
36
- }
37
- ])
38
- end
39
- end
40
- end