trello_lead_time 0.1.0 → 0.1.1
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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/trello_lead_time/board.rb +33 -16
- data/lib/trello_lead_time/card.rb +22 -0
- data/lib/trello_lead_time/config.rb +10 -0
- data/lib/trello_lead_time/list.rb +31 -23
- data/lib/trello_lead_time/version.rb +1 -1
- data/spec/fixtures/comments.json +56 -0
- data/spec/fixtures/labels.json +1 -0
- data/spec/lib/trello_lead_time/board_spec.rb +75 -55
- data/spec/lib/trello_lead_time/card_spec.rb +54 -6
- data/spec/lib/trello_lead_time/config_spec.rb +46 -33
- data/spec/lib/trello_lead_time/list_spec.rb +95 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96f6e51efeac5483b81f0d5e226f9494accc8f5e
|
4
|
+
data.tar.gz: 0e1b9d7901f5ca08cc9e9b60bfb1444cfbe9cf19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e88d94eedadfd18d2220be613ff13ed068ac1f19f8f2b21996ee34a3a98db1f83aba20e0118b8af805b5ea541fef7d7fd3ca3b5e454ef9b2f509254324e7582
|
7
|
+
data.tar.gz: c5b5f7c476a369b9fc7f9c7fdfeeecf6da4305a4519a3f1316eefed4ff986938dbfb067c05d879fe83d38986053267179e3b90f8722bc983b5599ca8539e59bd
|
data/Gemfile.lock
CHANGED
@@ -21,28 +21,28 @@ module TrelloLeadTime
|
|
21
21
|
@trello_board.name
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
24
|
+
def totals(name_of_list_with_done_cards)
|
25
25
|
list = find_list_by_name(name_of_list_with_done_cards)
|
26
|
-
|
27
|
-
list.
|
28
|
-
end
|
26
|
+
response = default_format
|
27
|
+
return response if list.nil?
|
29
28
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
list.
|
29
|
+
response[:lead_time][:overall] = list.total_lead_time
|
30
|
+
response[:queue_time][:overall] = list.total_queue_time
|
31
|
+
response[:cycle_time][:overall] = list.total_cycle_time
|
32
|
+
response[:age][:overall] = list.total_age
|
33
|
+
response
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
36
|
+
def averages(name_of_list_with_done_cards)
|
37
37
|
list = find_list_by_name(name_of_list_with_done_cards)
|
38
|
-
|
39
|
-
list.
|
40
|
-
end
|
38
|
+
response = default_format
|
39
|
+
return response if list.nil?
|
41
40
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
list.
|
41
|
+
response[:lead_time][:overall] = list.average_lead_time
|
42
|
+
response[:queue_time][:overall] = list.average_queue_time
|
43
|
+
response[:cycle_time][:overall] = list.average_cycle_time
|
44
|
+
response[:age][:overall] = list.average_age
|
45
|
+
response
|
46
46
|
end
|
47
47
|
|
48
48
|
private
|
@@ -56,5 +56,22 @@ module TrelloLeadTime
|
|
56
56
|
@_lists[name]
|
57
57
|
end
|
58
58
|
|
59
|
+
def default_format
|
60
|
+
{
|
61
|
+
lead_time: default_entry,
|
62
|
+
queue_time: default_entry,
|
63
|
+
cycle_time: default_entry,
|
64
|
+
age: default_entry,
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def default_entry
|
69
|
+
{
|
70
|
+
overall: 0,
|
71
|
+
initiatives: {},
|
72
|
+
finance_types: {}
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
59
76
|
end
|
60
77
|
end
|
@@ -37,11 +37,33 @@ module TrelloLeadTime
|
|
37
37
|
@_cycle_time ||= sum_of_times_in_lists(Config.cycle_time_lists)
|
38
38
|
end
|
39
39
|
|
40
|
+
def has_label_name?(name)
|
41
|
+
match = labels.find { |l| l.name =~ /^#{Regexp.quote(name)}$/i }
|
42
|
+
!match.nil?
|
43
|
+
end
|
44
|
+
|
45
|
+
def has_label_color?(color)
|
46
|
+
match = labels.find { |l| l.color =~ /^#{Regexp.quote(color)}$/i }
|
47
|
+
!match.nil?
|
48
|
+
end
|
49
|
+
|
50
|
+
def hash_tags
|
51
|
+
comments.select { |comment| comment =~ /^#(.+)$/ } || []
|
52
|
+
end
|
53
|
+
|
40
54
|
private
|
41
55
|
|
42
56
|
def sum_of_times_in_lists(lists)
|
43
57
|
lists.inject(0) { |sum, list_name| sum + @timeline.seconds_in_list(list_name) }
|
44
58
|
end
|
45
59
|
|
60
|
+
def labels
|
61
|
+
@_labels ||= @trello_card.labels
|
62
|
+
end
|
63
|
+
|
64
|
+
def comments
|
65
|
+
@_comments ||= @trello_card.actions(filter:"commentCard").map { |comment| comment.data['text'] }
|
66
|
+
end
|
67
|
+
|
46
68
|
end
|
47
69
|
end
|
@@ -8,6 +8,7 @@ module TrelloLeadTime
|
|
8
8
|
attr_accessor :organization_name, :queue_time_lists, :cycle_time_lists, :list_name_matcher_for_done
|
9
9
|
|
10
10
|
def configure
|
11
|
+
reset!
|
11
12
|
yield self
|
12
13
|
end
|
13
14
|
|
@@ -33,4 +34,13 @@ module TrelloLeadTime
|
|
33
34
|
@list_name_matcher_for_done
|
34
35
|
end
|
35
36
|
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def reset!
|
41
|
+
@organization_name = nil
|
42
|
+
@queue_time_lists = nil
|
43
|
+
@cycle_time_lists = nil
|
44
|
+
@list_name_matcher_for_done = nil
|
45
|
+
end
|
36
46
|
end
|
@@ -12,50 +12,58 @@ module TrelloLeadTime
|
|
12
12
|
@trello_list.name
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
|
15
|
+
def total_lead_time
|
16
|
+
times = done_or_closed_cards.collect(&:lead_time)
|
17
|
+
total(times)
|
17
18
|
end
|
18
19
|
|
19
20
|
def average_lead_time
|
20
|
-
|
21
|
+
times = done_or_closed_cards.collect(&:lead_time)
|
22
|
+
average(times)
|
21
23
|
end
|
22
24
|
|
23
|
-
def
|
24
|
-
|
25
|
+
def total_queue_time
|
26
|
+
times = done_or_closed_cards.collect(&:queue_time)
|
27
|
+
total(times)
|
25
28
|
end
|
26
29
|
|
27
|
-
def
|
28
|
-
|
30
|
+
def average_queue_time
|
31
|
+
times = done_or_closed_cards.collect(&:queue_time)
|
32
|
+
average(times)
|
29
33
|
end
|
30
34
|
|
31
|
-
|
35
|
+
def total_cycle_time
|
36
|
+
times = done_or_closed_cards.collect(&:cycle_time)
|
37
|
+
total(times)
|
38
|
+
end
|
32
39
|
|
33
|
-
def
|
34
|
-
|
40
|
+
def average_cycle_time
|
41
|
+
times = done_or_closed_cards.collect(&:cycle_time)
|
42
|
+
average(times)
|
35
43
|
end
|
36
44
|
|
37
|
-
def
|
38
|
-
|
45
|
+
def total_age
|
46
|
+
times = done_or_closed_cards.collect(&:age_in_seconds)
|
47
|
+
total(times)
|
39
48
|
end
|
40
49
|
|
41
|
-
def
|
42
|
-
times = done_or_closed_cards.
|
50
|
+
def average_age
|
51
|
+
times = done_or_closed_cards.collect(&:age_in_seconds)
|
43
52
|
average(times)
|
44
53
|
end
|
45
54
|
|
46
|
-
|
47
|
-
|
48
|
-
|
55
|
+
private
|
56
|
+
|
57
|
+
def done_or_closed_cards
|
58
|
+
@_done_or_closed_cards ||= cards.select { |c| c.done? || c.closed? }
|
49
59
|
end
|
50
60
|
|
51
|
-
def
|
52
|
-
|
53
|
-
average(times)
|
61
|
+
def cards
|
62
|
+
@_cards ||= @trello_list.cards.map { |c| TrelloLeadTime::Card.from_trello_card(c) }
|
54
63
|
end
|
55
64
|
|
56
|
-
def
|
57
|
-
times
|
58
|
-
average(times)
|
65
|
+
def total(times)
|
66
|
+
times.inject(0) { |sum, el| sum + el }
|
59
67
|
end
|
60
68
|
|
61
69
|
def average(times)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"id": "666666",
|
4
|
+
"idMemberCreator": "555555",
|
5
|
+
"data": {
|
6
|
+
"board": {
|
7
|
+
"shortLink": "87361",
|
8
|
+
"name": "Mobile",
|
9
|
+
"id": "123456"
|
10
|
+
},
|
11
|
+
"card": {
|
12
|
+
"shortLink": "876361",
|
13
|
+
"idShort": 122,
|
14
|
+
"name": "some card name",
|
15
|
+
"id": "83716489"
|
16
|
+
},
|
17
|
+
"text": "This is not a hashtag"
|
18
|
+
},
|
19
|
+
"type": "commentCard",
|
20
|
+
"date": "2014-05-12T14:14:59.223Z",
|
21
|
+
"memberCreator": {
|
22
|
+
"id": "981736",
|
23
|
+
"avatarHash": "813747ajsdb",
|
24
|
+
"fullName": "John Tyler",
|
25
|
+
"initials": "JT",
|
26
|
+
"username": "johntyler"
|
27
|
+
}
|
28
|
+
},
|
29
|
+
{
|
30
|
+
"id": "666666",
|
31
|
+
"idMemberCreator": "555555",
|
32
|
+
"data": {
|
33
|
+
"board": {
|
34
|
+
"shortLink": "87361",
|
35
|
+
"name": "Mobile",
|
36
|
+
"id": "123456"
|
37
|
+
},
|
38
|
+
"card": {
|
39
|
+
"shortLink": "876361",
|
40
|
+
"idShort": 122,
|
41
|
+
"name": "some card name",
|
42
|
+
"id": "83716489"
|
43
|
+
},
|
44
|
+
"text": "#myhashtag"
|
45
|
+
},
|
46
|
+
"type": "commentCard",
|
47
|
+
"date": "2014-05-12T14:14:59.223Z",
|
48
|
+
"memberCreator": {
|
49
|
+
"id": "981736",
|
50
|
+
"avatarHash": "813747ajsdb",
|
51
|
+
"fullName": "John Tyler",
|
52
|
+
"initials": "JT",
|
53
|
+
"username": "johntyler"
|
54
|
+
}
|
55
|
+
}
|
56
|
+
]
|
@@ -0,0 +1 @@
|
|
1
|
+
[{"color":"green","name":"iOS"},{"color":"red","name":"API"}]
|
@@ -4,79 +4,99 @@ describe TrelloLeadTime::Board do
|
|
4
4
|
let(:key) { "key" }
|
5
5
|
let(:token) { "token" }
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
7
|
+
let(:organization_id) { "myorg_id" }
|
8
|
+
let(:organization_name) { "myorg_name" }
|
9
|
+
let(:url) { "https://trello.com/#{organization_name}" }
|
10
|
+
let(:board_url) { "http://trello.com/b/1234/board_name" }
|
11
|
+
let(:board_id) { "myboard_id" }
|
12
|
+
let(:board_name) { "Development Team" }
|
13
|
+
let(:list_with_done_cards) { "Done for 2014-03" }
|
14
|
+
let(:list_id) { "mylist_id" }
|
15
|
+
let(:card_id) { "mycard_id" }
|
16
|
+
|
17
|
+
let(:organization_json) {
|
18
|
+
File.read(File.expand_path("../../../fixtures/organization.json", __FILE__))
|
19
|
+
}
|
20
|
+
|
21
|
+
let(:boards_json) {
|
22
|
+
File.read(File.expand_path("../../../fixtures/boards.json", __FILE__))
|
23
|
+
}
|
24
|
+
|
25
|
+
let(:lists_json) {
|
26
|
+
File.read(File.expand_path("../../../fixtures/lists.json", __FILE__))
|
27
|
+
}
|
28
|
+
|
29
|
+
let(:cards_json) {
|
30
|
+
File.read(File.expand_path("../../../fixtures/cards.json", __FILE__))
|
31
|
+
}
|
32
|
+
|
33
|
+
let(:actions_json) {
|
34
|
+
{
|
35
|
+
"1111" => File.read(File.expand_path("../../../fixtures/actions.1111.json", __FILE__)),
|
36
|
+
"2222" => File.read(File.expand_path("../../../fixtures/actions.2222.json", __FILE__)),
|
37
|
+
"3333" => File.read(File.expand_path("../../../fixtures/actions.3333.json", __FILE__)),
|
38
|
+
"4444" => File.read(File.expand_path("../../../fixtures/actions.4444.json", __FILE__))
|
20
39
|
}
|
40
|
+
}
|
21
41
|
|
22
|
-
|
23
|
-
File.read(File.expand_path("../../../fixtures/boards.json", __FILE__))
|
24
|
-
}
|
42
|
+
subject { TrelloLeadTime::Board.from_url(board_url) }
|
25
43
|
|
26
|
-
|
27
|
-
|
28
|
-
}
|
44
|
+
describe ".totals" do
|
45
|
+
let(:totals) { subject.totals(list_with_done_cards) }
|
29
46
|
|
30
|
-
|
31
|
-
|
32
|
-
|
47
|
+
it "should have an overall lead time" do
|
48
|
+
stub_all_requests
|
49
|
+
totals[:lead_time][:overall].should == 4512370
|
50
|
+
end
|
33
51
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
"3333" => File.read(File.expand_path("../../../fixtures/actions.3333.json", __FILE__)),
|
39
|
-
"4444" => File.read(File.expand_path("../../../fixtures/actions.4444.json", __FILE__))
|
40
|
-
}
|
41
|
-
}
|
52
|
+
it "should have an overall queue time" do
|
53
|
+
stub_all_requests
|
54
|
+
totals[:queue_time][:overall].should == 2697355
|
55
|
+
end
|
42
56
|
|
43
|
-
|
57
|
+
it "should have an overall cycle time" do
|
58
|
+
stub_all_requests
|
59
|
+
totals[:cycle_time][:overall].should == 1815015
|
60
|
+
end
|
44
61
|
|
45
|
-
it "should
|
46
|
-
|
47
|
-
|
62
|
+
it "should have an overall age" do
|
63
|
+
stub_all_requests
|
64
|
+
totals[:age][:overall].should == 4512370
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe ".averages" do
|
69
|
+
let(:averages) { subject.averages(list_with_done_cards) }
|
70
|
+
|
71
|
+
it "should have an overall lead time" do
|
72
|
+
stub_all_requests
|
73
|
+
averages[:lead_time][:overall].should == 1128093
|
48
74
|
end
|
49
75
|
|
50
|
-
it "should have
|
51
|
-
|
52
|
-
|
53
|
-
stub_card_requests
|
54
|
-
lead_time = subject.average_lead_time(list_with_done_cards)
|
55
|
-
# 13 days 1 hours 21 minutes 33 seconds
|
56
|
-
lead_time.should == 1128093
|
76
|
+
it "should have an overall queue time" do
|
77
|
+
stub_all_requests
|
78
|
+
averages[:queue_time][:overall].should == 674339
|
57
79
|
end
|
58
80
|
|
59
|
-
it "should have
|
60
|
-
|
61
|
-
|
62
|
-
stub_card_requests
|
63
|
-
queue_time = subject.average_queue_time(list_with_done_cards)
|
64
|
-
# 7 days 19 hours 18 minutes 59 seconds
|
65
|
-
queue_time.should == 674339
|
81
|
+
it "should have an overall cycle time" do
|
82
|
+
stub_all_requests
|
83
|
+
averages[:cycle_time][:overall].should == 453754
|
66
84
|
end
|
67
85
|
|
68
|
-
it "should have
|
69
|
-
|
70
|
-
|
71
|
-
stub_card_requests
|
72
|
-
cycle_time = subject.average_cycle_time(list_with_done_cards)
|
73
|
-
# 5 days 6 hours 2 minutes 34 seconds
|
74
|
-
cycle_time.should == 453754
|
86
|
+
it "should have an overall age" do
|
87
|
+
stub_all_requests
|
88
|
+
averages[:age][:overall].should == 1128093
|
75
89
|
end
|
76
90
|
end
|
77
91
|
|
78
92
|
private
|
79
93
|
|
94
|
+
def stub_all_requests
|
95
|
+
stub_board_requests
|
96
|
+
stub_list_requests
|
97
|
+
stub_card_requests
|
98
|
+
end
|
99
|
+
|
80
100
|
def stub_board_requests
|
81
101
|
stub_request(:get, "https://api.trello.com/1/organizations/wellmatch?key=#{key}&token=#{token}").
|
82
102
|
with(headers).
|
@@ -9,16 +9,64 @@ describe TrelloLeadTime::Card do
|
|
9
9
|
let(:actions_json) {
|
10
10
|
File.read(File.expand_path("../../../fixtures/actions.1111.json", __FILE__))
|
11
11
|
}
|
12
|
+
let(:labels_json) {
|
13
|
+
File.read(File.expand_path("../../../fixtures/labels.json", __FILE__))
|
14
|
+
}
|
15
|
+
let(:comments_json) {
|
16
|
+
File.read(File.expand_path("../../../fixtures/comments.json", __FILE__))
|
17
|
+
}
|
12
18
|
|
13
|
-
|
14
|
-
subject { TrelloLeadTime::Card.from_trello_card(Trello::Card.parse(card_json)) }
|
19
|
+
subject { TrelloLeadTime::Card.from_trello_card(Trello::Card.parse(card_json)) }
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
def do_stubs(key, token)
|
22
|
+
stub_request(:get, "https://api.trello.com/1/cards/533dd01513e035206902124c/actions?filter=createCard,updateCard:idList,updateCard:closed&key=#{key}&token=#{token}").
|
23
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}).
|
24
|
+
to_return(:status => 200, :body => actions_json, :headers => {})
|
25
|
+
|
26
|
+
stub_request(:get, "https://api.trello.com/1/cards/533dd01513e035206902124c/labels?key=#{key}&token=#{token}").
|
27
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}).
|
28
|
+
to_return(:status => 200, :body => labels_json, :headers => {})
|
20
29
|
|
30
|
+
stub_request(:get, "https://api.trello.com/1/cards/533dd01513e035206902124c/actions?filter=commentCard&key=#{key}&token=#{token}").
|
31
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}).
|
32
|
+
to_return(:status => 200, :body => comments_json, :headers => {})
|
33
|
+
end
|
34
|
+
|
35
|
+
describe ".done" do
|
36
|
+
it "should be a card" do
|
37
|
+
do_stubs(key, token)
|
21
38
|
subject.should be_an_instance_of(TrelloLeadTime::Card)
|
22
39
|
end
|
23
40
|
end
|
41
|
+
|
42
|
+
describe ".hash_tags" do
|
43
|
+
it "should have a hash tag" do
|
44
|
+
do_stubs(key, token)
|
45
|
+
expect(subject.hash_tags).to eq(['#myhashtag'])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe ".has_label_name?" do
|
50
|
+
it "should not have a named label" do
|
51
|
+
do_stubs(key, token)
|
52
|
+
subject.has_label_name?("blah").should be_false
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should have a named label" do
|
56
|
+
do_stubs(key, token)
|
57
|
+
subject.has_label_name?("ios").should be_true
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe ".has_label_color?" do
|
62
|
+
it "should not have a color label" do
|
63
|
+
do_stubs(key, token)
|
64
|
+
subject.has_label_color?("yellow").should be_false
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should have a color label" do
|
68
|
+
do_stubs(key, token)
|
69
|
+
subject.has_label_color?("Green").should be_true
|
70
|
+
end
|
71
|
+
end
|
24
72
|
end
|
@@ -1,50 +1,63 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe TrelloLeadTime::Config do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
TrelloLeadTime.
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
subject { TrelloLeadTime::Config }
|
5
|
+
before(:all) do
|
6
|
+
@cfg = {
|
7
|
+
organization_name: TrelloLeadTime::Config.organization_name,
|
8
|
+
queue_time_lists: TrelloLeadTime::Config.queue_time_lists,
|
9
|
+
cycle_time_lists: TrelloLeadTime::Config.cycle_time_lists,
|
10
|
+
list_name_matcher_for_done: TrelloLeadTime::Config.list_name_matcher_for_done
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
after(:all) do
|
15
|
+
TrelloLeadTime.configure do |cfg|
|
16
|
+
cfg.queue_time_lists = @cfg[:queue_time_lists]
|
17
|
+
cfg.cycle_time_lists = @cfg[:cycle_time_lists]
|
18
|
+
cfg.organization_name = @cfg[:organization_name]
|
19
|
+
cfg.list_name_matcher_for_done = @cfg[:list_name_matcher_for_done]
|
12
20
|
end
|
21
|
+
end
|
13
22
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
subject.queue_time_lists.should include("my list")
|
23
|
+
it "should have default empty list for queue time lists" do
|
24
|
+
TrelloLeadTime.configure do |cfg|
|
25
|
+
cfg.queue_time_lists = nil
|
19
26
|
end
|
27
|
+
subject.queue_time_lists.should be_empty
|
28
|
+
end
|
20
29
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
subject.cycle_time_lists.should be_empty
|
30
|
+
it "should set queue time lists" do
|
31
|
+
TrelloLeadTime.configure do |cfg|
|
32
|
+
cfg.queue_time_lists = ["my list"]
|
26
33
|
end
|
34
|
+
subject.queue_time_lists.should include("my list")
|
35
|
+
end
|
27
36
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
subject.cycle_time_lists.should include("my list")
|
37
|
+
it "should have default empty list for cycle time lists" do
|
38
|
+
TrelloLeadTime.configure do |cfg|
|
39
|
+
cfg.cycle_time_lists = nil
|
33
40
|
end
|
41
|
+
subject.cycle_time_lists.should be_empty
|
42
|
+
end
|
34
43
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
expect(subject.list_name_matcher_for_done).to eq(/^Done/i)
|
44
|
+
it "should set cycle time lists" do
|
45
|
+
TrelloLeadTime.configure do |cfg|
|
46
|
+
cfg.cycle_time_lists = ["my list"]
|
40
47
|
end
|
48
|
+
subject.cycle_time_lists.should include("my list")
|
49
|
+
end
|
41
50
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
expect(subject.list_name_matcher_for_done).to eq(/^Live/)
|
51
|
+
it "should have default done matcher" do
|
52
|
+
TrelloLeadTime.configure do |cfg|
|
53
|
+
cfg.list_name_matcher_for_done = nil
|
47
54
|
end
|
55
|
+
expect(subject.list_name_matcher_for_done).to eq(/^Done/i)
|
56
|
+
end
|
48
57
|
|
58
|
+
it "should set a default done matcher" do
|
59
|
+
TrelloLeadTime.configure do |cfg|
|
60
|
+
cfg.list_name_matcher_for_done = /^Live/ end
|
61
|
+
expect(subject.list_name_matcher_for_done).to eq(/^Live/)
|
49
62
|
end
|
50
63
|
end
|
@@ -1,6 +1,100 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe TrelloLeadTime::List do
|
4
|
-
|
4
|
+
let(:key) { "key" }
|
5
|
+
let(:token) { "token" }
|
6
|
+
|
7
|
+
let(:list) {
|
8
|
+
l = Trello::List.new
|
9
|
+
l.attributes[:id] = 12345
|
10
|
+
l.attributes[:name] = 'Test List'
|
11
|
+
l.attributes[:closed] = false
|
12
|
+
l.attributes[:board_id] = 67890
|
13
|
+
l.attributes[:pos] = 1
|
14
|
+
l
|
15
|
+
}
|
16
|
+
|
17
|
+
let(:cards_json) {
|
18
|
+
File.read(File.expand_path("../../../fixtures/cards.json", __FILE__))
|
19
|
+
}
|
20
|
+
|
21
|
+
let(:actions_json) {
|
22
|
+
{
|
23
|
+
"1111" => File.read(File.expand_path("../../../fixtures/actions.1111.json", __FILE__)),
|
24
|
+
"2222" => File.read(File.expand_path("../../../fixtures/actions.2222.json", __FILE__)),
|
25
|
+
"3333" => File.read(File.expand_path("../../../fixtures/actions.3333.json", __FILE__)),
|
26
|
+
"4444" => File.read(File.expand_path("../../../fixtures/actions.4444.json", __FILE__))
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
subject { TrelloLeadTime::List.from_trello_list(list) }
|
31
|
+
|
32
|
+
it "should have an average age" do
|
33
|
+
stub_all_requests
|
34
|
+
subject.average_age.should == 1128093
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have a total age" do
|
38
|
+
stub_all_requests
|
39
|
+
subject.total_age.should == 4512370
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should have a average lead time" do
|
43
|
+
stub_all_requests
|
44
|
+
subject.average_lead_time.should == 1128093
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should have a total lead time" do
|
48
|
+
stub_all_requests
|
49
|
+
subject.total_lead_time.should == 4512370
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should have a average queue time" do
|
53
|
+
stub_all_requests
|
54
|
+
subject.average_queue_time.should == 674339
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should have a total queue time" do
|
58
|
+
stub_all_requests
|
59
|
+
subject.total_queue_time.should == 2697355
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should have a average cycle time" do
|
63
|
+
stub_all_requests
|
64
|
+
subject.average_cycle_time.should == 453754
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should have a total cycle time" do
|
68
|
+
stub_all_requests
|
69
|
+
subject.total_cycle_time.should == 1815015
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def stub_all_requests
|
75
|
+
stub_list_requests
|
76
|
+
stub_card_requests
|
77
|
+
end
|
78
|
+
|
79
|
+
def stub_list_requests
|
80
|
+
stub_request(:get, "https://api.trello.com/1/lists/#{list.id}/cards?filter=open&key=#{key}&token=#{token}").
|
81
|
+
with(headers).
|
82
|
+
to_return(stub_returns(cards_json))
|
83
|
+
end
|
84
|
+
|
85
|
+
def stub_card_requests
|
86
|
+
%w{1111 2222 3333 4444}.each do |card_id|
|
87
|
+
stub_request(:get, "https://api.trello.com/1/cards/#{card_id}/actions?filter=createCard,updateCard:idList,updateCard:closed&key=#{key}&token=#{token}").
|
88
|
+
with(headers).
|
89
|
+
to_return(stub_returns(actions_json[card_id]))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def headers
|
94
|
+
{ headers: {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'} }
|
95
|
+
end
|
96
|
+
|
97
|
+
def stub_returns(json)
|
98
|
+
{ status: 200, body: json, headers: {} }
|
5
99
|
end
|
6
100
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trello_lead_time
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Baldwin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -86,6 +86,8 @@ files:
|
|
86
86
|
- spec/fixtures/boards.json
|
87
87
|
- spec/fixtures/card.json
|
88
88
|
- spec/fixtures/cards.json
|
89
|
+
- spec/fixtures/comments.json
|
90
|
+
- spec/fixtures/labels.json
|
89
91
|
- spec/fixtures/lists.json
|
90
92
|
- spec/fixtures/organization.json
|
91
93
|
- spec/lib/trello_lead_time/array_matcher_spec.rb
|
@@ -129,6 +131,8 @@ test_files:
|
|
129
131
|
- spec/fixtures/boards.json
|
130
132
|
- spec/fixtures/card.json
|
131
133
|
- spec/fixtures/cards.json
|
134
|
+
- spec/fixtures/comments.json
|
135
|
+
- spec/fixtures/labels.json
|
132
136
|
- spec/fixtures/lists.json
|
133
137
|
- spec/fixtures/organization.json
|
134
138
|
- spec/lib/trello_lead_time/array_matcher_spec.rb
|