trello_lead_time 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +81 -0
- data/LICENSE.md +21 -0
- data/README.md +88 -0
- data/Rakefile +1 -0
- data/lib/trello_lead_time.rb +10 -0
- data/lib/trello_lead_time/action.rb +23 -0
- data/lib/trello_lead_time/board.rb +58 -0
- data/lib/trello_lead_time/card.rb +47 -0
- data/lib/trello_lead_time/config.rb +36 -0
- data/lib/trello_lead_time/list.rb +69 -0
- data/lib/trello_lead_time/time_humanizer.rb +13 -0
- data/lib/trello_lead_time/timeline.rb +142 -0
- data/lib/trello_lead_time/version.rb +3 -0
- data/sample.rb +33 -0
- data/spec/fixtures/actions.1111.json +146 -0
- data/spec/fixtures/actions.2222.json +146 -0
- data/spec/fixtures/actions.3333.json +146 -0
- data/spec/fixtures/actions.4444.json +146 -0
- data/spec/fixtures/boards.json +112 -0
- data/spec/fixtures/card.json +45 -0
- data/spec/fixtures/cards.json +18 -0
- data/spec/fixtures/lists.json +10 -0
- data/spec/fixtures/organization.json +12 -0
- data/spec/lib/trello_lead_time/board_spec.rb +115 -0
- data/spec/lib/trello_lead_time/card_spec.rb +24 -0
- data/spec/lib/trello_lead_time/config_spec.rb +50 -0
- data/spec/lib/trello_lead_time/list_spec.rb +6 -0
- data/spec/lib/trello_lead_time/time_humanizer_spec.rb +12 -0
- data/spec/lib/trello_lead_time_spec.rb +9 -0
- data/spec/spec_helper.rb +14 -0
- data/trello_lead_time.gemspec +23 -0
- metadata +124 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"id": "1111",
|
4
|
+
"name": "(2) ANALYTICS: Track events for tutorial and training video"
|
5
|
+
},
|
6
|
+
{
|
7
|
+
"id": "2222",
|
8
|
+
"name": "(0) Remove any W numbers that end in - 01 or 01"
|
9
|
+
},
|
10
|
+
{
|
11
|
+
"id": "3333",
|
12
|
+
"name": "(3) SEARCH 2.0: Hit HL typeahead and apply filtering/fallbacks"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"id": "4444",
|
16
|
+
"name": "(3) ADMIN: Search for members by plan sponsor and plan"
|
17
|
+
}
|
18
|
+
]
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TrelloLeadTime::Board do
|
4
|
+
let(:key) { "key" }
|
5
|
+
let(:token) { "token" }
|
6
|
+
|
7
|
+
describe ".from_url" do
|
8
|
+
let(:organization_id) { "myorg_id" }
|
9
|
+
let(:organization_name) { "myorg_name" }
|
10
|
+
let(:url) { "https://trello.com/#{organization_name}" }
|
11
|
+
let(:board_url) { "http://trello.com/b/1234/board_name" }
|
12
|
+
let(:board_id) { "myboard_id" }
|
13
|
+
let(:board_name) { "Development Team" }
|
14
|
+
let(:list_with_done_cards) { "Done for 2014-03" }
|
15
|
+
let(:list_id) { "mylist_id" }
|
16
|
+
let(:card_id) { "mycard_id" }
|
17
|
+
|
18
|
+
let(:organization_json) {
|
19
|
+
File.read(File.expand_path("../../../fixtures/organization.json", __FILE__))
|
20
|
+
}
|
21
|
+
|
22
|
+
let(:boards_json) {
|
23
|
+
File.read(File.expand_path("../../../fixtures/boards.json", __FILE__))
|
24
|
+
}
|
25
|
+
|
26
|
+
let(:lists_json) {
|
27
|
+
File.read(File.expand_path("../../../fixtures/lists.json", __FILE__))
|
28
|
+
}
|
29
|
+
|
30
|
+
let(:cards_json) {
|
31
|
+
File.read(File.expand_path("../../../fixtures/cards.json", __FILE__))
|
32
|
+
}
|
33
|
+
|
34
|
+
let(:actions_json) {
|
35
|
+
{
|
36
|
+
"1111" => File.read(File.expand_path("../../../fixtures/actions.1111.json", __FILE__)),
|
37
|
+
"2222" => File.read(File.expand_path("../../../fixtures/actions.2222.json", __FILE__)),
|
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
|
+
}
|
42
|
+
|
43
|
+
subject { TrelloLeadTime::Board.from_url(board_url) }
|
44
|
+
|
45
|
+
it "should return a board" do
|
46
|
+
stub_board_requests
|
47
|
+
subject.should be_an_instance_of(TrelloLeadTime::Board)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should have a lead time" do
|
51
|
+
stub_board_requests
|
52
|
+
stub_list_requests
|
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
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should have a queue time" do
|
60
|
+
stub_board_requests
|
61
|
+
stub_list_requests
|
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
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should have a cycle time" do
|
69
|
+
stub_board_requests
|
70
|
+
stub_list_requests
|
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
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def stub_board_requests
|
81
|
+
stub_request(:get, "https://api.trello.com/1/organizations/wellmatch?key=#{key}&token=#{token}").
|
82
|
+
with(headers).
|
83
|
+
to_return(stub_returns(organization_json))
|
84
|
+
|
85
|
+
stub_request(:get, "https://api.trello.com/1/organizations/#{organization_id}/boards/all?key=#{key}&token=#{token}").
|
86
|
+
with(headers).
|
87
|
+
to_return(stub_returns(boards_json))
|
88
|
+
end
|
89
|
+
|
90
|
+
def stub_list_requests
|
91
|
+
stub_request(:get, "https://api.trello.com/1/boards/#{board_id}/lists?filter=all&key=#{key}&token=#{token}").
|
92
|
+
with(headers).
|
93
|
+
to_return(stub_returns(lists_json))
|
94
|
+
|
95
|
+
stub_request(:get, "https://api.trello.com/1/lists/#{list_id}/cards?filter=open&key=#{key}&token=#{token}").
|
96
|
+
with(headers).
|
97
|
+
to_return(stub_returns(cards_json))
|
98
|
+
end
|
99
|
+
|
100
|
+
def stub_card_requests
|
101
|
+
%w{1111 2222 3333 4444}.each do |card_id|
|
102
|
+
stub_request(:get, "https://api.trello.com/1/cards/#{card_id}/actions?filter=createCard,updateCard:idList,updateCard:closed&key=#{key}&token=#{token}").
|
103
|
+
with(headers).
|
104
|
+
to_return(stub_returns(actions_json[card_id]))
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def headers
|
109
|
+
{ headers: {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'} }
|
110
|
+
end
|
111
|
+
|
112
|
+
def stub_returns(json)
|
113
|
+
{ status: 200, body: json, headers: {} }
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TrelloLeadTime::Card do
|
4
|
+
let(:key) { 'key' }
|
5
|
+
let(:token) { 'token' }
|
6
|
+
let(:card_json) {
|
7
|
+
File.read(File.expand_path("../../../fixtures/card.json", __FILE__))
|
8
|
+
}
|
9
|
+
let(:actions_json) {
|
10
|
+
File.read(File.expand_path("../../../fixtures/actions.1111.json", __FILE__))
|
11
|
+
}
|
12
|
+
|
13
|
+
describe ".done" do
|
14
|
+
subject { TrelloLeadTime::Card.from_trello_card(Trello::Card.parse(card_json)) }
|
15
|
+
|
16
|
+
it "should be a card" do
|
17
|
+
stub_request(:get, "https://api.trello.com/1/cards/533dd01513e035206902124c/actions?filter=createCard,updateCard:idList,updateCard:closed&key=#{key}&token=#{token}").
|
18
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}).
|
19
|
+
to_return(:status => 200, :body => actions_json, :headers => {})
|
20
|
+
|
21
|
+
subject.should be_an_instance_of(TrelloLeadTime::Card)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TrelloLeadTime::Config do
|
4
|
+
describe ".add_queue_time_list" do
|
5
|
+
subject { TrelloLeadTime::Config }
|
6
|
+
|
7
|
+
it "should have default empty list for queue time lists" do
|
8
|
+
TrelloLeadTime.configure do |cfg|
|
9
|
+
cfg.queue_time_lists = nil
|
10
|
+
end
|
11
|
+
subject.queue_time_lists.should be_empty
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should set queue time lists" do
|
15
|
+
TrelloLeadTime.configure do |cfg|
|
16
|
+
cfg.queue_time_lists = ["my list"]
|
17
|
+
end
|
18
|
+
subject.queue_time_lists.should include("my list")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have default empty list for cycle time lists" do
|
22
|
+
TrelloLeadTime.configure do |cfg|
|
23
|
+
cfg.cycle_time_lists = nil
|
24
|
+
end
|
25
|
+
subject.cycle_time_lists.should be_empty
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should set cycle time lists" do
|
29
|
+
TrelloLeadTime.configure do |cfg|
|
30
|
+
cfg.cycle_time_lists = ["my list"]
|
31
|
+
end
|
32
|
+
subject.cycle_time_lists.should include("my list")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should have default done matcher" do
|
36
|
+
TrelloLeadTime.configure do |cfg|
|
37
|
+
cfg.list_name_matcher_for_done = nil
|
38
|
+
end
|
39
|
+
expect(subject.list_name_matcher_for_done).to eq(/^Done/i)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should set a default done matcher" do
|
43
|
+
TrelloLeadTime.configure do |cfg|
|
44
|
+
cfg.list_name_matcher_for_done = /^Live/
|
45
|
+
end
|
46
|
+
expect(subject.list_name_matcher_for_done).to eq(/^Live/)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TrelloLeadTime::TimeHumanizer do
|
4
|
+
describe ".humanize_seconds" do
|
5
|
+
let(:seconds) { 428155 }
|
6
|
+
subject { TrelloLeadTime::TimeHumanizer.humanize_seconds(seconds) }
|
7
|
+
|
8
|
+
it "should have days, hours, mins, and seconds" do
|
9
|
+
subject.should == "4 days 22 hours 55 minutes 55 seconds"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'trello_lead_time'
|
2
|
+
require 'webmock/rspec'
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
config.before(:suite) do
|
6
|
+
TrelloLeadTime.configure do |cfg|
|
7
|
+
cfg.organization_name = 'wellmatch'
|
8
|
+
cfg.set_trello_key_and_token('key', 'token')
|
9
|
+
cfg.queue_time_lists = ['Product Backlog']
|
10
|
+
cfg.cycle_time_lists = ['Development', 'Acceptance']
|
11
|
+
cfg.list_name_matcher_for_done = /^Done/i
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'trello_lead_time/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'trello_lead_time'
|
8
|
+
spec.version = TrelloLeadTime::VERSION
|
9
|
+
spec.authors = ['Scott Baldwin']
|
10
|
+
spec.email = ['scottsbaldwin@gmail.com']
|
11
|
+
spec.summary = %q{Lead and cycle time calculator for Trello boards.}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = 'https://github.com/scottsbaldwin/trello_lead_time'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: trello_lead_time
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Scott Baldwin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: ''
|
42
|
+
email:
|
43
|
+
- scottsbaldwin@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- .gitignore
|
49
|
+
- .rspec
|
50
|
+
- .ruby-gemset
|
51
|
+
- .ruby-version
|
52
|
+
- Gemfile
|
53
|
+
- Gemfile.lock
|
54
|
+
- LICENSE.md
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- lib/trello_lead_time.rb
|
58
|
+
- lib/trello_lead_time/action.rb
|
59
|
+
- lib/trello_lead_time/board.rb
|
60
|
+
- lib/trello_lead_time/card.rb
|
61
|
+
- lib/trello_lead_time/config.rb
|
62
|
+
- lib/trello_lead_time/list.rb
|
63
|
+
- lib/trello_lead_time/time_humanizer.rb
|
64
|
+
- lib/trello_lead_time/timeline.rb
|
65
|
+
- lib/trello_lead_time/version.rb
|
66
|
+
- sample.rb
|
67
|
+
- spec/fixtures/actions.1111.json
|
68
|
+
- spec/fixtures/actions.2222.json
|
69
|
+
- spec/fixtures/actions.3333.json
|
70
|
+
- spec/fixtures/actions.4444.json
|
71
|
+
- spec/fixtures/boards.json
|
72
|
+
- spec/fixtures/card.json
|
73
|
+
- spec/fixtures/cards.json
|
74
|
+
- spec/fixtures/lists.json
|
75
|
+
- spec/fixtures/organization.json
|
76
|
+
- spec/lib/trello_lead_time/board_spec.rb
|
77
|
+
- spec/lib/trello_lead_time/card_spec.rb
|
78
|
+
- spec/lib/trello_lead_time/config_spec.rb
|
79
|
+
- spec/lib/trello_lead_time/list_spec.rb
|
80
|
+
- spec/lib/trello_lead_time/time_humanizer_spec.rb
|
81
|
+
- spec/lib/trello_lead_time_spec.rb
|
82
|
+
- spec/spec_helper.rb
|
83
|
+
- trello_lead_time.gemspec
|
84
|
+
homepage: https://github.com/scottsbaldwin/trello_lead_time
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 2.0.7
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: Lead and cycle time calculator for Trello boards.
|
108
|
+
test_files:
|
109
|
+
- spec/fixtures/actions.1111.json
|
110
|
+
- spec/fixtures/actions.2222.json
|
111
|
+
- spec/fixtures/actions.3333.json
|
112
|
+
- spec/fixtures/actions.4444.json
|
113
|
+
- spec/fixtures/boards.json
|
114
|
+
- spec/fixtures/card.json
|
115
|
+
- spec/fixtures/cards.json
|
116
|
+
- spec/fixtures/lists.json
|
117
|
+
- spec/fixtures/organization.json
|
118
|
+
- spec/lib/trello_lead_time/board_spec.rb
|
119
|
+
- spec/lib/trello_lead_time/card_spec.rb
|
120
|
+
- spec/lib/trello_lead_time/config_spec.rb
|
121
|
+
- spec/lib/trello_lead_time/list_spec.rb
|
122
|
+
- spec/lib/trello_lead_time/time_humanizer_spec.rb
|
123
|
+
- spec/lib/trello_lead_time_spec.rb
|
124
|
+
- spec/spec_helper.rb
|