Class: CucumberCharacteristics::ProfileData
- Inherits:
-
Object
- Object
- CucumberCharacteristics::ProfileData
- Extended by:
- Forwardable
- Defined in:
- lib/cucumber_characteristics/profile_data.rb
Constant Summary collapse
- CUCUMBER_VERSION =
Gem::Version.new(Cucumber::VERSION)
- STATUS_ORDER =
{ passed: 0, failed: 2000, skipped: 1000, undefined: 500 }.freeze
- STATUS =
STATUS_ORDER.keys
Instance Attribute Summary collapse
-
#duration ⇒ Object
readonly
Returns the value of attribute duration.
Instance Method Summary collapse
- #ambiguous?(step) ⇒ Boolean
- #ambiguous_count ⇒ Object
- #feature_profiles ⇒ Object
-
#initialize(runtime, features) ⇒ ProfileData
constructor
A new instance of ProfileData.
- #nonstep_duration ⇒ Object
- #scenario_count_by_status ⇒ Object
- #step_count(status) ⇒ Object
- #step_count_by_status ⇒ Object
- #step_duration ⇒ Object
- #step_profiles ⇒ Object
- #unmatched_steps ⇒ Object
- #unmatched_steps? ⇒ Boolean
- #with_feature_calculations(feature_profiles) ⇒ Object
- #with_step_calculations(step_profiles) ⇒ Object
Constructor Details
#initialize(runtime, features) ⇒ ProfileData
Returns a new instance of ProfileData.
16 17 18 19 20 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 16 def initialize(runtime, features) @runtime = runtime @duration = features.duration @features = features end |
Instance Attribute Details
#duration ⇒ Object (readonly)
Returns the value of attribute duration.
10 11 12 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 10 def duration @duration end |
Instance Method Details
#ambiguous?(step) ⇒ Boolean
86 87 88 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 86 def ambiguous?(step) step.status == :failed && step.step_match.step_definition.nil? end |
#ambiguous_count ⇒ Object
22 23 24 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 22 def ambiguous_count @runtime.steps.count { |s| ambiguous?(s) } end |
#feature_profiles ⇒ Object
39 40 41 42 43 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 39 def feature_profiles return @feature_profiles if @feature_profiles feature_profiles = @runtime.scenario_profiles @feature_profiles = with_feature_calculations(feature_profiles) end |
#nonstep_duration ⇒ Object
124 125 126 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 124 def nonstep_duration duration - step_duration end |
#scenario_count_by_status ⇒ Object
141 142 143 144 145 146 147 148 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 141 def scenario_count_by_status status = {} @runtime.scenarios.each do |s| status[s.status] ||= 0 status[s.status] += 1 end status end |
#step_count(status) ⇒ Object
137 138 139 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 137 def step_count(status) step_count_by_status[status] end |
#step_count_by_status ⇒ Object
128 129 130 131 132 133 134 135 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 128 def step_count_by_status status = {} @runtime.steps.each do |s| status[s.status] ||= 0 status[s.status] += 1 end status end |
#step_duration ⇒ Object
112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 112 def step_duration step_duration = [] step_profiles.each do |_step, | STATUS.each do |status| [status][:feature_location].each do |_location, timings| step_duration << timings end end end step_duration.flatten.compact.inject(:+) || 0 end |
#step_profiles ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 65 def step_profiles step_profiles = {} @runtime.steps.each do |s| next if ambiguous?(s) step_name = s.status == :undefined ? s.name : s.step_match.step_definition.file_colon_line # Initialize data structure step_profiles[step_name] ||= { total_count: 0 } STATUS.each { |status| step_profiles[step_name][status] ||= { count: 0, feature_location: {} } } feature_location = s.file_colon_line step_profiles[step_name][s.status][:count] += 1 step_profiles[step_name][:total_count] += 1 step_profiles[step_name][s.status][:feature_location][feature_location] ||= [] next unless s.status != :undefined step_profiles[step_name][:regexp] = s.step_match.step_definition.regexp_source if s.status == :passed step_profiles[step_name][s.status][:feature_location][feature_location] << s.step_match.duration end end with_step_calculations(step_profiles) end |
#unmatched_steps ⇒ Object
26 27 28 29 30 31 32 33 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 26 def unmatched_steps unmatched = {} @runtime.unmatched_step_definitions.each do |u| location = u.file_colon_line unmatched[location] = u.regexp_source end unmatched.sort end |
#unmatched_steps? ⇒ Boolean
35 36 37 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 35 def unmatched_steps? unmatched_steps.count > 0 end |
#with_feature_calculations(feature_profiles) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 45 def with_feature_calculations(feature_profiles) feature_profiles.each do |feature, | next unless [:examples] feature_profiles[feature][:example_count] = [:examples].keys.count feature_profiles[feature][:total_duration] = [:examples].map { |_e, m| m[:total_duration] || 0 }.inject(&:+) feature_profiles[feature][:step_count] = [:examples].map { |_e, m| m[:step_count] }.inject(&:+) feature_profiles[feature][:examples] = feature_profiles[feature][:examples].sort_by { |_k, v| v[:total_duration] }.reverse feature_profiles[feature][:status] = if [:examples].all? { |_e, m| m[:status] == :passed } :passed elsif [:examples].any? { |_e, m| m[:status] == :failed } :failed elsif [:examples].any? { |_e, m| m[:status] == :skipped } :skipped else :unknown end end feature_profiles.sort_by { |_k, v| (STATUS_ORDER[v[:status]] || 0) + (v[:total_duration] || 0) }.reverse end |
#with_step_calculations(step_profiles) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/cucumber_characteristics/profile_data.rb', line 90 def with_step_calculations(step_profiles) step_profiles.each do |step, | .merge!(fastest: nil, slowest: nil, average: nil, total_duration: nil, standard_deviation: nil, variation: nil) next unless [:passed][:count] > 0 timings = [] STATUS.each do |status| timings << [status][:feature_location].values end timings = timings.flatten.compact step_profiles[step][:fastest] = timings.min step_profiles[step][:slowest] = timings.max step_profiles[step][:variation] = step_profiles[step][:slowest] - step_profiles[step][:fastest] step_profiles[step][:total_duration] = timings.inject(:+) step_profiles[step][:average] = step_profiles[step][:total_duration] / [:passed][:count] sum = timings.inject(0) { |accum, i| accum + (i - step_profiles[step][:average])**2 } step_profiles[step][:variance] = sum / timings.length.to_f step_profiles[step][:standard_deviation] = Math.sqrt(step_profiles[step][:variance]) end step_profiles.sort_by { |_k, v| v[:total_duration] || 0 }.reverse end |