pain 0.0.3 → 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 +5 -5
- data/.rubocop.yml +3 -2
- data/Gemfile +4 -2
- data/Rakefile +2 -1
- data/bin/.rubocop.yml +0 -0
- data/bin/pain +2 -135
- data/lib/pain.rb +5 -58
- data/lib/pain/cli.rb +164 -0
- data/lib/pain/color_strings.rb +11 -0
- data/lib/pain/model.rb +79 -0
- data/lib/pain/version.rb +3 -1
- data/pain.gemspec +4 -3
- data/spec/model_spec.rb +26 -0
- data/spec/spec_helper.rb +0 -1
- metadata +50 -38
- data/spec/normalize_spec.rb +0 -16
- data/spec/user_pain_spec.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7ed10c1b52b39337e13741f8cc57fb41e8b116c5e7f41a8438af2bb441d19a68
|
4
|
+
data.tar.gz: 10fb7b20f0fafaf75c2e2c3e06c638939b50dae86eca5e1f54442e1a2abb044b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc3fc6de280eac3f11662545ee19d6dea0d982fe56a8fc994f637c6a3f61bf6778c84483a2503c2ee8c47e3c23169e991e9fc325b4cc2c4054012b4d6824ab90
|
7
|
+
data.tar.gz: 24f06280c62da6d1a3e745f27d35b109bc29c4512ad0c1160452c886c7356b1da70e6bd3d1dc995798f0f6ca535ddcbc0b22d804bf1a3181e27f0b81240c43a9
|
data/.rubocop.yml
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/bin/.rubocop.yml
CHANGED
File without changes
|
data/bin/pain
CHANGED
@@ -1,140 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'bundler/setup'
|
4
|
-
require 'term/ansicolor'
|
5
5
|
require 'pain'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
class String
|
10
|
-
include Term::ANSIColor
|
11
|
-
end
|
12
|
-
|
13
|
-
def get_color(value)
|
14
|
-
offset = case value
|
15
|
-
when :trivial
|
16
|
-
40
|
17
|
-
when :minor
|
18
|
-
69
|
19
|
-
when :standard
|
20
|
-
184
|
21
|
-
when :major
|
22
|
-
202
|
23
|
-
when :critical
|
24
|
-
9
|
25
|
-
else
|
26
|
-
252
|
27
|
-
end
|
28
|
-
Term::ANSIColor::Attribute[offset]
|
29
|
-
end
|
30
|
-
|
31
|
-
def case_danger(danger)
|
32
|
-
if danger < 0.21
|
33
|
-
:trivial
|
34
|
-
elsif danger < 0.41
|
35
|
-
:minor
|
36
|
-
elsif danger < 0.65
|
37
|
-
:standard
|
38
|
-
elsif danger < 0.81
|
39
|
-
:major
|
40
|
-
else
|
41
|
-
:critical
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def total_danger(danger)
|
46
|
-
if danger < 21
|
47
|
-
:trivial
|
48
|
-
elsif danger < 31
|
49
|
-
:minor
|
50
|
-
elsif danger < 51
|
51
|
-
:standard
|
52
|
-
elsif danger < 75
|
53
|
-
:major
|
54
|
-
else
|
55
|
-
:critical
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def color_output(msg, danger = :normal)
|
60
|
-
level = if danger == :normal
|
61
|
-
:default
|
62
|
-
elsif danger.is_a? Symbol
|
63
|
-
danger
|
64
|
-
else
|
65
|
-
case_danger(danger)
|
66
|
-
end
|
67
|
-
puts msg.color(get_color(level))
|
68
|
-
end
|
69
|
-
|
70
|
-
def display_options_for(input)
|
71
|
-
ceiling = Pain::OPTIONS[input].count
|
72
|
-
Pain::OPTIONS[input].each do |v, msg|
|
73
|
-
color_output("#{v}: #{msg}", (v / ceiling.to_f))
|
74
|
-
end
|
75
|
-
puts
|
76
|
-
end
|
77
|
-
|
78
|
-
def ask_question_for(input)
|
79
|
-
color_output Pain::INPUT_MESSAGE[input]
|
80
|
-
end
|
81
|
-
|
82
|
-
def print_report_for(o)
|
83
|
-
pain = Pain.user_pain(o[:bug_type], o[:likelihood], o[:impact])
|
84
|
-
|
85
|
-
levels = o.reduce({}) do |hash, (input, level)|
|
86
|
-
hash[input] = case_danger(level.to_f / Pain::MAX[input])
|
87
|
-
hash
|
88
|
-
end
|
89
|
-
|
90
|
-
color_output "Type: #{o[:bug_type]} - #{Pain::OPTIONS[:bug_type][o[:bug_type]]}" , levels[:bug_type]
|
91
|
-
color_output "Likelihood: #{o[:likelihood]} - #{Pain::OPTIONS[:likelihood][o[:likelihood]]}", levels[:likelihood]
|
92
|
-
color_output "Impact: #{o[:impact]} - #{Pain::OPTIONS[:impact][o[:impact]]}" , levels[:impact]
|
93
|
-
puts
|
94
|
-
color_output "User Pain: #{pain}", total_danger(pain)
|
95
|
-
end
|
96
|
-
|
97
|
-
options = {}
|
98
|
-
|
99
|
-
OptionParser.new do |opts|
|
100
|
-
opts.on(
|
101
|
-
'-l',
|
102
|
-
'--likelihood [LIKELIHOOD]',
|
103
|
-
OptionParser::DecimalInteger,
|
104
|
-
Pain::INPUT_MESSAGE[:likelihood]
|
105
|
-
) do |like|
|
106
|
-
options[:likelihood] = Pain.normalize(like, :likelihood)
|
107
|
-
end
|
108
|
-
|
109
|
-
opts.on(
|
110
|
-
'-i',
|
111
|
-
'--impact [IMPACT]',
|
112
|
-
OptionParser::DecimalInteger,
|
113
|
-
Pain::INPUT_MESSAGE[:impact]
|
114
|
-
) do |impact|
|
115
|
-
options[:impact] = Pain.normalize(impact, :impact)
|
116
|
-
end
|
117
|
-
|
118
|
-
opts.on(
|
119
|
-
'-t',
|
120
|
-
'--type [TYPE]',
|
121
|
-
OptionParser::DecimalInteger,
|
122
|
-
Pain::INPUT_MESSAGE[:bug_type]
|
123
|
-
) do |bug_type|
|
124
|
-
options[:bug_type] = Pain.normalize(bug_type, :bug_type)
|
125
|
-
end
|
126
|
-
end.parse!
|
127
|
-
|
128
|
-
[:bug_type, :likelihood, :impact].each do |input|
|
129
|
-
first = true
|
130
|
-
until options[input]
|
131
|
-
ask_question_for input
|
132
|
-
display_options_for(input) if first
|
133
|
-
|
134
|
-
response = gets.chomp
|
135
|
-
options[input] = Pain.normalize(response, input)
|
136
|
-
first = false
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
print_report_for options
|
7
|
+
Pain::Cli.new.run!
|
data/lib/pain.rb
CHANGED
@@ -1,62 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pain/color_strings'
|
4
|
+
require 'pain/model'
|
5
|
+
require 'pain/cli'
|
1
6
|
require 'pain/version'
|
2
|
-
require 'optparse'
|
3
|
-
require 'ostruct'
|
4
7
|
|
5
8
|
module Pain
|
6
|
-
MAX = {
|
7
|
-
bug_type: 7,
|
8
|
-
likelihood: 5,
|
9
|
-
impact: 5
|
10
|
-
}
|
11
|
-
|
12
|
-
INPUT_MESSAGE = {
|
13
|
-
bug_type: 'What kind of bug is this?',
|
14
|
-
likelihood: 'How likely is this bug to occur?',
|
15
|
-
impact: 'How much impact will this bug have?'
|
16
|
-
}
|
17
|
-
|
18
|
-
OPTIONS = {
|
19
|
-
bug_type: {
|
20
|
-
1 => 'Documentation: a documentation issue',
|
21
|
-
2 => 'Localization: missing translations',
|
22
|
-
3 => 'Visual Polish: Aesthetic issues',
|
23
|
-
4 => 'Balancing: allows poor usage strategy',
|
24
|
-
5 => 'Minor UX: Impairs UX in secondary scenarios',
|
25
|
-
6 => 'Major UX: Impairs UX in key scenarios',
|
26
|
-
7 => 'Crash: Causes crash or data loss'
|
27
|
-
},
|
28
|
-
likelihood: {
|
29
|
-
1 => 'Will affect almost no one',
|
30
|
-
2 => 'Will only affect a few users',
|
31
|
-
3 => 'Will affect average number of users',
|
32
|
-
4 => 'Will affect most users',
|
33
|
-
5 => 'Will affect all users'
|
34
|
-
},
|
35
|
-
|
36
|
-
impact: {
|
37
|
-
1 => 'Nuisance: not a big deal but noticeable.',
|
38
|
-
2 => 'A Pain: Users won\'t like this once they notice it.',
|
39
|
-
3 => 'Affects Buy-in. Will show up in review. Clearly noticeable.',
|
40
|
-
4 => 'A user would return the product. Should not deploy until fixed',
|
41
|
-
5 => 'Affects system build'
|
42
|
-
}
|
43
|
-
}
|
44
|
-
|
45
|
-
def max_pain
|
46
|
-
MAX.values.reduce(&:*)
|
47
|
-
end
|
48
|
-
|
49
|
-
def user_pain(type, likelihood, impact)
|
50
|
-
100 * (type * likelihood * impact) / max_pain
|
51
|
-
end
|
52
|
-
|
53
|
-
def normalize(value, variable)
|
54
|
-
value = value.to_i
|
55
|
-
max = MAX[variable]
|
56
|
-
|
57
|
-
return nil if max.nil? || value.nil?
|
58
|
-
return nil if value < 1
|
59
|
-
return max if value > max
|
60
|
-
value
|
61
|
-
end
|
62
9
|
end
|
data/lib/pain/cli.rb
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
module Pain
|
6
|
+
class Cli
|
7
|
+
using Pain::ColorStrings
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@options = {}
|
11
|
+
@model = Pain::Model.new
|
12
|
+
@option_parser = Options.create(@options, @model)
|
13
|
+
end
|
14
|
+
|
15
|
+
def run!
|
16
|
+
@option_parser.parse!
|
17
|
+
|
18
|
+
%i[bug_type likelihood impact].each { |input| fill_question(input) }
|
19
|
+
|
20
|
+
puts
|
21
|
+
print_report_for options
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :model, :options, :option_parser
|
27
|
+
|
28
|
+
def fill_question(input, first: true)
|
29
|
+
return unless options[input].nil?
|
30
|
+
|
31
|
+
ask_question_for input
|
32
|
+
display_choices_for(input) if first
|
33
|
+
|
34
|
+
response = gets.chomp
|
35
|
+
options[input] = model.normalize(response, input)
|
36
|
+
|
37
|
+
fill_question(input, first: false) if options[input].nil?
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_color(value)
|
41
|
+
offset = case value
|
42
|
+
when :trivial
|
43
|
+
40
|
44
|
+
when :minor
|
45
|
+
69
|
46
|
+
when :standard
|
47
|
+
184
|
48
|
+
when :major
|
49
|
+
202
|
50
|
+
when :critical
|
51
|
+
9
|
52
|
+
else
|
53
|
+
252
|
54
|
+
end
|
55
|
+
Term::ANSIColor::Attribute[offset]
|
56
|
+
end
|
57
|
+
|
58
|
+
def case_danger(danger)
|
59
|
+
if danger < 0.21
|
60
|
+
:trivial
|
61
|
+
elsif danger < 0.41
|
62
|
+
:minor
|
63
|
+
elsif danger < 0.65
|
64
|
+
:standard
|
65
|
+
elsif danger < 0.81
|
66
|
+
:major
|
67
|
+
else
|
68
|
+
:critical
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def total_danger(danger)
|
73
|
+
if danger < 21
|
74
|
+
:trivial
|
75
|
+
elsif danger < 31
|
76
|
+
:minor
|
77
|
+
elsif danger < 51
|
78
|
+
:standard
|
79
|
+
elsif danger < 75
|
80
|
+
:major
|
81
|
+
else
|
82
|
+
:critical
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def color_output(msg, danger = :normal)
|
87
|
+
level = case danger
|
88
|
+
when :normal
|
89
|
+
:default
|
90
|
+
when Symbol
|
91
|
+
danger
|
92
|
+
else
|
93
|
+
case_danger(danger)
|
94
|
+
end
|
95
|
+
puts msg.color(get_color(level))
|
96
|
+
end
|
97
|
+
|
98
|
+
def display_choices_for(input)
|
99
|
+
choices = model.choices_for(input)
|
100
|
+
ceiling = choices.count
|
101
|
+
choices.each do |v, msg|
|
102
|
+
color_output("#{v}: #{msg}", (v / ceiling.to_f))
|
103
|
+
end
|
104
|
+
puts
|
105
|
+
end
|
106
|
+
|
107
|
+
def ask_question_for(input)
|
108
|
+
color_output model.input_message(input)
|
109
|
+
end
|
110
|
+
|
111
|
+
# rubocop:disable Metrics/AbcSize
|
112
|
+
def print_report_for(scores)
|
113
|
+
pain = model.user_pain(scores[:bug_type], scores[:likelihood], scores[:impact])
|
114
|
+
|
115
|
+
levels = scores.each_with_object({}) do |(input, level), hash|
|
116
|
+
hash[input] = case_danger(level.to_f / model.max_for(input))
|
117
|
+
end
|
118
|
+
|
119
|
+
color_output "Type: #{scores[:bug_type]} - #{model.level_string(:bug_type, scores[:bug_type])}",
|
120
|
+
levels[:bug_type]
|
121
|
+
color_output "Likelihood: #{scores[:likelihood]} - #{model.level_string(:likelihood, scores[:likelihood])}",
|
122
|
+
levels[:likelihood]
|
123
|
+
color_output "Impact: #{scores[:impact]} - #{model.level_string(:impact, scores[:impact])}", levels[:impact]
|
124
|
+
puts
|
125
|
+
color_output "User Pain: #{pain}", total_danger(pain)
|
126
|
+
end
|
127
|
+
# rubocop:enable Metrics/AbcSize
|
128
|
+
end
|
129
|
+
|
130
|
+
# rubocop:disable Metrics/MethodLength
|
131
|
+
class Options
|
132
|
+
def self.create(options, model)
|
133
|
+
OptionParser.new do |opts|
|
134
|
+
opts.on(
|
135
|
+
'-l',
|
136
|
+
'--likelihood [LIKELIHOOD]',
|
137
|
+
OptionParser::DecimalInteger,
|
138
|
+
model.input_message(:likelihood)
|
139
|
+
) do |like|
|
140
|
+
options[:likelihood] = model.normalize(like, :likelihood)
|
141
|
+
end
|
142
|
+
|
143
|
+
opts.on(
|
144
|
+
'-i',
|
145
|
+
'--impact [IMPACT]',
|
146
|
+
OptionParser::DecimalInteger,
|
147
|
+
model.input_message(:impact)
|
148
|
+
) do |impact|
|
149
|
+
options[:impact] = model.normalize(impact, :impact)
|
150
|
+
end
|
151
|
+
|
152
|
+
opts.on(
|
153
|
+
'-t',
|
154
|
+
'--type [TYPE]',
|
155
|
+
OptionParser::DecimalInteger,
|
156
|
+
model.input_message(:bug_type)
|
157
|
+
) do |bug_type|
|
158
|
+
options[:bug_type] = model.normalize(bug_type, :bug_type)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
# rubocop:enable Metrics/MethodLength
|
164
|
+
end
|
data/lib/pain/model.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pain
|
4
|
+
class Model
|
5
|
+
MAX = {
|
6
|
+
bug_type: 7,
|
7
|
+
likelihood: 5,
|
8
|
+
impact: 5
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
INPUT_MESSAGE = {
|
12
|
+
bug_type: 'What kind of bug is this?',
|
13
|
+
likelihood: 'How likely is this bug to occur?',
|
14
|
+
impact: 'How much impact will this bug have?'
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
OPTIONS = {
|
18
|
+
bug_type: {
|
19
|
+
1 => 'Documentation: a documentation issue',
|
20
|
+
2 => 'Localization: missing translations',
|
21
|
+
3 => 'Visual Polish: Aesthetic issues',
|
22
|
+
4 => 'Balancing: allows poor usage strategy',
|
23
|
+
5 => 'Minor UX: Impairs UX in secondary scenarios',
|
24
|
+
6 => 'Major UX: Impairs UX in key scenarios',
|
25
|
+
7 => 'Crash: Causes crash or data loss'
|
26
|
+
},
|
27
|
+
likelihood: {
|
28
|
+
1 => 'Will affect almost no one',
|
29
|
+
2 => 'Will only affect a few users',
|
30
|
+
3 => 'Will affect average number of users',
|
31
|
+
4 => 'Will affect most users',
|
32
|
+
5 => 'Will affect all users'
|
33
|
+
},
|
34
|
+
|
35
|
+
impact: {
|
36
|
+
1 => 'Nuisance: not a big deal but noticeable.',
|
37
|
+
2 => 'A Pain: Users won\'t like this once they notice it.',
|
38
|
+
3 => 'Affects Buy-in. Will show up in review. Clearly noticeable.',
|
39
|
+
4 => 'A user would return the product. Should not deploy until fixed',
|
40
|
+
5 => 'Affects system build'
|
41
|
+
}
|
42
|
+
}.freeze
|
43
|
+
|
44
|
+
def choices_for(category)
|
45
|
+
OPTIONS[category]
|
46
|
+
end
|
47
|
+
|
48
|
+
def level_string(category, score)
|
49
|
+
OPTIONS.dig(category, score)
|
50
|
+
end
|
51
|
+
|
52
|
+
def max_for(category)
|
53
|
+
MAX[category]
|
54
|
+
end
|
55
|
+
|
56
|
+
def input_message(category)
|
57
|
+
INPUT_MESSAGE[category]
|
58
|
+
end
|
59
|
+
|
60
|
+
def max_pain
|
61
|
+
MAX.values.reduce(&:*)
|
62
|
+
end
|
63
|
+
|
64
|
+
def user_pain(type, likelihood, impact)
|
65
|
+
100 * (type * likelihood * impact) / max_pain
|
66
|
+
end
|
67
|
+
|
68
|
+
def normalize(value, variable)
|
69
|
+
value = value.to_i
|
70
|
+
max = MAX[variable]
|
71
|
+
|
72
|
+
return nil if max.nil? || value.nil?
|
73
|
+
return nil if value < 1
|
74
|
+
return max if value > max
|
75
|
+
|
76
|
+
value
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/pain/version.rb
CHANGED
data/pain.gemspec
CHANGED
@@ -14,17 +14,18 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
17
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/pain}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_dependency 'term-ansicolor'
|
22
22
|
spec.add_dependency 'tins'
|
23
23
|
|
24
|
-
spec.add_development_dependency 'bundler', '~>
|
24
|
+
spec.add_development_dependency 'bundler', '~> 2'
|
25
25
|
spec.add_development_dependency 'rake'
|
26
|
-
spec.add_development_dependency 'rspec'
|
26
|
+
spec.add_development_dependency 'rspec', '< 4'
|
27
27
|
spec.add_development_dependency 'simplecov'
|
28
28
|
spec.add_development_dependency 'simplecov-rcov'
|
29
29
|
spec.add_development_dependency 'pry'
|
30
|
+
spec.add_development_dependency 'rubygems-update'
|
30
31
|
end
|
data/spec/model_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Pain
|
4
|
+
RSpec.describe Model do
|
5
|
+
describe '#user_pain' do
|
6
|
+
it 'calculates_correctly' do
|
7
|
+
expect(subject.user_pain(7, 5, 5)).to eq(100)
|
8
|
+
expect(subject.user_pain(1, 1, 1)).to eq(0)
|
9
|
+
expect(subject.user_pain(4, 3, 3)).to eq(20)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#normalize' do
|
14
|
+
it 'doesn\'t allow numbers too small' do
|
15
|
+
expect(subject.normalize(0, :impact)).to be_nil
|
16
|
+
expect(subject.normalize(-1, :impact)).to be_nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'doesn\'t allow numbers too big' do
|
20
|
+
expect(subject.normalize(10, :bug_type)).to eq(7)
|
21
|
+
expect(subject.normalize(7, :impact)).to eq(5)
|
22
|
+
expect(subject.normalize(7, :bug_type)).to eq(7)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,139 +1,152 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pain
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Nicholson
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: term-ansicolor
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: tins
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '2'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - "<"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '4'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - "<"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '4'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: simplecov
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: simplecov-rcov
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: pry
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubygems-update
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
116
130
|
- !ruby/object:Gem::Version
|
117
131
|
version: '0'
|
118
132
|
type: :development
|
119
133
|
prerelease: false
|
120
134
|
version_requirements: !ruby/object:Gem::Requirement
|
121
135
|
requirements:
|
122
|
-
- -
|
136
|
+
- - ">="
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
125
139
|
description: 'Based on http://www.lostgarden.com/2008/05/improving-bug-triage-with-user-pain.html '
|
126
140
|
email:
|
127
141
|
- andrew@anicholson.net
|
128
142
|
executables:
|
129
|
-
- .rubocop.yml
|
130
143
|
- pain
|
131
144
|
extensions: []
|
132
145
|
extra_rdoc_files: []
|
133
146
|
files:
|
134
|
-
- .gitignore
|
135
|
-
- .rspec
|
136
|
-
- .rubocop.yml
|
147
|
+
- ".gitignore"
|
148
|
+
- ".rspec"
|
149
|
+
- ".rubocop.yml"
|
137
150
|
- Gemfile
|
138
151
|
- LICENSE.txt
|
139
152
|
- README.md
|
@@ -141,37 +154,36 @@ files:
|
|
141
154
|
- bin/.rubocop.yml
|
142
155
|
- bin/pain
|
143
156
|
- lib/pain.rb
|
157
|
+
- lib/pain/cli.rb
|
158
|
+
- lib/pain/color_strings.rb
|
159
|
+
- lib/pain/model.rb
|
144
160
|
- lib/pain/version.rb
|
145
161
|
- pain.gemspec
|
146
|
-
- spec/
|
162
|
+
- spec/model_spec.rb
|
147
163
|
- spec/spec_helper.rb
|
148
|
-
- spec/user_pain_spec.rb
|
149
164
|
homepage: http://github.com/anicholson/pain.git
|
150
165
|
licenses:
|
151
166
|
- MIT
|
152
167
|
metadata: {}
|
153
|
-
post_install_message:
|
168
|
+
post_install_message:
|
154
169
|
rdoc_options: []
|
155
170
|
require_paths:
|
156
171
|
- lib
|
157
172
|
required_ruby_version: !ruby/object:Gem::Requirement
|
158
173
|
requirements:
|
159
|
-
- -
|
174
|
+
- - ">="
|
160
175
|
- !ruby/object:Gem::Version
|
161
176
|
version: '0'
|
162
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
178
|
requirements:
|
164
|
-
- -
|
179
|
+
- - ">="
|
165
180
|
- !ruby/object:Gem::Version
|
166
181
|
version: '0'
|
167
182
|
requirements: []
|
168
|
-
|
169
|
-
|
170
|
-
signing_key:
|
183
|
+
rubygems_version: 3.1.6
|
184
|
+
signing_key:
|
171
185
|
specification_version: 4
|
172
186
|
summary: Quickly calculate User Pain for a bug
|
173
187
|
test_files:
|
174
|
-
- spec/
|
188
|
+
- spec/model_spec.rb
|
175
189
|
- spec/spec_helper.rb
|
176
|
-
- spec/user_pain_spec.rb
|
177
|
-
has_rdoc:
|
data/spec/normalize_spec.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'normalize' do
|
4
|
-
subject { Class.new { include Pain }.new }
|
5
|
-
|
6
|
-
it 'doesn\'t allow numbers too small' do
|
7
|
-
expect(subject.normalize(0, :impact)).to be_nil
|
8
|
-
expect(subject.normalize(-1, :impact)).to be_nil
|
9
|
-
end
|
10
|
-
|
11
|
-
it 'doesn\'t allow numbers too big' do
|
12
|
-
expect(subject.normalize(10, :bug_type)).to eq(7)
|
13
|
-
expect(subject.normalize(7, :impact)).to eq(5)
|
14
|
-
expect(subject.normalize(7, :bug_type)).to eq(7)
|
15
|
-
end
|
16
|
-
end
|
data/spec/user_pain_spec.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
|
4
|
-
describe 'pain' do
|
5
|
-
subject { Class.new { include Pain }.new }
|
6
|
-
|
7
|
-
it 'calculates_correctly' do
|
8
|
-
expect(subject.user_pain(7, 5, 5)).to eq(100)
|
9
|
-
expect(subject.user_pain(1, 1, 1)).to eq(0)
|
10
|
-
expect(subject.user_pain(4, 3, 3)).to eq(20)
|
11
|
-
end
|
12
|
-
end
|