Skip to content

Commit 8a52e58

Browse files
committed
Add some dubious hacks to get appropriate errors
These build on the smell of hacks from the previous commit to make this class a bit smelly. This adds some work arounds to get appropriate error messages for nodes that could be one of two types. Should we need more usage of this we probably want to refactor aspects of the ObjectFactory code to be able to handle dual types and the TypeChecker.
1 parent 6d16da6 commit 8a52e58

File tree

2 files changed

+48
-4
lines changed
  • lib/openapi3_parser/node_factory/schema
  • spec/lib/openapi3_parser/node_factory/schema

2 files changed

+48
-4
lines changed

lib/openapi3_parser/node_factory/schema/v3_1.rb

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
module Openapi3Parser
88
module NodeFactory
99
module Schema
10+
# rubocop:disable Metrics/ClassLength
1011
class V3_1 < NodeFactory::Object # rubocop:disable Naming/ClassAndModuleCamelCase
1112
using ArraySentence
1213
include Referenceable
@@ -44,13 +45,37 @@ def boolean_input?
4445
end
4546

4647
def errors
47-
@errors ||= boolean_input? ? [] : super
48+
# It's a bit janky that we do this method overloading here to handle
49+
# the dual types of a 3.1 Schema. However this is the only node we
50+
# have this dual type behaviour. We should do something more clever
51+
# in the factories if there is further precedent.
52+
@errors ||= if boolean_input?
53+
Validation::ErrorCollection.new
54+
elsif raw_input && !raw_input.is_a?(::Hash)
55+
error = Validation::Error.new(
56+
"Invalid type. Expected Object or Boolean",
57+
context,
58+
self.class
59+
)
60+
Validation::ErrorCollection.new([error])
61+
else
62+
super
63+
end
4864
end
4965

5066
def node(node_context)
51-
return super unless boolean_input?
52-
53-
Node::Schema::V3_1.new({ "boolean" => resolved_input }, node_context)
67+
# as per #errors above, this is a bit of a nasty hack to handle
68+
# dual type handling and should be refactored should there be
69+
# other nodes with the same needs
70+
if boolean_input?
71+
Node::Schema::V3_1.new({ "boolean" => resolved_input }, node_context)
72+
elsif raw_input && !raw_input.is_a?(::Hash)
73+
raise Error::InvalidType,
74+
"Invalid type for #{context.location_summary}: " \
75+
"Expected Object or Boolean"
76+
else
77+
super
78+
end
5479
end
5580

5681
def build_node(data, node_context)
@@ -122,6 +147,7 @@ def prefix_items_factory(context)
122147
)
123148
end
124149
end
150+
# rubocop:enable Metrics/ClassLength
125151
end
126152
end
127153
end

spec/lib/openapi3_parser/node_factory/schema/v3_1_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,24 @@
5050

5151
it_behaves_like "schema factory"
5252

53+
describe "type validation" do
54+
it "rejects a non object or boolean input with an appropriate explanation" do
55+
instance = described_class.new(create_node_factory_context(15))
56+
57+
expect(instance).to have_validation_error("#/").with_message("Invalid type. Expected Object or Boolean")
58+
end
59+
60+
it "raises the appropriate error when a non object or boolean input is built" do
61+
node_factory_context = create_node_factory_context("blah")
62+
instance = described_class.new(node_factory_context)
63+
node_context = node_factory_context_to_node_context(node_factory_context)
64+
65+
expect { instance.node(node_context) }
66+
.to raise_error(Openapi3Parser::Error::InvalidType,
67+
"Invalid type for #/: Expected Object or Boolean")
68+
end
69+
end
70+
5371
describe "boolean input" do
5472
it "is valid for a boolean input" do
5573
instance = described_class.new(create_node_factory_context(false))

0 commit comments

Comments
 (0)