tracco 0.0.14 → 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
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