apiwork-rspec 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 +7 -0
- data/LICENSE.txt +21 -0
- data/Rakefile +10 -0
- data/lib/apiwork/rspec/matchers/base_matcher.rb +44 -0
- data/lib/apiwork/rspec/matchers/define_contact_matcher.rb +80 -0
- data/lib/apiwork/rspec/matchers/define_enum_matcher.rb +139 -0
- data/lib/apiwork/rspec/matchers/define_license_matcher.rb +53 -0
- data/lib/apiwork/rspec/matchers/define_server_matcher.rb +50 -0
- data/lib/apiwork/rspec/matchers/have_association_matcher.rb +247 -0
- data/lib/apiwork/rspec/matchers/have_attribute_matcher.rb +283 -0
- data/lib/apiwork/rspec/matchers/have_description_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_discriminator_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_example_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_export_matcher.rb +29 -0
- data/lib/apiwork/rspec/matchers/have_identifier_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_import_matcher.rb +34 -0
- data/lib/apiwork/rspec/matchers/have_key_format_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_model_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_operation_id_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_param_matcher.rb +222 -0
- data/lib/apiwork/rspec/matchers/have_path_format_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_raises_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_representation_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_resource_matcher.rb +142 -0
- data/lib/apiwork/rspec/matchers/have_root_matcher.rb +35 -0
- data/lib/apiwork/rspec/matchers/have_summary_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_tags_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_terms_of_service_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_title_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_type_name_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/have_variant_matcher.rb +127 -0
- data/lib/apiwork/rspec/matchers/have_version_matcher.rb +30 -0
- data/lib/apiwork/rspec/matchers/no_content_matcher.rb +22 -0
- data/lib/apiwork/rspec/matchers/param_wrapper.rb +17 -0
- data/lib/apiwork/rspec/matchers.rb +388 -0
- data/lib/apiwork/rspec/version.rb +7 -0
- data/lib/apiwork/rspec.rb +25 -0
- data/lib/apiwork-rspec.rb +3 -0
- metadata +154 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module RSpec
|
|
5
|
+
module Matchers
|
|
6
|
+
# @api public
|
|
7
|
+
# Matcher for representation attributes.
|
|
8
|
+
class HaveAttributeMatcher < BaseMatcher
|
|
9
|
+
BOOLEAN_CHECKS = {
|
|
10
|
+
deprecated: :deprecated?,
|
|
11
|
+
empty: :empty,
|
|
12
|
+
filterable: :filterable?,
|
|
13
|
+
nullable: :nullable?,
|
|
14
|
+
optional: :optional?,
|
|
15
|
+
sortable: :sortable?,
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
VALUE_CHECKS = {
|
|
19
|
+
default: :default,
|
|
20
|
+
description: :description,
|
|
21
|
+
enum: :enum,
|
|
22
|
+
example: :example,
|
|
23
|
+
format: :format,
|
|
24
|
+
max: :max,
|
|
25
|
+
min: :min,
|
|
26
|
+
type: :type,
|
|
27
|
+
}.freeze
|
|
28
|
+
|
|
29
|
+
def initialize(name)
|
|
30
|
+
super()
|
|
31
|
+
@name = name
|
|
32
|
+
@checks = {}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @api public
|
|
36
|
+
# Requires the attribute to have the expected type.
|
|
37
|
+
#
|
|
38
|
+
# @param type [Symbol] [:array, :binary, :boolean, :date, :datetime, :decimal, :integer, :number, :object, :record, :string, :time, :unknown, :uuid]
|
|
39
|
+
# The type.
|
|
40
|
+
# @return [self]
|
|
41
|
+
def of_type(type)
|
|
42
|
+
@checks[:type] = type
|
|
43
|
+
self
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @api public
|
|
47
|
+
# Requires the attribute to be writable.
|
|
48
|
+
#
|
|
49
|
+
# @param action [Symbol, Boolean] (true) [Symbol: :create, :update]
|
|
50
|
+
# The action to check writability for, or `true` for any action.
|
|
51
|
+
# @return [self]
|
|
52
|
+
def writable(action = true)
|
|
53
|
+
@checks[:writable] = action
|
|
54
|
+
self
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @api public
|
|
58
|
+
# Requires the attribute to be empty.
|
|
59
|
+
#
|
|
60
|
+
# @return [self]
|
|
61
|
+
def empty
|
|
62
|
+
@checks[:empty] = true
|
|
63
|
+
self
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# @api public
|
|
67
|
+
# Requires the attribute to be deprecated.
|
|
68
|
+
#
|
|
69
|
+
# @return [self]
|
|
70
|
+
def deprecated
|
|
71
|
+
@checks[:deprecated] = true
|
|
72
|
+
self
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @api public
|
|
76
|
+
# Requires the attribute to be optional.
|
|
77
|
+
#
|
|
78
|
+
# @return [self]
|
|
79
|
+
def optional
|
|
80
|
+
@checks[:optional] = true
|
|
81
|
+
self
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @api public
|
|
85
|
+
# Requires the attribute to be nullable.
|
|
86
|
+
#
|
|
87
|
+
# @return [self]
|
|
88
|
+
def nullable
|
|
89
|
+
@checks[:nullable] = true
|
|
90
|
+
self
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# @api public
|
|
94
|
+
# Requires the attribute to be filterable.
|
|
95
|
+
#
|
|
96
|
+
# @return [self]
|
|
97
|
+
def filterable
|
|
98
|
+
@checks[:filterable] = true
|
|
99
|
+
self
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# @api public
|
|
103
|
+
# Requires the attribute to be sortable.
|
|
104
|
+
#
|
|
105
|
+
# @return [self]
|
|
106
|
+
def sortable
|
|
107
|
+
@checks[:sortable] = true
|
|
108
|
+
self
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# @api public
|
|
112
|
+
# Requires the attribute to have the expected enum values.
|
|
113
|
+
#
|
|
114
|
+
# @param values [Array]
|
|
115
|
+
# The enum values.
|
|
116
|
+
# @return [self]
|
|
117
|
+
def with_enum(values)
|
|
118
|
+
@checks[:enum] = values
|
|
119
|
+
self
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# @api public
|
|
123
|
+
# Requires the attribute to have the expected format.
|
|
124
|
+
#
|
|
125
|
+
# @param format [Symbol] [:date, :datetime, :double, :email, :float, :hostname, :int32, :int64, :ipv4, :ipv6, :password, :text, :url, :uuid]
|
|
126
|
+
# The format. Valid formats by type: `:decimal`/`:number` (`:double`, `:float`), `:integer` (`:int32`, `:int64`),
|
|
127
|
+
# `:string` (`:date`, `:datetime`, `:email`, `:hostname`, `:ipv4`, `:ipv6`, `:password`, `:text`, `:url`, `:uuid`).
|
|
128
|
+
# @return [self]
|
|
129
|
+
def with_format(format)
|
|
130
|
+
@checks[:format] = format
|
|
131
|
+
self
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# @api public
|
|
135
|
+
# Requires the attribute to have the expected minimum.
|
|
136
|
+
#
|
|
137
|
+
# @param value [Numeric]
|
|
138
|
+
# The minimum.
|
|
139
|
+
# @return [self]
|
|
140
|
+
def with_min(value)
|
|
141
|
+
@checks[:min] = value
|
|
142
|
+
self
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# @api public
|
|
146
|
+
# Requires the attribute to have the expected maximum.
|
|
147
|
+
#
|
|
148
|
+
# @param value [Numeric]
|
|
149
|
+
# The maximum.
|
|
150
|
+
# @return [self]
|
|
151
|
+
def with_max(value)
|
|
152
|
+
@checks[:max] = value
|
|
153
|
+
self
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# @api public
|
|
157
|
+
# Requires the attribute to have the expected default.
|
|
158
|
+
#
|
|
159
|
+
# @param value [Object]
|
|
160
|
+
# The default.
|
|
161
|
+
# @return [self]
|
|
162
|
+
def with_default(value)
|
|
163
|
+
@checks[:default] = value
|
|
164
|
+
self
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# @api public
|
|
168
|
+
# Requires the attribute to have the expected description.
|
|
169
|
+
#
|
|
170
|
+
# @param text [String]
|
|
171
|
+
# The description.
|
|
172
|
+
# @return [self]
|
|
173
|
+
def with_description(text)
|
|
174
|
+
@checks[:description] = text
|
|
175
|
+
self
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# @api public
|
|
179
|
+
# Requires the attribute to have the expected example.
|
|
180
|
+
#
|
|
181
|
+
# @param value [Object]
|
|
182
|
+
# The example.
|
|
183
|
+
# @return [self]
|
|
184
|
+
def with_example(value)
|
|
185
|
+
@checks[:example] = value
|
|
186
|
+
self
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def matches?(subject)
|
|
190
|
+
@subject = subject
|
|
191
|
+
attribute = subject.attributes[@name]
|
|
192
|
+
return fail_with("expected #{format_subject} to have attribute #{@name.inspect}") unless attribute
|
|
193
|
+
|
|
194
|
+
verify_all(attribute)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def description
|
|
198
|
+
parts = ["have attribute #{@name.inspect}"]
|
|
199
|
+
parts << "of type #{@checks[:type].inspect}" if @checks.key?(:type)
|
|
200
|
+
boolean_parts = boolean_description_parts
|
|
201
|
+
parts << "that is #{join_sentence(boolean_parts)}" if boolean_parts.any?
|
|
202
|
+
VALUE_CHECKS.except(:type).each_key do |key|
|
|
203
|
+
parts << "with #{key} #{@checks[key].inspect}" if @checks.key?(key)
|
|
204
|
+
end
|
|
205
|
+
parts.join(' ')
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
private
|
|
209
|
+
|
|
210
|
+
def verify_all(attribute)
|
|
211
|
+
verify_value_checks(attribute) &&
|
|
212
|
+
verify_boolean_checks(attribute) &&
|
|
213
|
+
verify_writable(attribute)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def verify_value_checks(attribute)
|
|
217
|
+
VALUE_CHECKS.each do |key, method|
|
|
218
|
+
next unless @checks.key?(key)
|
|
219
|
+
|
|
220
|
+
actual = attribute.public_send(method)
|
|
221
|
+
next if actual == @checks[key]
|
|
222
|
+
|
|
223
|
+
return fail_with(
|
|
224
|
+
"expected #{format_subject} to have attribute #{@name.inspect} " \
|
|
225
|
+
"#{format_value_check(key, @checks[key])}, but got #{actual.inspect}",
|
|
226
|
+
)
|
|
227
|
+
end
|
|
228
|
+
true
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def verify_boolean_checks(attribute)
|
|
232
|
+
BOOLEAN_CHECKS.each do |key, method|
|
|
233
|
+
next unless @checks.key?(key)
|
|
234
|
+
next if attribute.public_send(method)
|
|
235
|
+
|
|
236
|
+
return fail_with(
|
|
237
|
+
"expected #{format_subject} to have attribute #{@name.inspect} that is #{key}, but it is not",
|
|
238
|
+
)
|
|
239
|
+
end
|
|
240
|
+
true
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def verify_writable(attribute)
|
|
244
|
+
return true unless @checks.key?(:writable)
|
|
245
|
+
|
|
246
|
+
expected = @checks[:writable]
|
|
247
|
+
if expected == true
|
|
248
|
+
return true if attribute.writable?
|
|
249
|
+
|
|
250
|
+
return fail_with(
|
|
251
|
+
"expected #{format_subject} to have attribute #{@name.inspect} that is writable, but it is not",
|
|
252
|
+
)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
return true if attribute.writable_for?(expected)
|
|
256
|
+
|
|
257
|
+
fail_with(
|
|
258
|
+
"expected #{format_subject} to have attribute #{@name.inspect} " \
|
|
259
|
+
"that is writable for #{expected.inspect}, but it is not",
|
|
260
|
+
)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def format_value_check(key, value)
|
|
264
|
+
case key
|
|
265
|
+
when :type
|
|
266
|
+
"of type #{value.inspect}"
|
|
267
|
+
else
|
|
268
|
+
"with #{key} #{value.inspect}"
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def boolean_description_parts
|
|
273
|
+
parts = []
|
|
274
|
+
BOOLEAN_CHECKS.each_key { |key| parts << key.to_s if @checks.key?(key) }
|
|
275
|
+
if @checks.key?(:writable)
|
|
276
|
+
parts << (@checks[:writable] == true ? 'writable' : "writable for #{@checks[:writable].inspect}")
|
|
277
|
+
end
|
|
278
|
+
parts
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module RSpec
|
|
5
|
+
module Matchers
|
|
6
|
+
# @api public
|
|
7
|
+
# Matcher for verifying a subject has the expected description.
|
|
8
|
+
class HaveDescriptionMatcher < BaseMatcher
|
|
9
|
+
def initialize(text)
|
|
10
|
+
super()
|
|
11
|
+
@text = text
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def matches?(subject)
|
|
15
|
+
@subject = subject
|
|
16
|
+
actual = subject.description
|
|
17
|
+
return true if actual == @text
|
|
18
|
+
|
|
19
|
+
fail_with(
|
|
20
|
+
"expected #{format_subject} to have description #{@text.inspect}, but got #{actual.inspect}",
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def description
|
|
25
|
+
"have description #{@text.inspect}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module RSpec
|
|
5
|
+
module Matchers
|
|
6
|
+
# @api public
|
|
7
|
+
# Matcher for verifying a union has the expected discriminator.
|
|
8
|
+
class HaveDiscriminatorMatcher < BaseMatcher
|
|
9
|
+
def initialize(field)
|
|
10
|
+
super()
|
|
11
|
+
@field = field
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def matches?(subject)
|
|
15
|
+
@subject = subject
|
|
16
|
+
actual = subject.discriminator
|
|
17
|
+
return true if actual == @field
|
|
18
|
+
|
|
19
|
+
fail_with(
|
|
20
|
+
"expected #{format_subject} to have discriminator #{@field.inspect}, but got #{actual.inspect}",
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def description
|
|
25
|
+
"have discriminator #{@field.inspect}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module RSpec
|
|
5
|
+
module Matchers
|
|
6
|
+
# @api public
|
|
7
|
+
# Matcher for verifying a subject has the expected example.
|
|
8
|
+
class HaveExampleMatcher < BaseMatcher
|
|
9
|
+
def initialize(value)
|
|
10
|
+
super()
|
|
11
|
+
@value = value
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def matches?(subject)
|
|
15
|
+
@subject = subject
|
|
16
|
+
actual = subject.example
|
|
17
|
+
return true if actual == @value
|
|
18
|
+
|
|
19
|
+
fail_with(
|
|
20
|
+
"expected #{format_subject} to have example #{@value.inspect}, but got #{actual.inspect}",
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def description
|
|
25
|
+
"have example #{@value.inspect}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module RSpec
|
|
5
|
+
module Matchers
|
|
6
|
+
# @api public
|
|
7
|
+
# Matcher for verifying an API has a specific export enabled.
|
|
8
|
+
class HaveExportMatcher < BaseMatcher
|
|
9
|
+
def initialize(name)
|
|
10
|
+
super()
|
|
11
|
+
@name = name
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def matches?(subject)
|
|
15
|
+
@subject = subject
|
|
16
|
+
return true if subject.export_configs.key?(@name)
|
|
17
|
+
|
|
18
|
+
fail_with(
|
|
19
|
+
"expected #{format_subject} to have export #{@name.inspect}",
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def description
|
|
24
|
+
"have export #{@name.inspect}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module RSpec
|
|
5
|
+
module Matchers
|
|
6
|
+
# @api public
|
|
7
|
+
# Matcher for verifying a contract has the expected identifier.
|
|
8
|
+
class HaveIdentifierMatcher < BaseMatcher
|
|
9
|
+
def initialize(value)
|
|
10
|
+
super()
|
|
11
|
+
@value = value
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def matches?(subject)
|
|
15
|
+
@subject = subject
|
|
16
|
+
actual = subject.identifier
|
|
17
|
+
return true if actual == @value
|
|
18
|
+
|
|
19
|
+
fail_with(
|
|
20
|
+
"expected #{format_subject} to have identifier #{@value.inspect}, but got #{actual.inspect}",
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def description
|
|
25
|
+
"have identifier #{@value.inspect}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module RSpec
|
|
5
|
+
module Matchers
|
|
6
|
+
# @api public
|
|
7
|
+
# Matcher for verifying a contract imports another contract.
|
|
8
|
+
class HaveImportMatcher < BaseMatcher
|
|
9
|
+
def initialize(klass, as:)
|
|
10
|
+
super()
|
|
11
|
+
@klass = klass
|
|
12
|
+
@alias = as
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def matches?(subject)
|
|
16
|
+
@subject = subject
|
|
17
|
+
actual = subject.imports[@alias]
|
|
18
|
+
|
|
19
|
+
return fail_with("expected #{format_subject} to have import #{@alias.inspect}") unless actual
|
|
20
|
+
return true if actual == @klass
|
|
21
|
+
|
|
22
|
+
fail_with(
|
|
23
|
+
"expected #{format_subject} to have import #{@alias.inspect} " \
|
|
24
|
+
"of #{@klass.inspect}, but got #{actual.inspect}",
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def description
|
|
29
|
+
"have import #{@klass.inspect} as #{@alias.inspect}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module RSpec
|
|
5
|
+
module Matchers
|
|
6
|
+
# @api public
|
|
7
|
+
# Matcher for verifying an API has the expected key format.
|
|
8
|
+
class HaveKeyFormatMatcher < BaseMatcher
|
|
9
|
+
def initialize(format)
|
|
10
|
+
super()
|
|
11
|
+
@format = format
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def matches?(subject)
|
|
15
|
+
@subject = subject
|
|
16
|
+
actual = subject.key_format
|
|
17
|
+
return true if actual == @format
|
|
18
|
+
|
|
19
|
+
fail_with(
|
|
20
|
+
"expected #{format_subject} to have key format #{@format.inspect}, but got #{actual.inspect}",
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def description
|
|
25
|
+
"have key format #{@format.inspect}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module RSpec
|
|
5
|
+
module Matchers
|
|
6
|
+
# @api public
|
|
7
|
+
# Matcher for verifying a representation has the expected model.
|
|
8
|
+
class HaveModelMatcher < BaseMatcher
|
|
9
|
+
def initialize(klass)
|
|
10
|
+
super()
|
|
11
|
+
@klass = klass
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def matches?(subject)
|
|
15
|
+
@subject = subject
|
|
16
|
+
actual = subject.model_class
|
|
17
|
+
return true if actual == @klass
|
|
18
|
+
|
|
19
|
+
fail_with(
|
|
20
|
+
"expected #{format_subject} to have model #{@klass.inspect}, but got #{actual.inspect}",
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def description
|
|
25
|
+
"have model #{@klass.inspect}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Apiwork
|
|
4
|
+
module RSpec
|
|
5
|
+
module Matchers
|
|
6
|
+
# @api public
|
|
7
|
+
# Matcher for verifying an action has the expected operation ID.
|
|
8
|
+
class HaveOperationIdMatcher < BaseMatcher
|
|
9
|
+
def initialize(id)
|
|
10
|
+
super()
|
|
11
|
+
@id = id
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def matches?(subject)
|
|
15
|
+
@subject = subject
|
|
16
|
+
actual = subject.operation_id
|
|
17
|
+
return true if actual == @id
|
|
18
|
+
|
|
19
|
+
fail_with(
|
|
20
|
+
"expected #{format_subject} to have operation ID #{@id.inspect}, but got #{actual.inspect}",
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def description
|
|
25
|
+
"have operation ID #{@id.inspect}"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|