tracco 0.0.14 → 0.0.15

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.
Files changed (45) hide show
  1. data/CHANGELOG +16 -0
  2. data/Gemfile.lock +1 -1
  3. data/README.md +4 -4
  4. data/lib/patches/trello/card.rb +3 -2
  5. data/lib/patches/trello/member.rb +4 -2
  6. data/lib/tasks/tasks.rake +2 -2
  7. data/lib/tracco/google_docs_exporter.rb +50 -47
  8. data/lib/tracco/models/effort.rb +40 -0
  9. data/lib/tracco/models/estimate.rb +29 -0
  10. data/lib/tracco/models/member.rb +64 -0
  11. data/lib/tracco/models/tracked_card.rb +148 -0
  12. data/lib/tracco/tracking/base.rb +68 -65
  13. data/lib/tracco/tracking/card_done_tracking.rb +9 -6
  14. data/lib/tracco/tracking/effort_tracking.rb +32 -29
  15. data/lib/tracco/tracking/estimate_tracking.rb +16 -13
  16. data/lib/tracco/tracking/factory.rb +18 -16
  17. data/lib/tracco/tracking/invalid_tracking.rb +15 -13
  18. data/lib/tracco/trello_tracker.rb +34 -30
  19. data/lib/tracco/version.rb +2 -2
  20. data/lib/tracco.rb +4 -4
  21. data/spec/factories/effort_factory.rb +2 -2
  22. data/spec/factories/estimate_factory.rb +1 -1
  23. data/spec/factories/tracked_card_factory.rb +1 -1
  24. data/spec/integration/trello_tracker_spec.rb +49 -47
  25. data/spec/models/effort_spec.rb +61 -0
  26. data/spec/models/estimate_spec.rb +40 -0
  27. data/spec/models/member_spec.rb +83 -0
  28. data/spec/models/tracked_card_spec.rb +467 -0
  29. data/spec/support/spec_helper_methods.rb +7 -1
  30. data/spec/tracking/card_done_tracking_spec.rb +11 -9
  31. data/spec/tracking/effort_tracking_spec.rb +77 -75
  32. data/spec/tracking/estimate_tracking_spec.rb +30 -28
  33. data/spec/tracking/factory_spec.rb +39 -0
  34. data/spec/trello_tracker_spec.rb +20 -18
  35. data/tracco.gemspec +1 -1
  36. metadata +12 -12
  37. data/lib/tracco/effort.rb +0 -37
  38. data/lib/tracco/estimate.rb +0 -26
  39. data/lib/tracco/member.rb +0 -61
  40. data/lib/tracco/tracked_card.rb +0 -145
  41. data/spec/effort_spec.rb +0 -59
  42. data/spec/estimate_spec.rb +0 -38
  43. data/spec/member_spec.rb +0 -81
  44. data/spec/tracked_card_spec.rb +0 -465
  45. data/spec/tracking_factory_spec.rb +0 -42
@@ -1,145 +0,0 @@
1
- class TrackedCard
2
- include Mongoid::Document
3
- include Mongoid::Timestamps
4
- extend MongoidHelper
5
-
6
- field :name
7
- field :description
8
- field :short_id, type: Integer
9
- field :trello_id
10
- field :done, type: Boolean
11
- field :due, type: Date
12
- field :closed, type: Boolean
13
- field :url
14
- field :pos
15
-
16
- embeds_many :estimates
17
- embeds_many :efforts
18
-
19
- validates_presence_of :name, :short_id, :trello_id
20
- validates_numericality_of :short_id
21
-
22
- scope :with_effort_spent_by, ->(username){ where("efforts.members.username" => username) }
23
-
24
- def self.find_by_trello_id(trello_id)
25
- without_mongo_raising_errors do
26
- find_by(trello_id: trello_id)
27
- end
28
- end
29
-
30
- def self.update_or_create_with(trello_card)
31
- tracked_card = find_or_create_by(trello_id: trello_card.id)
32
- trello_card.attributes.delete(:id)
33
- tracked_card_attributes = trello_card.attributes.merge(done: trello_card.in_done_column?)
34
- updated_successfully = tracked_card.update_attributes(tracked_card_attributes)
35
- return tracked_card if updated_successfully
36
- end
37
-
38
- def self.all_tracked_cards(sorting_options = {})
39
- cards = all.reject(&:no_tracking?)
40
- cards.sort_by!(&sorting_options[:sort_by].to_sym) if sorting_options[:sort_by]
41
- cards.reverse! if sorting_options[:order] == :desc
42
- return cards
43
- end
44
-
45
- def self.build_from(trello_card)
46
- trello_card_id = trello_card.id
47
- trello_card.attributes.delete(:id)
48
- new(trello_card.attributes.merge(trello_id: trello_card_id))
49
- end
50
-
51
- def self.efforts_between(search_options)
52
- condition = {}
53
- {'$gte' => :from_date, '$lte' => :to_date}.each do |selection, option_key|
54
- condition[selection] = search_options[option_key] if search_options[option_key]
55
- end
56
-
57
- where("efforts.date" => condition)
58
- end
59
-
60
- def status
61
- if done?
62
- :done
63
- elsif efforts.empty?
64
- :todo
65
- else
66
- :in_progress
67
- end
68
- end
69
-
70
- def add(tracking)
71
- tracking.add_to(self)
72
- end
73
-
74
- def add!(tracking)
75
- add(tracking) && save!
76
- end
77
-
78
- def contains_effort?(effort)
79
- efforts.unscoped.any? { |e| e.tracking_notification_id == effort.tracking_notification_id }
80
- end
81
-
82
- def contains_estimate?(estimate)
83
- estimates.any? { |e| e.tracking_notification_id == estimate.tracking_notification_id }
84
- end
85
-
86
- def no_tracking?
87
- first_activity_date.nil?
88
- end
89
-
90
- def first_activity_date
91
- [working_start_date, first_estimate_date].compact.min
92
- end
93
-
94
- def working_start_date
95
- efforts.sort_by(&:date).first.date if efforts.present?
96
- end
97
-
98
- def first_estimate_date
99
- estimates.sort_by(&:date).first.date if estimates.present?
100
- end
101
-
102
- def last_estimate_date
103
- estimates.sort_by(&:date).last.date if estimates.present?
104
- end
105
-
106
- def total_effort
107
- efforts.map(&:amount).inject(0, &:+)
108
- end
109
-
110
- def members
111
- efforts.map(&:members).flatten.uniq
112
- end
113
-
114
- def last_estimate_error
115
- estimate_errors.last
116
- end
117
-
118
- def estimate_errors
119
- return [] if estimates.empty? || efforts.empty?
120
-
121
- estimate_errors = []
122
- estimates.each do |each|
123
- estimate_errors << (100 * ((total_effort - each.amount) / each.amount * 1.0)).round(2)
124
- end
125
-
126
- estimate_errors
127
- end
128
-
129
- def trello_notifications
130
- # TODO select all efforts, even the muted ones?
131
- notification_ids = efforts.map(&:tracking_notification_id) | estimates.map(&:tracking_notification_id)
132
- notification_ids.map { |id| Trello::Notification.find(id) rescue nil }.compact.sort_by(&:date)
133
- end
134
-
135
- def to_s
136
- "[#{name}]. Total effort: #{total_effort}h. Estimates #{estimates.map(&:to_s)}. Efforts: #{efforts.map(&:to_s)}"
137
- end
138
-
139
- def ==(other)
140
- return true if other.equal?(self)
141
- return false unless other.kind_of?(self.class)
142
- trello_id == other.trello_id
143
- end
144
-
145
- end
data/spec/effort_spec.rb DELETED
@@ -1,59 +0,0 @@
1
- require 'spec_helper'
2
- require 'mongoid-rspec'
3
-
4
- describe Effort do
5
-
6
- it { should have_fields(:amount, :date, :muted, :tracking_notification_id) }
7
- it { should be_embedded_in(:tracked_card) }
8
- it { should embed_many(:members) }
9
-
10
- describe "validation" do
11
- it { should validate_presence_of(:amount) }
12
- it { should validate_presence_of(:date) }
13
- it { should validate_presence_of(:members) }
14
- end
15
-
16
- %w{piero tommaso tom ugo}.each do |username|
17
- let(username.to_sym) { Member.new(username: username) }
18
- end
19
-
20
- describe "#amount_per_member" do
21
- it "counts the amount spent per single member" do
22
- effort = Effort.new(amount: 6, members: [piero, tommaso], date: Date.parse("2012-11-09"), )
23
- effort.amount_per_member.should == 3
24
- end
25
- end
26
-
27
- describe "equality" do
28
- it "is equal to another effort with same amount, date and members" do
29
- effort = Effort.new(amount: 3, date: Date.parse("2012-11-09"), members: [piero, tommaso])
30
- same_effort = Effort.new(amount: 3, date: Date.parse("2012-11-09"), members: [piero, tommaso])
31
- yet_same_effort = Effort.new(amount: 3, date: Date.parse("2012-11-09"), members: [tommaso, piero])
32
-
33
- effort.should == same_effort
34
- effort.should == yet_same_effort
35
- end
36
-
37
- it "is not equal when amount differs" do
38
- effort = Effort.new(amount: 3, date: Date.today, members: [tom, ugo])
39
- another_effort = Effort.new(amount: 1, date: Date.today, members: [tom, ugo])
40
-
41
- effort.should_not == another_effort
42
- end
43
-
44
- it "is not equal when date differs" do
45
- effort = Effort.new(amount: 3, date: Date.parse("2012-11-09"), members: [tom, ugo])
46
- another_effort = Effort.new(amount: 3, date: Date.parse("2011-10-08"), members: [tom, ugo])
47
-
48
- effort.should_not == another_effort
49
- end
50
-
51
- it "is not equal when members differ" do
52
- effort = Effort.new(amount: 3, date: Date.today, members: [tom, ugo])
53
- another_effort = Effort.new(amount: 3, date: Date.today, members: [piero, ugo])
54
-
55
- effort.should_not == another_effort
56
- end
57
-
58
- end
59
- end
@@ -1,38 +0,0 @@
1
- require 'spec_helper'
2
- require 'mongoid-rspec'
3
-
4
- describe Estimate do
5
-
6
- it { should have_fields(:amount, :date) }
7
- it { should be_embedded_in(:tracked_card) }
8
-
9
- describe "validation" do
10
- it { should validate_presence_of(:amount) }
11
- it { should validate_presence_of(:date) }
12
- end
13
-
14
- describe "equality" do
15
-
16
- it "is equal to another estimate with same amount and date" do
17
- estimate = Estimate.new(amount: 3, date: Date.parse("2012-11-09"))
18
- same_estimate = Estimate.new(amount: 3, date: Date.parse("2012-11-09"))
19
-
20
- estimate.should == same_estimate
21
- end
22
-
23
- it "is not equal when amount differs" do
24
- estimate = Estimate.new(amount: 3, date: Date.today)
25
- another_estimate = Estimate.new(amount: 1, date: Date.today)
26
-
27
- estimate.should_not == another_estimate
28
- end
29
-
30
- it "is not equal when date differs" do
31
- estimate = Estimate.new(amount: 3, date: Date.parse("2012-11-09"))
32
- another_estimate = Estimate.new(amount: 3, date: Date.parse("2011-10-08"))
33
-
34
- estimate.should_not == another_estimate
35
- end
36
-
37
- end
38
- end
data/spec/member_spec.rb DELETED
@@ -1,81 +0,0 @@
1
- require 'spec_helper'
2
- require 'mongoid-rspec'
3
-
4
- describe Member do
5
-
6
- it { should have_fields(:trello_id, :username, :full_name, :avatar_id, :bio, :url) }
7
- it { should be_embedded_in(:effort) }
8
-
9
- describe "validation" do
10
- it { should validate_presence_of(:username) }
11
- end
12
-
13
- describe "equality" do
14
- it "is equal to another member with the same username" do
15
- member = Member.new(username: "piero")
16
- same_member = Member.new(username: "piero")
17
- different_member = Member.new(username: "tommaso")
18
-
19
- member.should == same_member
20
- member.should_not == different_member
21
- end
22
- end
23
-
24
- describe ".build_from" do
25
- it "builds a Member from a Trello Member" do
26
- member = Member.build_from(Trello::Member.new("username" => "piero"))
27
-
28
- member.username.should == "piero"
29
- end
30
-
31
- it "takes the Trello Member id and set it as trello_id" do
32
- member = Member.build_from(Trello::Member.new("username" => "piero", "id" => "1234567abc"))
33
-
34
- member.id.should_not == "1234567abc"
35
- member.trello_id.should == "1234567abc"
36
- end
37
- end
38
-
39
- describe "#effort_spent" do
40
- %w{piero tommaso}.each do |username|
41
- let(username.to_sym) { Member.new(username: username) }
42
- end
43
-
44
- let(:card) { TrackedCard.create(name: "any", short_id: 1234, trello_id: "123123") }
45
- let(:another_card) { TrackedCard.create(name: "any_other", short_id: 1235, trello_id: "123125") }
46
-
47
- it "is zero when the member did not spent effort at all" do
48
- piero.effort_spent.should == 0
49
- end
50
-
51
- it "counts the effort spent on a card" do
52
- card.efforts << Effort.new(amount: 4, date: Date.today, members: [piero, tommaso])
53
- card.efforts << Effort.new(amount: 5, date: Date.today, members: [tommaso])
54
-
55
- piero.effort_spent.should == 4 / 2
56
- end
57
-
58
- it "counts the effort spent on several cards" do
59
- card.efforts << Effort.new(amount: 4, date: Date.today, members: [piero, tommaso])
60
- another_card.efforts << Effort.new(amount: 5, date: Date.today, members: [piero])
61
-
62
- piero.effort_spent.should == 2 + 5
63
- end
64
-
65
- it "counts the effort spent on a card from a given date" do
66
- card.efforts << Effort.new(amount: 4, date: Date.yesterday, members: [piero])
67
- card.efforts << Effort.new(amount: 5, date: Date.today, members: [piero])
68
-
69
- piero.effort_spent(Date.today).should == 5
70
- piero.effort_spent_since(Date.today).should == 5
71
- end
72
-
73
- end
74
-
75
- describe "#avatar_url" do
76
- it "points to the avatar thumbnail image" do
77
- member = Member.new(avatar_id: "123xyz")
78
- member.avatar_url.should == "https://trello-avatars.s3.amazonaws.com/123xyz/30.png"
79
- end
80
- end
81
- end