trello_lead_time 0.0.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 +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
|