sleeping_king_studios-tasks 0.1.0.rc.0
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/CHANGELOG.md +26 -0
- data/DEVELOPMENT.md +50 -0
- data/LICENSE +22 -0
- data/README.md +405 -0
- data/lib/sleeping_king_studios/tasks.rb +27 -0
- data/lib/sleeping_king_studios/tasks/apps.rb +49 -0
- data/lib/sleeping_king_studios/tasks/apps/app_configuration.rb +68 -0
- data/lib/sleeping_king_studios/tasks/apps/applications_task.rb +28 -0
- data/lib/sleeping_king_studios/tasks/apps/bundle.rb +8 -0
- data/lib/sleeping_king_studios/tasks/apps/bundle/install_runner.rb +21 -0
- data/lib/sleeping_king_studios/tasks/apps/bundle/install_task.rb +39 -0
- data/lib/sleeping_king_studios/tasks/apps/bundle/update_runner.rb +21 -0
- data/lib/sleeping_king_studios/tasks/apps/bundle/update_task.rb +39 -0
- data/lib/sleeping_king_studios/tasks/apps/ci.rb +8 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/results_reporter.rb +69 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/rspec_task.rb +29 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/rspec_wrapper.rb +42 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/rubocop_task.rb +29 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/rubocop_wrapper.rb +29 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/simplecov_task.rb +68 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/step_wrapper.rb +49 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/steps_runner.rb +37 -0
- data/lib/sleeping_king_studios/tasks/apps/ci/steps_task.rb +92 -0
- data/lib/sleeping_king_studios/tasks/ci.rb +8 -0
- data/lib/sleeping_king_studios/tasks/ci/cucumber_parser.rb +118 -0
- data/lib/sleeping_king_studios/tasks/ci/cucumber_results.rb +191 -0
- data/lib/sleeping_king_studios/tasks/ci/cucumber_runner.rb +53 -0
- data/lib/sleeping_king_studios/tasks/ci/cucumber_task.rb +47 -0
- data/lib/sleeping_king_studios/tasks/ci/results_helpers.rb +44 -0
- data/lib/sleeping_king_studios/tasks/ci/rspec_each_results.rb +118 -0
- data/lib/sleeping_king_studios/tasks/ci/rspec_each_task.rb +156 -0
- data/lib/sleeping_king_studios/tasks/ci/rspec_results.rb +126 -0
- data/lib/sleeping_king_studios/tasks/ci/rspec_runner.rb +62 -0
- data/lib/sleeping_king_studios/tasks/ci/rspec_task.rb +71 -0
- data/lib/sleeping_king_studios/tasks/ci/rubocop_results.rb +80 -0
- data/lib/sleeping_king_studios/tasks/ci/rubocop_runner.rb +46 -0
- data/lib/sleeping_king_studios/tasks/ci/rubocop_task.rb +44 -0
- data/lib/sleeping_king_studios/tasks/ci/simplecov_results.rb +62 -0
- data/lib/sleeping_king_studios/tasks/ci/simplecov_task.rb +25 -0
- data/lib/sleeping_king_studios/tasks/ci/steps_runner.rb +69 -0
- data/lib/sleeping_king_studios/tasks/ci/steps_task.rb +93 -0
- data/lib/sleeping_king_studios/tasks/configuration.rb +114 -0
- data/lib/sleeping_king_studios/tasks/file.rb +8 -0
- data/lib/sleeping_king_studios/tasks/file/new_task.rb +238 -0
- data/lib/sleeping_king_studios/tasks/process_runner.rb +70 -0
- data/lib/sleeping_king_studios/tasks/task.rb +95 -0
- data/lib/sleeping_king_studios/tasks/task_group.rb +37 -0
- data/lib/sleeping_king_studios/tasks/version.rb +58 -0
- metadata +271 -0
@@ -0,0 +1,53 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/cucumber_runner.rb
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require 'sleeping_king_studios/tasks/ci'
|
6
|
+
require 'sleeping_king_studios/tasks/ci/cucumber_parser'
|
7
|
+
require 'sleeping_king_studios/tasks/process_runner'
|
8
|
+
|
9
|
+
module SleepingKingStudios::Tasks::Ci
|
10
|
+
# Service object to run Cucumber as an external process with the specified
|
11
|
+
# parameters.
|
12
|
+
class CucumberRunner < SleepingKingStudios::Tasks::ProcessRunner
|
13
|
+
def call env: {}, files: [], options: [], report: true
|
14
|
+
report = 'tmp/ci/cucumber.json' if report && !report.is_a?(String)
|
15
|
+
command =
|
16
|
+
build_command(
|
17
|
+
:env => env,
|
18
|
+
:files => files,
|
19
|
+
:options => options,
|
20
|
+
:report => report
|
21
|
+
) # end build_command
|
22
|
+
|
23
|
+
stream_process(command)
|
24
|
+
|
25
|
+
report ? load_report(:report => report) : {}
|
26
|
+
end # method call
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def base_command
|
31
|
+
'bundle exec cucumber'
|
32
|
+
end # method base_command
|
33
|
+
|
34
|
+
def build_options files:, options:, report:, **_kwargs
|
35
|
+
options += ['--format=json', "--out=#{report}"] if report
|
36
|
+
|
37
|
+
super :files => files, :options => options
|
38
|
+
end # method build_options
|
39
|
+
|
40
|
+
def load_report report:
|
41
|
+
raw = File.read report
|
42
|
+
|
43
|
+
return {} if raw.empty?
|
44
|
+
|
45
|
+
json = JSON.parse raw
|
46
|
+
parser = SleepingKingStudios::Tasks::Ci::CucumberParser
|
47
|
+
|
48
|
+
parser.parse(json)
|
49
|
+
rescue
|
50
|
+
{}
|
51
|
+
end # method load_report
|
52
|
+
end # class
|
53
|
+
end # module
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/cucumber_task.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/ci'
|
4
|
+
require 'sleeping_king_studios/tasks/ci/cucumber_results'
|
5
|
+
require 'sleeping_king_studios/tasks/ci/cucumber_runner'
|
6
|
+
|
7
|
+
module SleepingKingStudios::Tasks::Ci
|
8
|
+
# Defines a Thor task for running the full RSpec test suite.
|
9
|
+
class CucumberTask < SleepingKingStudios::Tasks::Task
|
10
|
+
def self.description
|
11
|
+
'Runs the Cucumber feature suite.'
|
12
|
+
end # class method description
|
13
|
+
|
14
|
+
option :quiet,
|
15
|
+
:aliases => '-q',
|
16
|
+
:type => :boolean,
|
17
|
+
:default => false,
|
18
|
+
:desc => 'Do not write spec results to STDOUT.'
|
19
|
+
option :raw,
|
20
|
+
:aliases => '-r',
|
21
|
+
:type => :boolean,
|
22
|
+
:default => false,
|
23
|
+
:desc => 'Return a Hash instead of a results object.'
|
24
|
+
|
25
|
+
def call *files
|
26
|
+
files += default_files unless files.empty?
|
27
|
+
|
28
|
+
results = cucumber_runner.call(:files => files)
|
29
|
+
|
30
|
+
raw? ? results : CucumberResults.new(results)
|
31
|
+
end # method call
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def cucumber_runner
|
36
|
+
opts = %w(--color)
|
37
|
+
opts << '--format=pretty' unless quiet?
|
38
|
+
|
39
|
+
CucumberRunner.new(:options => opts)
|
40
|
+
end # method cucumber_runner
|
41
|
+
|
42
|
+
def default_files
|
43
|
+
SleepingKingStudios::Tasks.configuration.ci.cucumber.
|
44
|
+
fetch('default_files', [])
|
45
|
+
end # method default_files
|
46
|
+
end # class
|
47
|
+
end # module
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/results_helpers.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/ci'
|
4
|
+
|
5
|
+
module SleepingKingStudios::Tasks::Ci
|
6
|
+
# Helper methods for reporting CI results.
|
7
|
+
module ResultsHelpers
|
8
|
+
private
|
9
|
+
|
10
|
+
# Returns a terminal color corresponding to the state of the results object.
|
11
|
+
#
|
12
|
+
# @param results [Object] The results object.
|
13
|
+
#
|
14
|
+
# @return [Symbol] The terminal color.
|
15
|
+
def results_color results
|
16
|
+
if results.failing?
|
17
|
+
:red
|
18
|
+
elsif results.respond_to?(:errored?) && results.errored?
|
19
|
+
:red
|
20
|
+
elsif results.pending? || results.empty?
|
21
|
+
:yellow
|
22
|
+
else
|
23
|
+
:green
|
24
|
+
end # if-elsif-else
|
25
|
+
end # method set_results_color
|
26
|
+
|
27
|
+
# Returns a state string for the results object.
|
28
|
+
#
|
29
|
+
# @param results [Object] The results object.
|
30
|
+
#
|
31
|
+
# @return [String] The results state.
|
32
|
+
def results_state results
|
33
|
+
if results.respond_to?(:errored?) && results.errored?
|
34
|
+
'Errored'
|
35
|
+
elsif results.failing?
|
36
|
+
'Failing'
|
37
|
+
elsif results.pending? || results.empty?
|
38
|
+
'Pending'
|
39
|
+
else
|
40
|
+
'Passing'
|
41
|
+
end # if-elsif-else
|
42
|
+
end # method results_state
|
43
|
+
end # module
|
44
|
+
end # module
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/rspec_each_results.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/ci'
|
4
|
+
|
5
|
+
module SleepingKingStudios::Tasks::Ci
|
6
|
+
# Encapsulates the results of an RSpecEach call.
|
7
|
+
class RSpecEachResults
|
8
|
+
# @param results [Hash] The raw results of the RSpecEach call.
|
9
|
+
def initialize results
|
10
|
+
@results = results
|
11
|
+
end # constructor
|
12
|
+
|
13
|
+
# @param other [RSpecEachResults] The other results object to compare.
|
14
|
+
#
|
15
|
+
# @return [Boolean] True if the results are equal, otherwise false.
|
16
|
+
def == other
|
17
|
+
if other.is_a?(Hash)
|
18
|
+
empty? ? other.empty? : to_h == other
|
19
|
+
elsif other.is_a?(RSpecEachResults)
|
20
|
+
to_h == other.to_h
|
21
|
+
else
|
22
|
+
false
|
23
|
+
end # if-elsif-else
|
24
|
+
end # method ==
|
25
|
+
|
26
|
+
# @return [Float] The duration value.
|
27
|
+
def duration
|
28
|
+
@results.fetch('duration', 0.0)
|
29
|
+
end # method duration
|
30
|
+
|
31
|
+
# @return [Boolean] True if there are no files, otherwise false.
|
32
|
+
def empty?
|
33
|
+
file_count.zero?
|
34
|
+
end # method empty?
|
35
|
+
|
36
|
+
# @return [Boolean] True if there are any errored files, otherwise false.
|
37
|
+
def errored?
|
38
|
+
!errored_count.zero?
|
39
|
+
end # method errored?
|
40
|
+
|
41
|
+
# @return [Integer] The number of errored files.
|
42
|
+
def errored_count
|
43
|
+
errored_files.count
|
44
|
+
end # method errored_count
|
45
|
+
|
46
|
+
# @return [Array] The list of errored file names.
|
47
|
+
def errored_files
|
48
|
+
@results.fetch('errored_files', [])
|
49
|
+
end # method errored_files
|
50
|
+
|
51
|
+
# @return [Boolean] True if there are any failing files, otherwise false.
|
52
|
+
def failing?
|
53
|
+
!failure_count.zero?
|
54
|
+
end # method failing?
|
55
|
+
|
56
|
+
# @return [Array] The list of failing file names.
|
57
|
+
def failing_files
|
58
|
+
@results.fetch('failing_files', [])
|
59
|
+
end # method failing_files
|
60
|
+
|
61
|
+
# @return [Integer] The number of failing files.
|
62
|
+
def failure_count
|
63
|
+
failing_files.count
|
64
|
+
end # method failing_files
|
65
|
+
|
66
|
+
# @return [Integer] The total file count.
|
67
|
+
def file_count
|
68
|
+
@results.fetch('file_count', 0)
|
69
|
+
end # method file_count
|
70
|
+
|
71
|
+
# @return [Boolean] True if there are any pending files, otherwise false.
|
72
|
+
def pending?
|
73
|
+
!pending_count.zero?
|
74
|
+
end # method pending?
|
75
|
+
|
76
|
+
# @return [Integer] The number of pending files.
|
77
|
+
def pending_count
|
78
|
+
pending_files.count
|
79
|
+
end # method pending_count
|
80
|
+
|
81
|
+
# @return [Array] The list of pending file names.
|
82
|
+
def pending_files
|
83
|
+
@results.fetch('pending_files', [])
|
84
|
+
end # method pending_files
|
85
|
+
|
86
|
+
def pluralize count, singular, plural = nil
|
87
|
+
"#{count} #{tools.integer.pluralize count, singular, plural}"
|
88
|
+
end # method pluralize
|
89
|
+
|
90
|
+
# @return [Hash] The hash representation of the results.
|
91
|
+
def to_h
|
92
|
+
{
|
93
|
+
'failing_files' => failing_files,
|
94
|
+
'pending_files' => pending_files,
|
95
|
+
'errored_files' => errored_files,
|
96
|
+
'file_count' => file_count,
|
97
|
+
'duration' => duration
|
98
|
+
} # end hash
|
99
|
+
end # method to_h
|
100
|
+
|
101
|
+
# @return [String] The string representation of the results.
|
102
|
+
def to_s
|
103
|
+
str = "#{file_count} files"
|
104
|
+
|
105
|
+
str << ', ' << pluralize(failure_count, 'failure')
|
106
|
+
|
107
|
+
str << ", #{pending_count} pending" if pending?
|
108
|
+
|
109
|
+
str << ", #{errored_count} errored" if errored?
|
110
|
+
|
111
|
+
str << " in #{duration.round(2)} seconds"
|
112
|
+
end # method to_s
|
113
|
+
|
114
|
+
def tools
|
115
|
+
SleepingKingStudios::Tools::Toolbelt.instance
|
116
|
+
end # method tools
|
117
|
+
end # class
|
118
|
+
end # module
|
@@ -0,0 +1,156 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/rspec_each_task.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/ci'
|
4
|
+
require 'sleeping_king_studios/tasks/ci/results_helpers'
|
5
|
+
require 'sleeping_king_studios/tasks/ci/rspec_each_results'
|
6
|
+
require 'sleeping_king_studios/tasks/ci/rspec_results'
|
7
|
+
require 'sleeping_king_studios/tasks/ci/rspec_runner'
|
8
|
+
|
9
|
+
module SleepingKingStudios::Tasks::Ci
|
10
|
+
# rubocop:disable Metrics/ClassLength
|
11
|
+
|
12
|
+
# Defines a Thor task for running the full RSpec test suite.
|
13
|
+
class RSpecEachTask < SleepingKingStudios::Tasks::Task
|
14
|
+
include SleepingKingStudios::Tasks::Ci::ResultsHelpers
|
15
|
+
|
16
|
+
def self.description
|
17
|
+
'Runs each spec file as an individual RSpec process.'
|
18
|
+
end # class method description
|
19
|
+
|
20
|
+
def self.task_name
|
21
|
+
'rspec_each'
|
22
|
+
end # class method task_name
|
23
|
+
|
24
|
+
option :quiet,
|
25
|
+
:aliases => '-q',
|
26
|
+
:type => :boolean,
|
27
|
+
:default => false,
|
28
|
+
:desc => 'Do not write spec results to STDOUT.'
|
29
|
+
option :raw,
|
30
|
+
:aliases => '-r',
|
31
|
+
:type => :boolean,
|
32
|
+
:default => false,
|
33
|
+
:desc => 'Return a Hash instead of a results object.'
|
34
|
+
|
35
|
+
def call *groups
|
36
|
+
mute! if quiet?
|
37
|
+
|
38
|
+
files = files_list(groups)
|
39
|
+
|
40
|
+
say "Running #{files.count} spec files..."
|
41
|
+
say "\n"
|
42
|
+
|
43
|
+
results = run_files(files)
|
44
|
+
|
45
|
+
report_pending results
|
46
|
+
report_failing results
|
47
|
+
report_errored results
|
48
|
+
report_totals results
|
49
|
+
|
50
|
+
raw? ? results.to_h : results
|
51
|
+
end # method call
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def aggregate_results file, results, totals
|
56
|
+
if results.errored?
|
57
|
+
totals['errored_files'] << file
|
58
|
+
elsif results.failing?
|
59
|
+
totals['failing_files'] << file
|
60
|
+
elsif results.pending?
|
61
|
+
totals['pending_files'] << file
|
62
|
+
end # if-else
|
63
|
+
|
64
|
+
totals['file_count'] += 1
|
65
|
+
end # method aggregate_results
|
66
|
+
|
67
|
+
def build_totals
|
68
|
+
{
|
69
|
+
'pending_files' => [],
|
70
|
+
'failing_files' => [],
|
71
|
+
'errored_files' => [],
|
72
|
+
'file_count' => 0
|
73
|
+
} # end results
|
74
|
+
end # method build_totals
|
75
|
+
|
76
|
+
def files_list groups
|
77
|
+
groups = %w(spec) if groups.empty?
|
78
|
+
|
79
|
+
groups.map do |group_or_file|
|
80
|
+
if File.extname(group_or_file).empty?
|
81
|
+
Dir[File.join group_or_file, pattern]
|
82
|
+
else
|
83
|
+
[group_or_file]
|
84
|
+
end # if-else
|
85
|
+
end. # map
|
86
|
+
flatten.
|
87
|
+
uniq
|
88
|
+
end # method files_list
|
89
|
+
|
90
|
+
def pattern
|
91
|
+
'**{,/*/**}/*_spec.rb'
|
92
|
+
end # method pattern
|
93
|
+
|
94
|
+
def report_errored results
|
95
|
+
return unless results.errored?
|
96
|
+
|
97
|
+
say "\nErrored:\n\n"
|
98
|
+
|
99
|
+
results.errored_files.each { |file| say " #{file}", :red }
|
100
|
+
end # report_pending
|
101
|
+
|
102
|
+
def report_failing results
|
103
|
+
return unless results.failing?
|
104
|
+
|
105
|
+
say "\nFailures:\n\n"
|
106
|
+
|
107
|
+
results.failing_files.each { |file| say " #{file}", :red }
|
108
|
+
end # report_pending
|
109
|
+
|
110
|
+
def report_pending results
|
111
|
+
return unless results.pending?
|
112
|
+
|
113
|
+
say "\nPending:\n\n"
|
114
|
+
|
115
|
+
results.pending_files.each { |file| say " #{file}", :yellow }
|
116
|
+
end # report_pending
|
117
|
+
|
118
|
+
def report_totals results
|
119
|
+
say "\nFinished in #{results.duration.round(2)} seconds"
|
120
|
+
|
121
|
+
if results.failing? || results.errored?
|
122
|
+
say results.to_s, :red
|
123
|
+
elsif results.pending? || results.empty?
|
124
|
+
say results.to_s, :yellow
|
125
|
+
else
|
126
|
+
say results.to_s, :green
|
127
|
+
end # if-elsif-else
|
128
|
+
end # method report_totals
|
129
|
+
|
130
|
+
def rspec_runner
|
131
|
+
RSpecRunner.new(:env => { :coverage => false })
|
132
|
+
end # method rspec_runner
|
133
|
+
|
134
|
+
def run_file file
|
135
|
+
results = rspec_runner.call(:files => [file])
|
136
|
+
results = RSpecResults.new(results)
|
137
|
+
|
138
|
+
say "#{set_color results_state(results), results_color(results)} #{file}"
|
139
|
+
|
140
|
+
results
|
141
|
+
end # method run_file
|
142
|
+
|
143
|
+
def run_files files
|
144
|
+
start = Time.now
|
145
|
+
totals = build_totals
|
146
|
+
|
147
|
+
files.each { |file| aggregate_results(file, run_file(file), totals) }
|
148
|
+
|
149
|
+
totals['duration'] = Time.now - start
|
150
|
+
|
151
|
+
RSpecEachResults.new(totals)
|
152
|
+
end # method run_files
|
153
|
+
end # class
|
154
|
+
|
155
|
+
# rubocop:enable Metrics/ClassLength
|
156
|
+
end # module
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# lib/sleeping_king_studios/tasks/ci/rspec_results.rb
|
2
|
+
|
3
|
+
require 'sleeping_king_studios/tasks/ci'
|
4
|
+
|
5
|
+
module SleepingKingStudios::Tasks::Ci
|
6
|
+
# Encapsulates the results of an RSpec call.
|
7
|
+
class RSpecResults
|
8
|
+
# @param results [Hash] The raw results of the RSpec call.
|
9
|
+
def initialize results
|
10
|
+
@results = results
|
11
|
+
end # constructor
|
12
|
+
|
13
|
+
# @param other [RSpecResults] The other results object to compare.
|
14
|
+
#
|
15
|
+
# @return [Boolean] True if the results are equal, otherwise false.
|
16
|
+
def == other
|
17
|
+
if other.is_a?(Hash)
|
18
|
+
empty? ? other.empty? : to_h == other
|
19
|
+
elsif other.is_a?(RSpecResults)
|
20
|
+
to_h == other.to_h
|
21
|
+
else
|
22
|
+
false
|
23
|
+
end # if-elsif-else
|
24
|
+
end # method ==
|
25
|
+
|
26
|
+
# @return [Float] The duration value.
|
27
|
+
def duration
|
28
|
+
@results.fetch('duration', 0.0)
|
29
|
+
end # method duration
|
30
|
+
|
31
|
+
# @return [Boolean] True if there are no examples, otherwise false.
|
32
|
+
def empty?
|
33
|
+
example_count.zero?
|
34
|
+
end # method empty?
|
35
|
+
|
36
|
+
# @return [Boolean] True if there are no results or if errors occurred
|
37
|
+
# outside of examples, otherwise false.
|
38
|
+
def errored?
|
39
|
+
@results.empty? || !error_count.zero?
|
40
|
+
end # method errored?
|
41
|
+
|
42
|
+
# @return [Integer] The number of errors that occurred outside of examples.
|
43
|
+
def error_count
|
44
|
+
@results.fetch('error_count', 0)
|
45
|
+
end # method error_count
|
46
|
+
|
47
|
+
# @return [Integer] The total number of examples.
|
48
|
+
def example_count
|
49
|
+
@results.fetch('example_count', 0)
|
50
|
+
end # method example_count
|
51
|
+
|
52
|
+
# @return [Boolean] True if there are any failing examples, otherwise false.
|
53
|
+
def failing?
|
54
|
+
!failure_count.zero?
|
55
|
+
end # method failing?
|
56
|
+
|
57
|
+
# @return [Integer] The number of failing examples.
|
58
|
+
def failure_count
|
59
|
+
@results.fetch('failure_count', 0)
|
60
|
+
end # method failure_count
|
61
|
+
|
62
|
+
# Adds the given result values and returns a new results object with the
|
63
|
+
# sums.
|
64
|
+
#
|
65
|
+
# @param other [RSpecResults] The results to add.
|
66
|
+
#
|
67
|
+
# @return [RSpecResults] The total results.
|
68
|
+
def merge other
|
69
|
+
self.class.new(
|
70
|
+
'duration' => duration + other.duration,
|
71
|
+
'example_count' => example_count + other.example_count,
|
72
|
+
'failure_count' => failure_count + other.failure_count,
|
73
|
+
'pending_count' => pending_count + other.pending_count
|
74
|
+
) # end new
|
75
|
+
end # method merge
|
76
|
+
|
77
|
+
# @return [Boolean] True if there are any pending examples, otherwise false.
|
78
|
+
def pending?
|
79
|
+
!pending_count.zero?
|
80
|
+
end # method pending?
|
81
|
+
|
82
|
+
# @return [Intger] The number of pending examples.
|
83
|
+
def pending_count
|
84
|
+
@results.fetch('pending_count', 0)
|
85
|
+
end # method pending_count
|
86
|
+
|
87
|
+
def pluralize count, singular, plural = nil
|
88
|
+
"#{count} #{tools.integer.pluralize count, singular, plural}"
|
89
|
+
end # method pluralize
|
90
|
+
|
91
|
+
# @return [Hash] The hash representation of the results.
|
92
|
+
def to_h
|
93
|
+
{
|
94
|
+
'duration' => duration,
|
95
|
+
'example_count' => example_count,
|
96
|
+
'failure_count' => failure_count,
|
97
|
+
'pending_count' => pending_count,
|
98
|
+
'error_count' => error_count
|
99
|
+
} # end hash
|
100
|
+
end # method to_h
|
101
|
+
|
102
|
+
# rubocop:disable Metrics/AbcSize
|
103
|
+
|
104
|
+
# @return [String] The string representation of the results.
|
105
|
+
def to_s
|
106
|
+
str = pluralize(example_count, 'example')
|
107
|
+
|
108
|
+
str << ', ' << pluralize(failure_count, 'failure')
|
109
|
+
|
110
|
+
str << ', ' << pending_count.to_s << ' pending' if pending?
|
111
|
+
|
112
|
+
if error_count.zero?
|
113
|
+
str << " in #{duration.round(2)} seconds"
|
114
|
+
else
|
115
|
+
str << ', ' << pluralize(error_count, 'error') <<
|
116
|
+
' occurred outside of examples'
|
117
|
+
end # if-else
|
118
|
+
end # method to_s
|
119
|
+
|
120
|
+
# rubocop:enable Metrics/AbcSize
|
121
|
+
|
122
|
+
def tools
|
123
|
+
SleepingKingStudios::Tools::Toolbelt.instance
|
124
|
+
end # method tools
|
125
|
+
end # class
|
126
|
+
end # module
|