cuprum-cli 0.1.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 +34 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/LICENSE +21 -0
- data/README.md +163 -0
- data/lib/cuprum/cli/argument.rb +172 -0
- data/lib/cuprum/cli/arguments/class_methods.rb +283 -0
- data/lib/cuprum/cli/arguments.rb +16 -0
- data/lib/cuprum/cli/coercion.rb +131 -0
- data/lib/cuprum/cli/command.rb +102 -0
- data/lib/cuprum/cli/commands/ci/report.rb +121 -0
- data/lib/cuprum/cli/commands/ci/rspec_command.rb +108 -0
- data/lib/cuprum/cli/commands/ci/rspec_each_command.rb +185 -0
- data/lib/cuprum/cli/commands/ci.rb +12 -0
- data/lib/cuprum/cli/commands/echo_command.rb +76 -0
- data/lib/cuprum/cli/commands/file/generate_file.rb +141 -0
- data/lib/cuprum/cli/commands/file/new_command.rb +86 -0
- data/lib/cuprum/cli/commands/file/render_erb.rb +88 -0
- data/lib/cuprum/cli/commands/file/resolve_template.rb +136 -0
- data/lib/cuprum/cli/commands/file/templates/rspec.rb.erb +14 -0
- data/lib/cuprum/cli/commands/file/templates/ruby.rb.erb +29 -0
- data/lib/cuprum/cli/commands/file/templates.rb +71 -0
- data/lib/cuprum/cli/commands/file.rb +14 -0
- data/lib/cuprum/cli/commands.rb +12 -0
- data/lib/cuprum/cli/dependencies/file_system/mock.rb +297 -0
- data/lib/cuprum/cli/dependencies/file_system.rb +247 -0
- data/lib/cuprum/cli/dependencies/standard_io/helpers.rb +138 -0
- data/lib/cuprum/cli/dependencies/standard_io/mock.rb +85 -0
- data/lib/cuprum/cli/dependencies/standard_io.rb +110 -0
- data/lib/cuprum/cli/dependencies/system_command/mock.rb +57 -0
- data/lib/cuprum/cli/dependencies/system_command.rb +147 -0
- data/lib/cuprum/cli/dependencies.rb +25 -0
- data/lib/cuprum/cli/errors/files/file_not_writeable.rb +42 -0
- data/lib/cuprum/cli/errors/files/missing_parameter.rb +71 -0
- data/lib/cuprum/cli/errors/files/missing_template.rb +36 -0
- data/lib/cuprum/cli/errors/files/template_error.rb +37 -0
- data/lib/cuprum/cli/errors/files/template_not_resolved.rb +54 -0
- data/lib/cuprum/cli/errors/files.rb +19 -0
- data/lib/cuprum/cli/errors/system_command_failure.rb +44 -0
- data/lib/cuprum/cli/errors.rb +11 -0
- data/lib/cuprum/cli/integrations/thor/arguments_parser.rb +99 -0
- data/lib/cuprum/cli/integrations/thor/registry.rb +42 -0
- data/lib/cuprum/cli/integrations/thor/task.rb +211 -0
- data/lib/cuprum/cli/integrations/thor.rb +14 -0
- data/lib/cuprum/cli/integrations.rb +8 -0
- data/lib/cuprum/cli/metadata.rb +215 -0
- data/lib/cuprum/cli/option.rb +165 -0
- data/lib/cuprum/cli/options/class_methods.rb +232 -0
- data/lib/cuprum/cli/options/quiet.rb +32 -0
- data/lib/cuprum/cli/options/verbose.rb +32 -0
- data/lib/cuprum/cli/options.rb +18 -0
- data/lib/cuprum/cli/registry.rb +141 -0
- data/lib/cuprum/cli/rspec/deferred/arguments_examples.rb +203 -0
- data/lib/cuprum/cli/rspec/deferred/ci/report_examples.rb +450 -0
- data/lib/cuprum/cli/rspec/deferred/ci.rb +8 -0
- data/lib/cuprum/cli/rspec/deferred/dependencies/file_system_examples.rb +1469 -0
- data/lib/cuprum/cli/rspec/deferred/dependencies.rb +8 -0
- data/lib/cuprum/cli/rspec/deferred/metadata_examples.rb +856 -0
- data/lib/cuprum/cli/rspec/deferred/options_examples.rb +234 -0
- data/lib/cuprum/cli/rspec/deferred/registry_examples.rb +451 -0
- data/lib/cuprum/cli/rspec/deferred.rb +8 -0
- data/lib/cuprum/cli/rspec.rb +8 -0
- data/lib/cuprum/cli/version.rb +59 -0
- data/lib/cuprum/cli.rb +47 -0
- metadata +173 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rspec/sleeping_king_studios/deferred/provider'
|
|
4
|
+
|
|
5
|
+
require 'cuprum/cli/rspec/deferred'
|
|
6
|
+
|
|
7
|
+
module Cuprum::Cli::RSpec::Deferred
|
|
8
|
+
# Deferred examples for testing command arguments.
|
|
9
|
+
module ArgumentsExamples
|
|
10
|
+
include RSpec::SleepingKingStudios::Deferred::Provider
|
|
11
|
+
|
|
12
|
+
deferred_examples 'should define argument' \
|
|
13
|
+
do |index, argument_name, **argument_options|
|
|
14
|
+
describe "should define argument #{argument_name.inspect}" do
|
|
15
|
+
expect_method =
|
|
16
|
+
argument_options
|
|
17
|
+
.fetch(:define_method, argument_options[:type] != :boolean)
|
|
18
|
+
expect_predicate =
|
|
19
|
+
argument_options
|
|
20
|
+
.fetch(:define_predicate, argument_options[:type] == :boolean)
|
|
21
|
+
|
|
22
|
+
let(:configured_default) do
|
|
23
|
+
value = argument_options[:default]
|
|
24
|
+
|
|
25
|
+
value.is_a?(Proc) ? instance_exec(&value) : value
|
|
26
|
+
end
|
|
27
|
+
let(:configured_description) do
|
|
28
|
+
value = argument_options[:description]
|
|
29
|
+
|
|
30
|
+
value.is_a?(Proc) ? instance_exec(&value) : value
|
|
31
|
+
end
|
|
32
|
+
let(:configured_parameter_name) do
|
|
33
|
+
value = argument_options[:parameter_name]
|
|
34
|
+
|
|
35
|
+
value.is_a?(Proc) ? instance_exec(&value) : value
|
|
36
|
+
end
|
|
37
|
+
let(:configured_required) do
|
|
38
|
+
value = argument_options[:required] ? true : false
|
|
39
|
+
|
|
40
|
+
value.is_a?(Proc) ? instance_exec(&value) : value
|
|
41
|
+
end
|
|
42
|
+
let(:configured_type) do
|
|
43
|
+
value = argument_options.fetch(:type, :string)
|
|
44
|
+
|
|
45
|
+
value.is_a?(Proc) ? instance_exec(&value) : value
|
|
46
|
+
end
|
|
47
|
+
let(:configured_variadic) do
|
|
48
|
+
value = argument_options.fetch(:variadic, false)
|
|
49
|
+
|
|
50
|
+
value.is_a?(Proc) ? instance_exec(&value) : value
|
|
51
|
+
end
|
|
52
|
+
let(:configured_arguments) do
|
|
53
|
+
value = argument_options.fetch(:arguments) do
|
|
54
|
+
defined?(arguments) ? arguments : {}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
value.is_a?(Proc) ? instance_exec(&value) : value
|
|
58
|
+
end
|
|
59
|
+
let(:defined_argument) { described_class.arguments[index] }
|
|
60
|
+
|
|
61
|
+
define_method :set_argument do |argument, value|
|
|
62
|
+
arguments = subject.instance_variable_get(:@arguments)
|
|
63
|
+
|
|
64
|
+
arguments[argument] = value
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it { expect(described_class.arguments.size).to be >= 1 + index }
|
|
68
|
+
|
|
69
|
+
describe '#:argument_name' do
|
|
70
|
+
if expect_method
|
|
71
|
+
let(:reader_name) { argument_name }
|
|
72
|
+
|
|
73
|
+
it { expect(subject).to respond_to(reader_name).with(0).arguments }
|
|
74
|
+
|
|
75
|
+
context 'when the argument is not initialized' do
|
|
76
|
+
before(:example) do
|
|
77
|
+
set_argument(argument_name, configured_default)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it 'should return the default value' do
|
|
81
|
+
expect(subject.public_send(reader_name))
|
|
82
|
+
.to be == configured_default
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context 'when the argument is set' do
|
|
87
|
+
let(:value) { 'argument value' }
|
|
88
|
+
|
|
89
|
+
before(:example) do
|
|
90
|
+
set_argument(argument_name, value)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it { expect(subject.public_send(reader_name)).to be == value }
|
|
94
|
+
end
|
|
95
|
+
else
|
|
96
|
+
it { expect(subject).not_to respond_to(argument_name) }
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe '#:argument_name?' do
|
|
101
|
+
if expect_predicate
|
|
102
|
+
let(:predicate_name) { "#{argument_name}?" }
|
|
103
|
+
|
|
104
|
+
it 'should define the predicate' do
|
|
105
|
+
expect(subject).to respond_to(predicate_name).with(0).arguments
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context 'when the argument is not initialized' do
|
|
109
|
+
let(:expected) do
|
|
110
|
+
next false if configured_default.nil?
|
|
111
|
+
next false if configured_default == false
|
|
112
|
+
next true unless configured_default.respond_to?(:empty?)
|
|
113
|
+
|
|
114
|
+
!configured_default.empty?
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
before(:example) do
|
|
118
|
+
set_argument(argument_name, configured_default)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'should return the default value' do
|
|
122
|
+
expect(subject.public_send(predicate_name)).to be == expected
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
context 'when the argument is set to false' do
|
|
127
|
+
before(:example) do
|
|
128
|
+
set_argument(argument_name, false)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it { expect(subject.public_send(predicate_name)).to be false }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
context 'when the argument is set to true' do
|
|
135
|
+
before(:example) do
|
|
136
|
+
set_argument(argument_name, true)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it { expect(subject.public_send(predicate_name)).to be true }
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
if argument_options[:type] != :boolean
|
|
143
|
+
context 'when the argument is set to an Object' do
|
|
144
|
+
before(:example) do
|
|
145
|
+
set_argument(argument_name, Object.new.freeze)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it { expect(subject.public_send(predicate_name)).to be true }
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
context 'when the argument is set to an empty value' do
|
|
152
|
+
before(:example) do
|
|
153
|
+
set_argument(argument_name, '')
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it { expect(subject.public_send(predicate_name)).to be false }
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
context 'when the argument is set to a non-empty value' do
|
|
160
|
+
before(:example) do
|
|
161
|
+
set_argument(argument_name, 'value')
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it { expect(subject.public_send(predicate_name)).to be true }
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
else
|
|
168
|
+
it { expect(subject).not_to respond_to(:"#{argument_name}?") }
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
describe '#default' do
|
|
173
|
+
it { expect(defined_argument.default).to be == configured_default }
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
describe '#description' do
|
|
177
|
+
it 'should return the option description' do
|
|
178
|
+
expect(defined_argument.description).to be == configured_description
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
describe '#parameter_name' do
|
|
183
|
+
it 'should return the option parameter name' do
|
|
184
|
+
expect(defined_argument.parameter_name)
|
|
185
|
+
.to be == configured_parameter_name
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
describe '#required?' do
|
|
190
|
+
it { expect(defined_argument.required?).to be configured_required }
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
describe '#type' do
|
|
194
|
+
it { expect(defined_argument.type).to be configured_type }
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
describe '#variadic?' do
|
|
198
|
+
it { expect(defined_argument.variadic?).to be configured_variadic }
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rspec/sleeping_king_studios/deferred/provider'
|
|
4
|
+
|
|
5
|
+
require 'cuprum/cli/rspec/deferred/ci'
|
|
6
|
+
|
|
7
|
+
module Cuprum::Cli::RSpec::Deferred::Ci
|
|
8
|
+
# Deferred examples for testing CI reports.
|
|
9
|
+
module ReportExamples
|
|
10
|
+
include RSpec::SleepingKingStudios::Deferred::Provider
|
|
11
|
+
|
|
12
|
+
deferred_examples 'should define report subclasses' do
|
|
13
|
+
describe '.define' do
|
|
14
|
+
let(:properties) { super().merge(custom_property: 'custom value') }
|
|
15
|
+
let(:symbols) { %i[custom_property] }
|
|
16
|
+
let(:block) do
|
|
17
|
+
lambda do
|
|
18
|
+
private def item_name = 'trial'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
let(:subclass) { described_class.define(*symbols, &block) }
|
|
22
|
+
let(:expected_members) do
|
|
23
|
+
described_class.members.concat(symbols)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'should define the class method' do
|
|
27
|
+
expect(described_class)
|
|
28
|
+
.to respond_to(:define)
|
|
29
|
+
.with_unlimited_arguments
|
|
30
|
+
.and_a_block
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it { expect(subclass).to be_a(Class).and be < Data }
|
|
34
|
+
|
|
35
|
+
it { expect(subclass.members).to be == expected_members }
|
|
36
|
+
|
|
37
|
+
describe 'with a report subclass' do
|
|
38
|
+
let(:described_class) { super().define(*symbols, &block) }
|
|
39
|
+
let(:empty_properties) do
|
|
40
|
+
{
|
|
41
|
+
custom_property: nil,
|
|
42
|
+
duration: 0,
|
|
43
|
+
total_count: 0
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
let(:other_properties) do
|
|
47
|
+
{
|
|
48
|
+
custom_property: 'Other Value',
|
|
49
|
+
duration: 5.0,
|
|
50
|
+
error_count: 5,
|
|
51
|
+
failure_count: 15,
|
|
52
|
+
label: 'Other Report',
|
|
53
|
+
pending_count: 25,
|
|
54
|
+
success_count: 35,
|
|
55
|
+
total_count: 75
|
|
56
|
+
}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
include_deferred 'should implement the CI report interface',
|
|
60
|
+
item_name: 'trials'
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
deferred_examples 'should implement the CI report interface' \
|
|
66
|
+
do |item_name: 'item'|
|
|
67
|
+
describe '#duration' do
|
|
68
|
+
include_examples 'should define reader',
|
|
69
|
+
:duration,
|
|
70
|
+
-> { properties[:duration] }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
describe '#error_count' do
|
|
74
|
+
include_examples 'should define reader', :error_count, 0
|
|
75
|
+
|
|
76
|
+
context 'when initialized with error_count: value' do
|
|
77
|
+
let(:properties) { super().merge(error_count: 10) }
|
|
78
|
+
|
|
79
|
+
it { expect(subject.error_count).to be == properties[:error_count] }
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe '#errored?' do
|
|
84
|
+
include_examples 'should define predicate', :errored?, false
|
|
85
|
+
|
|
86
|
+
context 'when initialized with error_count: value' do
|
|
87
|
+
let(:properties) { super().merge(error_count: 10) }
|
|
88
|
+
|
|
89
|
+
it { expect(subject.errored?).to be true }
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe '#failure?' do
|
|
94
|
+
include_examples 'should define predicate', :failure?, false
|
|
95
|
+
|
|
96
|
+
context 'when initialized with failure_count: value' do
|
|
97
|
+
let(:properties) { super().merge(failure_count: 20) }
|
|
98
|
+
|
|
99
|
+
it { expect(subject.failure?).to be true }
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
describe '#failure_count' do
|
|
104
|
+
include_examples 'should define reader', :failure_count, 0
|
|
105
|
+
|
|
106
|
+
context 'when initialized with failure_count: value' do
|
|
107
|
+
let(:properties) { super().merge(failure_count: 20) }
|
|
108
|
+
|
|
109
|
+
it 'should return the failure count' do
|
|
110
|
+
expect(subject.failure_count).to be == properties[:failure_count]
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
describe '#label' do
|
|
116
|
+
include_examples 'should define reader', :label, nil
|
|
117
|
+
|
|
118
|
+
context 'when initialized with label: value' do
|
|
119
|
+
let(:properties) { super().merge(label: 'Custom Integration') }
|
|
120
|
+
|
|
121
|
+
it { expect(subject.label).to be == properties[:label] }
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
describe '#merge' do
|
|
126
|
+
it 'should define the method' do
|
|
127
|
+
expect(subject)
|
|
128
|
+
.to respond_to(:merge)
|
|
129
|
+
.with(1).argument
|
|
130
|
+
.and_keywords(:with_label)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
describe 'with nil' do
|
|
134
|
+
let(:error_message) do
|
|
135
|
+
message = tools.assertions.error_message_for(
|
|
136
|
+
'instance_of',
|
|
137
|
+
as: 'report',
|
|
138
|
+
expected: described_class
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
/#{message}/
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'should raise an exception' do
|
|
145
|
+
expect { subject.merge(nil) }
|
|
146
|
+
.to raise_error ArgumentError, error_message
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
describe 'with an Object' do
|
|
151
|
+
let(:error_message) do
|
|
152
|
+
message = tools.assertions.error_message_for(
|
|
153
|
+
'instance_of',
|
|
154
|
+
as: 'report',
|
|
155
|
+
expected: described_class
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
/#{message}/
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it 'should raise an exception' do
|
|
162
|
+
expect { subject.merge(Object.new.freeze) }
|
|
163
|
+
.to raise_error ArgumentError, error_message
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
describe 'with an empty report' do
|
|
168
|
+
let(:empty_properties) do
|
|
169
|
+
next super() if defined?(super())
|
|
170
|
+
|
|
171
|
+
{
|
|
172
|
+
duration: 0,
|
|
173
|
+
total_count: 0
|
|
174
|
+
}
|
|
175
|
+
end
|
|
176
|
+
let(:other_report) do
|
|
177
|
+
described_class.new(**empty_properties)
|
|
178
|
+
end
|
|
179
|
+
let(:merged) { subject.merge(other_report) }
|
|
180
|
+
let(:expected) do
|
|
181
|
+
{
|
|
182
|
+
duration: subject.duration,
|
|
183
|
+
error_count: subject.error_count,
|
|
184
|
+
failure_count: subject.failure_count,
|
|
185
|
+
label: subject.label,
|
|
186
|
+
pending_count: subject.pending_count,
|
|
187
|
+
success_count: subject.success_count,
|
|
188
|
+
total_count: subject.total_count
|
|
189
|
+
}
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it { expect(merged).to be_a described_class }
|
|
193
|
+
|
|
194
|
+
it { expect(merged).to have_attributes(**expected) }
|
|
195
|
+
|
|
196
|
+
describe 'with label: value' do
|
|
197
|
+
let(:with_label) { 'Merged Report' }
|
|
198
|
+
let(:merged) { subject.merge(other_report, with_label:) }
|
|
199
|
+
|
|
200
|
+
it { expect(merged.label).to be == with_label }
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
context 'when initialized with label: value' do
|
|
204
|
+
let(:properties) { super().merge(label: 'Custom Integration') }
|
|
205
|
+
|
|
206
|
+
it { expect(merged.label).to be == subject.label }
|
|
207
|
+
|
|
208
|
+
describe 'with label: value' do
|
|
209
|
+
let(:with_label) { 'Merged Report' }
|
|
210
|
+
let(:merged) { subject.merge(other_report, with_label:) }
|
|
211
|
+
|
|
212
|
+
it { expect(merged.label).to be == with_label }
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
context 'when initialized with multiple counts' do
|
|
217
|
+
let(:properties) do
|
|
218
|
+
super().merge(
|
|
219
|
+
error_count: 10,
|
|
220
|
+
failure_count: 20,
|
|
221
|
+
pending_count: 30
|
|
222
|
+
)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
it { expect(merged).to have_attributes(**expected) }
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
describe 'with a non-empty report' do
|
|
230
|
+
let(:other_properties) do
|
|
231
|
+
next super() if defined?(super())
|
|
232
|
+
|
|
233
|
+
{
|
|
234
|
+
duration: 5.0,
|
|
235
|
+
error_count: 5,
|
|
236
|
+
failure_count: 15,
|
|
237
|
+
label: 'Other Report',
|
|
238
|
+
pending_count: 25,
|
|
239
|
+
success_count: 35,
|
|
240
|
+
total_count: 75
|
|
241
|
+
}
|
|
242
|
+
end
|
|
243
|
+
let(:other_report) do
|
|
244
|
+
described_class.new(**other_properties)
|
|
245
|
+
end
|
|
246
|
+
let(:merged) { subject.merge(other_report) }
|
|
247
|
+
let(:expected) do
|
|
248
|
+
{
|
|
249
|
+
duration: subject.duration + other_report.duration,
|
|
250
|
+
error_count: subject.error_count + other_report.error_count,
|
|
251
|
+
failure_count: subject.failure_count + other_report.failure_count,
|
|
252
|
+
label: other_report.label,
|
|
253
|
+
pending_count: subject.pending_count + other_report.pending_count,
|
|
254
|
+
success_count: subject.success_count + other_report.success_count,
|
|
255
|
+
total_count: subject.total_count + other_report.total_count
|
|
256
|
+
}
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
it { expect(merged).to be_a described_class }
|
|
260
|
+
|
|
261
|
+
it { expect(merged).to have_attributes(**expected) }
|
|
262
|
+
|
|
263
|
+
describe 'with label: value' do
|
|
264
|
+
let(:with_label) { 'Merged Report' }
|
|
265
|
+
let(:merged) { subject.merge(other_report, with_label:) }
|
|
266
|
+
|
|
267
|
+
it { expect(merged.label).to be == with_label }
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
context 'when initialized with label: value' do
|
|
271
|
+
let(:properties) { super().merge(label: 'Custom Integration') }
|
|
272
|
+
let(:expected_label) { "#{subject.label} + #{other_report.label}" }
|
|
273
|
+
|
|
274
|
+
it { expect(merged.label).to be == expected_label }
|
|
275
|
+
|
|
276
|
+
describe 'with label: value' do
|
|
277
|
+
let(:with_label) { 'Merged Report' }
|
|
278
|
+
let(:merged) { subject.merge(other_report, with_label:) }
|
|
279
|
+
|
|
280
|
+
it { expect(merged.label).to be == with_label }
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
context 'when initialized with multiple counts' do
|
|
285
|
+
let(:properties) do
|
|
286
|
+
super().merge(
|
|
287
|
+
error_count: 10,
|
|
288
|
+
failure_count: 20,
|
|
289
|
+
pending_count: 30
|
|
290
|
+
)
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
it { expect(merged).to have_attributes(**expected) }
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
describe '#pending?' do
|
|
299
|
+
include_examples 'should define predicate', :pending?, false
|
|
300
|
+
|
|
301
|
+
context 'when initialized with pending_count: value' do
|
|
302
|
+
let(:properties) { super().merge(pending_count: 30) }
|
|
303
|
+
|
|
304
|
+
it { expect(subject.pending?).to be true }
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
describe '#pending_count' do
|
|
309
|
+
include_examples 'should define reader', :pending_count, 0
|
|
310
|
+
|
|
311
|
+
context 'when initialized with pending_count: value' do
|
|
312
|
+
let(:properties) { super().merge(pending_count: 30) }
|
|
313
|
+
|
|
314
|
+
it 'should reutrn the pending count' do
|
|
315
|
+
expect(subject.pending_count).to be == properties[:pending_count]
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
describe '#success?' do
|
|
321
|
+
include_examples 'should define predicate', :success?, true
|
|
322
|
+
|
|
323
|
+
context 'when initialized with error_count: value' do
|
|
324
|
+
let(:properties) { super().merge(error_count: 10) }
|
|
325
|
+
|
|
326
|
+
it { expect(subject.success?).to be false }
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
context 'when initialized with failure_count: value' do
|
|
330
|
+
let(:properties) { super().merge(failure_count: 20) }
|
|
331
|
+
|
|
332
|
+
it { expect(subject.success?).to be false }
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
context 'when initialized with pending_count: value' do
|
|
336
|
+
let(:properties) { super().merge(pending_count: 30) }
|
|
337
|
+
|
|
338
|
+
it { expect(subject.success?).to be true }
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
describe '#success_count' do
|
|
343
|
+
include_examples 'should define reader',
|
|
344
|
+
:success_count,
|
|
345
|
+
-> { properties[:total_count] }
|
|
346
|
+
|
|
347
|
+
context 'when initialized with failure_count: value' do
|
|
348
|
+
let(:properties) { super().merge(failure_count: 20) }
|
|
349
|
+
let(:expected) do
|
|
350
|
+
properties[:total_count] - properties[:failure_count]
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
it { expect(subject.success_count).to be == expected }
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
context 'when initialized with pending_count: value' do
|
|
357
|
+
let(:properties) { super().merge(pending_count: 20) }
|
|
358
|
+
let(:expected) do
|
|
359
|
+
properties[:total_count] - properties[:pending_count]
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
it { expect(subject.success_count).to be == expected }
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
context 'when initialized with multiple counts' do
|
|
366
|
+
let(:properties) do
|
|
367
|
+
super().merge(failure_count: 10, pending_count: 20)
|
|
368
|
+
end
|
|
369
|
+
let(:expected) do
|
|
370
|
+
properties[:total_count] - (
|
|
371
|
+
properties[:pending_count] + properties[:failure_count]
|
|
372
|
+
)
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
it { expect(subject.success_count).to be == expected }
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
context 'when initialized with success_count: value' do
|
|
379
|
+
let(:properties) { super().merge(success_count: 25) }
|
|
380
|
+
|
|
381
|
+
it 'should return the success count' do
|
|
382
|
+
expect(subject.success_count).to be == properties[:success_count]
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
context 'when initialized with multiple counts' do
|
|
386
|
+
let(:properties) do
|
|
387
|
+
super().merge(failure_count: 10, pending_count: 20)
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
it 'should return the success count' do
|
|
391
|
+
expect(subject.success_count).to be == properties[:success_count]
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
describe '#summary' do
|
|
398
|
+
let(:item_label) { tools.str.pluralize(item_name) }
|
|
399
|
+
let(:expected) do
|
|
400
|
+
"#{properties[:total_count]} #{item_label}, " \
|
|
401
|
+
"#{properties.fetch(:failure_count, 0)} failures"
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
it { expect(subject).to respond_to(:summary).with(0).arguments }
|
|
405
|
+
|
|
406
|
+
it { expect(subject.summary).to be == expected }
|
|
407
|
+
|
|
408
|
+
context 'when initialized with error_count: value' do
|
|
409
|
+
let(:properties) { super().merge(error_count: 10) }
|
|
410
|
+
let(:expected) { "#{super()}, #{properties[:error_count]} errors" }
|
|
411
|
+
|
|
412
|
+
it { expect(subject.summary).to be == expected }
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
context 'when initialized with failure_count: value' do
|
|
416
|
+
let(:properties) { super().merge(failure_count: 20) }
|
|
417
|
+
|
|
418
|
+
it { expect(subject.summary).to be == expected }
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
context 'when initialized with pending_count: value' do
|
|
422
|
+
let(:properties) { super().merge(pending_count: 30) }
|
|
423
|
+
let(:expected) do
|
|
424
|
+
"#{super()}, #{properties[:pending_count]} pending"
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
it { expect(subject.summary).to be == expected }
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
context 'when initialized with multiple counts' do
|
|
431
|
+
let(:properties) do
|
|
432
|
+
super().merge(error_count: 10, failure_count: 20, pending_count: 30)
|
|
433
|
+
end
|
|
434
|
+
let(:expected) do
|
|
435
|
+
"#{super()}, #{properties[:pending_count]} pending, " \
|
|
436
|
+
"#{properties[:error_count]} errors"
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
it { expect(subject.summary).to be == expected }
|
|
440
|
+
end
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
describe '#total_count' do
|
|
444
|
+
include_examples 'should define reader',
|
|
445
|
+
:total_count,
|
|
446
|
+
-> { properties[:total_count] }
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
end
|
|
450
|
+
end
|