From 5eb663782bcf4f11a5fe280f2ca80324a4ff7468 Mon Sep 17 00:00:00 2001 From: Jason Numeroff Date: Mon, 14 Nov 2022 15:29:18 -0500 Subject: [PATCH 1/4] Add parent reference to nodes --- lib/swagger/blocks/node.rb | 9 ++++----- lib/swagger/blocks/nodes/all_of_node.rb | 2 +- .../blocks/nodes/callback_destination_node.rb | 2 +- .../blocks/nodes/callback_method_node.rb | 4 ++-- lib/swagger/blocks/nodes/callback_node.rb | 2 +- lib/swagger/blocks/nodes/component_node.rb | 14 +++++++------- lib/swagger/blocks/nodes/content_node.rb | 6 +++--- lib/swagger/blocks/nodes/example_node.rb | 2 +- lib/swagger/blocks/nodes/flow_node.rb | 2 +- lib/swagger/blocks/nodes/header_node.rb | 4 ++-- lib/swagger/blocks/nodes/info_node.rb | 4 ++-- lib/swagger/blocks/nodes/items_node.rb | 2 +- lib/swagger/blocks/nodes/link_node.rb | 2 +- lib/swagger/blocks/nodes/one_of_node.rb | 2 +- lib/swagger/blocks/nodes/operation_node.rb | 14 +++++++------- lib/swagger/blocks/nodes/parameter_node.rb | 6 +++--- lib/swagger/blocks/nodes/path_node.rb | 6 +++--- lib/swagger/blocks/nodes/properties_node.rb | 2 +- lib/swagger/blocks/nodes/property_node.rb | 4 ++-- lib/swagger/blocks/nodes/request_body_node.rb | 2 +- lib/swagger/blocks/nodes/response_node.rb | 12 ++++++------ lib/swagger/blocks/nodes/root_node.rb | 18 +++++++++--------- lib/swagger/blocks/nodes/schema_node.rb | 12 ++++++------ .../blocks/nodes/security_scheme_node.rb | 4 ++-- lib/swagger/blocks/nodes/server_node.rb | 2 +- lib/swagger/blocks/nodes/tag_node.rb | 2 +- spec/lib/nodes/root_node_spec.rb | 13 +++++++++++++ 27 files changed, 83 insertions(+), 71 deletions(-) create mode 100644 spec/lib/nodes/root_node_spec.rb diff --git a/lib/swagger/blocks/node.rb b/lib/swagger/blocks/node.rb index c3d290b..4271f9c 100644 --- a/lib/swagger/blocks/node.rb +++ b/lib/swagger/blocks/node.rb @@ -2,17 +2,16 @@ module Swagger module Blocks # Base node for representing every object in the Swagger DSL. class Node - attr_accessor :name + attr_accessor :parent, :name attr_writer :version VERSION_2 = '2.0' VERSION_3 = '3.0.0' - def self.call(options = {}, &block) + def self.call(parent: nil, name: nil, version: nil, inline_keys: nil, &block) # Create a new instance and evaluate the block into it. instance = new - instance.name = options[:name] if options[:name] - instance.version = options[:version] - instance.keys options[:inline_keys] + instance.parent, instance.name, instance.version = parent, name, version + instance.keys inline_keys instance.instance_eval(&block) if block instance end diff --git a/lib/swagger/blocks/nodes/all_of_node.rb b/lib/swagger/blocks/nodes/all_of_node.rb index 95a3a1c..05c4f09 100644 --- a/lib/swagger/blocks/nodes/all_of_node.rb +++ b/lib/swagger/blocks/nodes/all_of_node.rb @@ -35,7 +35,7 @@ def key(key, value) end def schema(inline_keys = nil, &block) - data << Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block) + data << Swagger::Blocks::Nodes::SchemaNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/callback_destination_node.rb b/lib/swagger/blocks/nodes/callback_destination_node.rb index 61d4bb8..0bf62d1 100644 --- a/lib/swagger/blocks/nodes/callback_destination_node.rb +++ b/lib/swagger/blocks/nodes/callback_destination_node.rb @@ -3,7 +3,7 @@ module Blocks module Nodes class CallbackDestinationNode < Node def method(method_name, inline_keys = nil, &block) - self.data[method_name] = Swagger::Blocks::Nodes::CallbackMethodNode.call(version: version, inline_keys: inline_keys, &block) + self.data[method_name] = Swagger::Blocks::Nodes::CallbackMethodNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/callback_method_node.rb b/lib/swagger/blocks/nodes/callback_method_node.rb index 3356ac7..e98e27c 100644 --- a/lib/swagger/blocks/nodes/callback_method_node.rb +++ b/lib/swagger/blocks/nodes/callback_method_node.rb @@ -3,12 +3,12 @@ module Blocks module Nodes class CallbackMethodNode < Node def request_body(inline_keys = nil, &block) - self.data[:requestBody] = Swagger::Blocks::Nodes::RequestBodyNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:requestBody] = Swagger::Blocks::Nodes::RequestBodyNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def response(resp, inline_keys = nil, &block) self.data[:responses] ||= {} - self.data[:responses][resp] = Swagger::Blocks::Nodes::ResponseNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:responses][resp] = Swagger::Blocks::Nodes::ResponseNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/callback_node.rb b/lib/swagger/blocks/nodes/callback_node.rb index 76c0b30..8e361ba 100644 --- a/lib/swagger/blocks/nodes/callback_node.rb +++ b/lib/swagger/blocks/nodes/callback_node.rb @@ -3,7 +3,7 @@ module Blocks module Nodes class CallbackNode < Node def destination(address, inline_keys = nil, &block) - self.data[address] = Swagger::Blocks::Nodes::CallbackDestinationNode.call(version: version, inline_keys: inline_keys, &block) + self.data[address] = Swagger::Blocks::Nodes::CallbackDestinationNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/component_node.rb b/lib/swagger/blocks/nodes/component_node.rb index cc2582b..7a7b036 100644 --- a/lib/swagger/blocks/nodes/component_node.rb +++ b/lib/swagger/blocks/nodes/component_node.rb @@ -11,38 +11,38 @@ def schema(name, inline_keys = nil, &block) schema_node.instance_eval(&block) else # First time we've seen this schema_node - self.data[:schemas][name] = Swagger::Blocks::Nodes::SchemaNode.call(version: '3.0.0', inline_keys: inline_keys, &block) + self.data[:schemas][name] = Swagger::Blocks::Nodes::SchemaNode.call(parent: self, version: '3.0.0', inline_keys: inline_keys, &block) end end def link(name, inline_keys = nil, &block) self.data[:links] ||= {} - self.data[:links][name] = Swagger::Blocks::Nodes::LinkNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:links][name] = Swagger::Blocks::Nodes::LinkNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def example(name, inline_keys = nil, &block) self.data[:examples] ||= {} - self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def security_scheme(name, inline_keys = nil, &block) self.data[:securitySchemes] ||= {} - self.data[:securitySchemes][name] = Swagger::Blocks::Nodes::SecuritySchemeNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:securitySchemes][name] = Swagger::Blocks::Nodes::SecuritySchemeNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def parameter(name, inline_keys = nil, &block) self.data[:parameters] ||= {} - self.data[:parameters][name] = Swagger::Blocks::Nodes::ParameterNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:parameters][name] = Swagger::Blocks::Nodes::ParameterNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def request_body(name, inline_keys = nil, &block) self.data[:requestBodies] ||= {} - self.data[:requestBodies][name] = Swagger::Blocks::Nodes::RequestBodyNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:requestBodies][name] = Swagger::Blocks::Nodes::RequestBodyNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def response(name, inline_keys = nil, &block) self.data[:responses] ||= {} - self.data[:responses][name] = Swagger::Blocks::Nodes::ResponseNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:responses][name] = Swagger::Blocks::Nodes::ResponseNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/content_node.rb b/lib/swagger/blocks/nodes/content_node.rb index af3a821..818472b 100644 --- a/lib/swagger/blocks/nodes/content_node.rb +++ b/lib/swagger/blocks/nodes/content_node.rb @@ -3,15 +3,15 @@ module Blocks module Nodes class ContentNode < Node def schema(inline_keys = nil, &block) - self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def example(name = nil, inline_keys = nil, &block) if name.nil? - self.data[:example] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:example] = Swagger::Blocks::Nodes::ExampleNode.call(parent: self, version: version, inline_keys: inline_keys, &block) else self.data[:examples] ||= {} - self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/example_node.rb b/lib/swagger/blocks/nodes/example_node.rb index 0f7d912..526f076 100644 --- a/lib/swagger/blocks/nodes/example_node.rb +++ b/lib/swagger/blocks/nodes/example_node.rb @@ -3,7 +3,7 @@ module Blocks module Nodes class ExampleNode < Node def value(inline_keys = nil, &block) - self.data[:value] = Swagger::Blocks::Nodes::ValueNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:value] = Swagger::Blocks::Nodes::ValueNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/flow_node.rb b/lib/swagger/blocks/nodes/flow_node.rb index 1f28338..6b13772 100644 --- a/lib/swagger/blocks/nodes/flow_node.rb +++ b/lib/swagger/blocks/nodes/flow_node.rb @@ -3,7 +3,7 @@ module Blocks module Nodes class FlowNode < Node def scopes(inline_keys = nil, &block) - self.data[:scopes] = Swagger::Blocks::Nodes::ScopesNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:scopes] = Swagger::Blocks::Nodes::ScopesNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/header_node.rb b/lib/swagger/blocks/nodes/header_node.rb index b59ef22..4b0d9f6 100644 --- a/lib/swagger/blocks/nodes/header_node.rb +++ b/lib/swagger/blocks/nodes/header_node.rb @@ -4,11 +4,11 @@ module Nodes # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#headerObject class HeaderNode < Node def items(inline_keys = nil, &block) - self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def schema(inline_keys = nil, &block) - self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/info_node.rb b/lib/swagger/blocks/nodes/info_node.rb index 5659d3e..3cf0faf 100644 --- a/lib/swagger/blocks/nodes/info_node.rb +++ b/lib/swagger/blocks/nodes/info_node.rb @@ -4,11 +4,11 @@ module Nodes # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#infoObject class InfoNode < Node def contact(inline_keys = nil, &block) - self.data[:contact] = Swagger::Blocks::Nodes::ContactNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:contact] = Swagger::Blocks::Nodes::ContactNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def license(inline_keys = nil, &block) - self.data[:license] = Swagger::Blocks::Nodes::LicenseNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:license] = Swagger::Blocks::Nodes::LicenseNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/items_node.rb b/lib/swagger/blocks/nodes/items_node.rb index cee8f49..7a2da54 100644 --- a/lib/swagger/blocks/nodes/items_node.rb +++ b/lib/swagger/blocks/nodes/items_node.rb @@ -10,7 +10,7 @@ def property(name, inline_keys = nil, &block) end def items(inline_keys = nil, &block) - self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/link_node.rb b/lib/swagger/blocks/nodes/link_node.rb index 8fd398d..f826e2a 100644 --- a/lib/swagger/blocks/nodes/link_node.rb +++ b/lib/swagger/blocks/nodes/link_node.rb @@ -3,7 +3,7 @@ module Blocks module Nodes class LinkNode < Node def parameters(inline_keys = nil, &block) - self.data[:parameters] ||= Swagger::Blocks::Nodes::LinkParameterNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:parameters] ||= Swagger::Blocks::Nodes::LinkParameterNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/one_of_node.rb b/lib/swagger/blocks/nodes/one_of_node.rb index eef6771..231b758 100644 --- a/lib/swagger/blocks/nodes/one_of_node.rb +++ b/lib/swagger/blocks/nodes/one_of_node.rb @@ -3,7 +3,7 @@ module Blocks module Nodes class OneOfNode < Node def items(inline_keys = nil, &block) - self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/operation_node.rb b/lib/swagger/blocks/nodes/operation_node.rb index bf2ded5..4b62466 100644 --- a/lib/swagger/blocks/nodes/operation_node.rb +++ b/lib/swagger/blocks/nodes/operation_node.rb @@ -7,37 +7,37 @@ def parameter(inline_keys = nil, &block) inline_keys = {'$ref' => "#/parameters/#{inline_keys}"} if inline_keys.is_a?(Symbol) self.data[:parameters] ||= [] - self.data[:parameters] << Swagger::Blocks::Nodes::ParameterNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:parameters] << Swagger::Blocks::Nodes::ParameterNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def response(resp, inline_keys = nil, &block) # TODO validate 'resp' is as per spec self.data[:responses] ||= {} - self.data[:responses][resp] = Swagger::Blocks::Nodes::ResponseNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:responses][resp] = Swagger::Blocks::Nodes::ResponseNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def externalDocs(inline_keys = nil, &block) - self.data[:externalDocs] = Swagger::Blocks::Nodes::ExternalDocsNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:externalDocs] = Swagger::Blocks::Nodes::ExternalDocsNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def security(inline_keys = nil, &block) self.data[:security] ||= [] - self.data[:security] << Swagger::Blocks::Nodes::SecurityRequirementNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:security] << Swagger::Blocks::Nodes::SecurityRequirementNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def request_body(inline_keys = nil, &block) - self.data[:requestBody] = Swagger::Blocks::Nodes::RequestBodyNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:requestBody] = Swagger::Blocks::Nodes::RequestBodyNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def callback(event_name, inline_keys = nil, &block) self.data[:callbacks] ||= {} - self.data[:callbacks][event_name] = Swagger::Blocks::Nodes::CallbackNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:callbacks][event_name] = Swagger::Blocks::Nodes::CallbackNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def server(inline_keys = nil, &block) raise NotSupportedError unless is_openapi_3_0? self.data[:servers] ||= [] - self.data[:servers] << Swagger::Blocks::Nodes::ServerNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:servers] << Swagger::Blocks::Nodes::ServerNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/parameter_node.rb b/lib/swagger/blocks/nodes/parameter_node.rb index e5bc39a..26cf944 100644 --- a/lib/swagger/blocks/nodes/parameter_node.rb +++ b/lib/swagger/blocks/nodes/parameter_node.rb @@ -4,16 +4,16 @@ module Nodes # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#parameter-object class ParameterNode < Node def schema(inline_keys = nil, &block) - self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def items(inline_keys = nil, &block) - self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def example(name, inline_keys = nil, &block) self.data[:examples] ||= {} - self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/path_node.rb b/lib/swagger/blocks/nodes/path_node.rb index e321796..6c3f00a 100644 --- a/lib/swagger/blocks/nodes/path_node.rb +++ b/lib/swagger/blocks/nodes/path_node.rb @@ -9,20 +9,20 @@ class PathNode < Node def operation(op, inline_keys = nil, &block) op = op.to_sym raise ArgumentError.new("#{name} not in #{OPERATION_TYPES}") if !OPERATION_TYPES.include?(op) - self.data[op] = Swagger::Blocks::Nodes::OperationNode.call(version: version, inline_keys: inline_keys, &block) + self.data[op] = Swagger::Blocks::Nodes::OperationNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def parameter(inline_keys = nil, &block) inline_keys = {'$ref' => "#/parameters/#{inline_keys}"} if inline_keys.is_a?(Symbol) self.data[:parameters] ||= [] - self.data[:parameters] << Swagger::Blocks::Nodes::ParameterNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:parameters] << Swagger::Blocks::Nodes::ParameterNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def server(inline_keys = nil, &block) raise NotSupportedError unless is_openapi_3_0? self.data[:servers] ||= [] - self.data[:servers] << Swagger::Blocks::Nodes::ServerNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:servers] << Swagger::Blocks::Nodes::ServerNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/properties_node.rb b/lib/swagger/blocks/nodes/properties_node.rb index 582c6ba..6751aa9 100644 --- a/lib/swagger/blocks/nodes/properties_node.rb +++ b/lib/swagger/blocks/nodes/properties_node.rb @@ -3,7 +3,7 @@ module Blocks module Nodes class PropertiesNode < Node def property(name, inline_keys = nil, &block) - self.data[name] = Swagger::Blocks::Nodes::PropertyNode.call(version: version, inline_keys: inline_keys, &block) + self.data[name] = Swagger::Blocks::Nodes::PropertyNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/property_node.rb b/lib/swagger/blocks/nodes/property_node.rb index f892a89..144e2aa 100644 --- a/lib/swagger/blocks/nodes/property_node.rb +++ b/lib/swagger/blocks/nodes/property_node.rb @@ -3,7 +3,7 @@ module Blocks module Nodes class PropertyNode < Node def items(inline_keys = nil, &block) - self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def property(name, inline_keys = nil, &block) @@ -14,7 +14,7 @@ def property(name, inline_keys = nil, &block) def one_of(&block) self.data[:oneOf] ||= [] - self.data[:oneOf] << Swagger::Blocks::Nodes::OneOfNode.call(version: version, &block) + self.data[:oneOf] << Swagger::Blocks::Nodes::OneOfNode.call(parent: self, version: version, &block) end end end diff --git a/lib/swagger/blocks/nodes/request_body_node.rb b/lib/swagger/blocks/nodes/request_body_node.rb index adf2a88..3d9757f 100644 --- a/lib/swagger/blocks/nodes/request_body_node.rb +++ b/lib/swagger/blocks/nodes/request_body_node.rb @@ -4,7 +4,7 @@ module Nodes class RequestBodyNode < Node def content(type, inline_keys = nil, &block) self.data[:content] ||= {} - self.data[:content][type] = Swagger::Blocks::Nodes::ContentNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:content][type] = Swagger::Blocks::Nodes::ContentNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/response_node.rb b/lib/swagger/blocks/nodes/response_node.rb index bbd8f4d..2f70412 100644 --- a/lib/swagger/blocks/nodes/response_node.rb +++ b/lib/swagger/blocks/nodes/response_node.rb @@ -4,32 +4,32 @@ module Nodes # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#responseObject class ResponseNode < Node def schema(inline_keys = nil, &block) - self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:schema] = Swagger::Blocks::Nodes::SchemaNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def header(head, inline_keys = nil, &block) # TODO validate 'head' is as per spec self.data[:headers] ||= {} - self.data[:headers][head] = Swagger::Blocks::Nodes::HeaderNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:headers][head] = Swagger::Blocks::Nodes::HeaderNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def content(type, inline_keys = nil, &block) self.data[:content] ||= {} - self.data[:content][type] = Swagger::Blocks::Nodes::ContentNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:content][type] = Swagger::Blocks::Nodes::ContentNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def example(name = nil, inline_keys = nil, &block) if name.nil? - self.data[:example] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:example] = Swagger::Blocks::Nodes::ExampleNode.call(parent: self, version: version, inline_keys: inline_keys, &block) else self.data[:examples] ||= {} - self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:examples][name] = Swagger::Blocks::Nodes::ExampleNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end def link(name, inline_keys = nil, &block) self.data[:links] ||= {} - self.data[:links][name] = Swagger::Blocks::Nodes::LinkNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:links][name] = Swagger::Blocks::Nodes::LinkNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/root_node.rb b/lib/swagger/blocks/nodes/root_node.rb index 710c33b..80bbd63 100644 --- a/lib/swagger/blocks/nodes/root_node.rb +++ b/lib/swagger/blocks/nodes/root_node.rb @@ -4,7 +4,7 @@ module Nodes class RootNode < Node def info(inline_keys = nil, &block) - self.data[:info] = Swagger::Blocks::Nodes::InfoNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:info] = Swagger::Blocks::Nodes::InfoNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def parameter(param, inline_keys = nil, &block) @@ -12,7 +12,7 @@ def parameter(param, inline_keys = nil, &block) # TODO validate 'param' is as per spec self.data[:parameters] ||= {} - self.data[:parameters][param] = Swagger::Blocks::Nodes::ParameterNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:parameters][param] = Swagger::Blocks::Nodes::ParameterNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def response(resp, inline_keys = nil, &block) @@ -20,46 +20,46 @@ def response(resp, inline_keys = nil, &block) # TODO validate 'resp' is as per spec self.data[:responses] ||= {} - self.data[:responses][resp] = Swagger::Blocks::Nodes::ResponseNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:responses][resp] = Swagger::Blocks::Nodes::ResponseNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def security_definition(name, inline_keys = nil, &block) raise NotSupportedError unless is_swagger_2_0? self.data[:securityDefinitions] ||= {} - self.data[:securityDefinitions][name] = Swagger::Blocks::Nodes::SecuritySchemeNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:securityDefinitions][name] = Swagger::Blocks::Nodes::SecuritySchemeNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def security(inline_keys = nil, &block) raise NotSupportedError unless is_swagger_2_0? || is_openapi_3_0? self.data[:security] ||= [] - self.data[:security] << Swagger::Blocks::Nodes::SecurityRequirementNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:security] << Swagger::Blocks::Nodes::SecurityRequirementNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def externalDocs(inline_keys = nil, &block) - self.data[:externalDocs] = Swagger::Blocks::Nodes::ExternalDocsNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:externalDocs] = Swagger::Blocks::Nodes::ExternalDocsNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def tag(inline_keys = nil, &block) raise NotSupportedError unless is_swagger_2_0? || is_openapi_3_0? self.data[:tags] ||= [] - self.data[:tags] << Swagger::Blocks::Nodes::TagNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:tags] << Swagger::Blocks::Nodes::TagNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def server(inline_keys = nil, &block) raise NotSupportedError unless is_openapi_3_0? self.data[:servers] ||= [] - self.data[:servers] << Swagger::Blocks::Nodes::ServerNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:servers] << Swagger::Blocks::Nodes::ServerNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def extension(name, inline_keys = nil, &block) raise NotSupportedError unless is_openapi_3_0? self.data[name] ||= [] - self.data[name] << Swagger::Blocks::Nodes::VendorExtensionNode.call(version: version, inline_keys: inline_keys, &block) + self.data[name] << Swagger::Blocks::Nodes::VendorExtensionNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end # Use 'tag' instead. diff --git a/lib/swagger/blocks/nodes/schema_node.rb b/lib/swagger/blocks/nodes/schema_node.rb index 004c185..f6f58c5 100644 --- a/lib/swagger/blocks/nodes/schema_node.rb +++ b/lib/swagger/blocks/nodes/schema_node.rb @@ -4,11 +4,11 @@ module Nodes # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#schema-object class SchemaNode < Node def items(inline_keys = nil, &block) - self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:items] = Swagger::Blocks::Nodes::ItemsNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def allOf(&block) - self.data[:allOf] = Swagger::Blocks::Nodes::AllOfNode.call(version: version, &block) + self.data[:allOf] = Swagger::Blocks::Nodes::AllOfNode.call(parent: self, version: version, &block) end def property(name, inline_keys = nil, &block) @@ -18,20 +18,20 @@ def property(name, inline_keys = nil, &block) end def xml(inline_keys = nil, &block) - self.data[:xml] = Swagger::Blocks::Nodes::XmlNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:xml] = Swagger::Blocks::Nodes::XmlNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def externalDocs(inline_keys = nil, &block) - self.data[:externalDocs] = Swagger::Blocks::Nodes::ExternalDocsNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:externalDocs] = Swagger::Blocks::Nodes::ExternalDocsNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def example(inline_keys = nil, &block) - self.data[:example] = Swagger::Blocks::Nodes::ExampleNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:example] = Swagger::Blocks::Nodes::ExampleNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def one_of(&block) self.data[:oneOf] ||= [] - self.data[:oneOf] << Swagger::Blocks::Nodes::OneOfNode.call(version: version, &block) + self.data[:oneOf] << Swagger::Blocks::Nodes::OneOfNode.call(parent: self, version: version, &block) end end end diff --git a/lib/swagger/blocks/nodes/security_scheme_node.rb b/lib/swagger/blocks/nodes/security_scheme_node.rb index d9345db..4757429 100644 --- a/lib/swagger/blocks/nodes/security_scheme_node.rb +++ b/lib/swagger/blocks/nodes/security_scheme_node.rb @@ -5,12 +5,12 @@ class SecuritySchemeNode < Node # TODO support ^x- Vendor Extensions def scopes(inline_keys = nil, &block) - self.data[:scopes] = Swagger::Blocks::Nodes::ScopesNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:scopes] = Swagger::Blocks::Nodes::ScopesNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end def flow(name, inline_keys = nil, &block) self.data[:flows] ||= {} - self.data[:flows][name] = Swagger::Blocks::Nodes::FlowNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:flows][name] = Swagger::Blocks::Nodes::FlowNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/server_node.rb b/lib/swagger/blocks/nodes/server_node.rb index 5e42d80..9c1e6cc 100644 --- a/lib/swagger/blocks/nodes/server_node.rb +++ b/lib/swagger/blocks/nodes/server_node.rb @@ -4,7 +4,7 @@ module Nodes class ServerNode < Node def variable(name, inline_keys = nil, &block) self.data[:variables] ||= {} - self.data[:variables][name] = Swagger::Blocks::Nodes::VariableNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:variables][name] = Swagger::Blocks::Nodes::VariableNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/lib/swagger/blocks/nodes/tag_node.rb b/lib/swagger/blocks/nodes/tag_node.rb index 2560b0d..961b5af 100644 --- a/lib/swagger/blocks/nodes/tag_node.rb +++ b/lib/swagger/blocks/nodes/tag_node.rb @@ -7,7 +7,7 @@ class TagNode < Node # TODO support ^x- Vendor Extensions def externalDocs(inline_keys = nil, &block) - self.data[:externalDocs] = Swagger::Blocks::Nodes::ExternalDocsNode.call(version: version, inline_keys: inline_keys, &block) + self.data[:externalDocs] = Swagger::Blocks::Nodes::ExternalDocsNode.call(parent: self, version: version, inline_keys: inline_keys, &block) end end end diff --git a/spec/lib/nodes/root_node_spec.rb b/spec/lib/nodes/root_node_spec.rb new file mode 100644 index 0000000..0b4dbfa --- /dev/null +++ b/spec/lib/nodes/root_node_spec.rb @@ -0,0 +1,13 @@ +require 'swagger/blocks' + +describe 'RootNode' do + describe 'build_json' do + it 'creates an info node' do + root_node = Swagger::Blocks::Nodes::RootNode.call(version: '3.0.0') + info_node = root_node.info + + expect(info_node).to be_a(Swagger::Blocks::Nodes::InfoNode) + expect(info_node.parent).to eq(root_node) + end + end +end From 88fd33ef49a906ae53727b639b088aea57306511 Mon Sep 17 00:00:00 2001 From: Jason Numeroff Date: Mon, 14 Nov 2022 15:58:00 -0500 Subject: [PATCH 2/4] Add path reference to path nodes --- lib/swagger/blocks/class_methods.rb | 2 +- lib/swagger/blocks/node.rb | 2 +- lib/swagger/blocks/nodes/path_node.rb | 8 ++++++++ spec/lib/class_methods_spec.rb | 17 +++++++++++++++++ spec/lib/nodes/path_node_spec.rb | 14 ++++++++++++++ 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 spec/lib/class_methods_spec.rb create mode 100644 spec/lib/nodes/path_node_spec.rb diff --git a/lib/swagger/blocks/class_methods.rb b/lib/swagger/blocks/class_methods.rb index 3906b13..b89a414 100644 --- a/lib/swagger/blocks/class_methods.rb +++ b/lib/swagger/blocks/class_methods.rb @@ -33,7 +33,7 @@ def swagger_path(path, &block) path_node.instance_eval(&block) else # First time we've seen this path - @swagger_path_node_map[path] = Swagger::Blocks::Nodes::PathNode.call(version: version, &block) + @swagger_path_node_map[path] = Swagger::Blocks::Nodes::PathNode.call(version: version, path: path.to_s, &block) end end diff --git a/lib/swagger/blocks/node.rb b/lib/swagger/blocks/node.rb index 4271f9c..9246167 100644 --- a/lib/swagger/blocks/node.rb +++ b/lib/swagger/blocks/node.rb @@ -7,7 +7,7 @@ class Node VERSION_2 = '2.0' VERSION_3 = '3.0.0' - def self.call(parent: nil, name: nil, version: nil, inline_keys: nil, &block) + def self.call(parent: nil, name: nil, version: nil, inline_keys: nil, **internal_data, &block) # Create a new instance and evaluate the block into it. instance = new instance.parent, instance.name, instance.version = parent, name, version diff --git a/lib/swagger/blocks/nodes/path_node.rb b/lib/swagger/blocks/nodes/path_node.rb index 6c3f00a..47eadf7 100644 --- a/lib/swagger/blocks/nodes/path_node.rb +++ b/lib/swagger/blocks/nodes/path_node.rb @@ -5,6 +5,14 @@ module Nodes class PathNode < Node OPERATION_TYPES = [:get, :put, :post, :delete, :options, :head, :patch].freeze + attr_accessor :path + + def self.call(parent: nil, name: nil, version: nil, inline_keys: nil, **internal_data, &block) + instance = super + instance.path = internal_data[:path] + instance + end + # TODO support ^x- Vendor Extensions def operation(op, inline_keys = nil, &block) op = op.to_sym diff --git a/spec/lib/class_methods_spec.rb b/spec/lib/class_methods_spec.rb new file mode 100644 index 0000000..45c80d1 --- /dev/null +++ b/spec/lib/class_methods_spec.rb @@ -0,0 +1,17 @@ +require 'swagger/blocks' + +class PetController + include Swagger::Blocks + + swagger_path '/pets' +end + +describe 'ClassMethods' do + describe 'swagger_path' do + it 'creates a path node' do + path_map = PetController.instance_variable_get(:@swagger_path_node_map) + path_node = path_map[:'/pets'] + expect(path_node.path).to eq('/pets') + end + end +end diff --git a/spec/lib/nodes/path_node_spec.rb b/spec/lib/nodes/path_node_spec.rb new file mode 100644 index 0000000..fced5d3 --- /dev/null +++ b/spec/lib/nodes/path_node_spec.rb @@ -0,0 +1,14 @@ +require 'swagger/blocks' + +describe 'PathNode' do + describe 'call' do + it 'sets the path' do + version, path = '3.0.0', '/pets' + path_node = Swagger::Blocks::Nodes::PathNode.call(version: version, path: path) + + expect(path_node).to be_a(Swagger::Blocks::Nodes::PathNode) + expect(path_node.path).to eq(path) + expect(path_node.version).to eq(version) + end + end +end From 3ce0d5da040ef5746a141a66e55550848c08eb70 Mon Sep 17 00:00:00 2001 From: Jason Numeroff Date: Mon, 14 Nov 2022 16:04:19 -0500 Subject: [PATCH 3/4] Add operation reference to operation nodes --- lib/swagger/blocks/nodes/operation_node.rb | 8 ++++++++ lib/swagger/blocks/nodes/path_node.rb | 2 +- spec/lib/nodes/operation_node_spec.rb | 14 ++++++++++++++ spec/lib/nodes/path_node_spec.rb | 10 ++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 spec/lib/nodes/operation_node_spec.rb diff --git a/lib/swagger/blocks/nodes/operation_node.rb b/lib/swagger/blocks/nodes/operation_node.rb index 4b62466..0fcba8b 100644 --- a/lib/swagger/blocks/nodes/operation_node.rb +++ b/lib/swagger/blocks/nodes/operation_node.rb @@ -3,6 +3,14 @@ module Blocks module Nodes # v2.0: https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#operation-object class OperationNode < Node + attr_accessor :operation + + def self.call(parent: nil, name: nil, version: nil, inline_keys: nil, **internal_data, &block) + instance = super + instance.operation = internal_data[:operation] + instance + end + def parameter(inline_keys = nil, &block) inline_keys = {'$ref' => "#/parameters/#{inline_keys}"} if inline_keys.is_a?(Symbol) diff --git a/lib/swagger/blocks/nodes/path_node.rb b/lib/swagger/blocks/nodes/path_node.rb index 47eadf7..ed486da 100644 --- a/lib/swagger/blocks/nodes/path_node.rb +++ b/lib/swagger/blocks/nodes/path_node.rb @@ -17,7 +17,7 @@ def self.call(parent: nil, name: nil, version: nil, inline_keys: nil, **internal def operation(op, inline_keys = nil, &block) op = op.to_sym raise ArgumentError.new("#{name} not in #{OPERATION_TYPES}") if !OPERATION_TYPES.include?(op) - self.data[op] = Swagger::Blocks::Nodes::OperationNode.call(parent: self, version: version, inline_keys: inline_keys, &block) + self.data[op] = Swagger::Blocks::Nodes::OperationNode.call(parent: self, version: version, inline_keys: inline_keys, operation: op, &block) end def parameter(inline_keys = nil, &block) diff --git a/spec/lib/nodes/operation_node_spec.rb b/spec/lib/nodes/operation_node_spec.rb new file mode 100644 index 0000000..ee2eec6 --- /dev/null +++ b/spec/lib/nodes/operation_node_spec.rb @@ -0,0 +1,14 @@ +require 'swagger/blocks' + +describe 'OperationNode' do + describe 'call' do + it 'sets the operation' do + version, operation = '3.0.0', :get + operation_node = Swagger::Blocks::Nodes::OperationNode.call(version: version, operation: operation) + + expect(operation_node).to be_a(Swagger::Blocks::Nodes::OperationNode) + expect(operation_node.operation).to eq(operation) + expect(operation_node.version).to eq(version) + end + end +end diff --git a/spec/lib/nodes/path_node_spec.rb b/spec/lib/nodes/path_node_spec.rb index fced5d3..088239f 100644 --- a/spec/lib/nodes/path_node_spec.rb +++ b/spec/lib/nodes/path_node_spec.rb @@ -11,4 +11,14 @@ expect(path_node.version).to eq(version) end end + describe 'operation' do + it 'creates an operation node' do + path_node = Swagger::Blocks::Nodes::PathNode.call(version: '3.0.0') + operation = :get + operation_node = path_node.operation(operation) + + expect(operation_node).to be_a(Swagger::Blocks::Nodes::OperationNode) + expect(operation_node.operation).to eq(operation) + end + end end From 934d24b40688c64bbd4ace05ff786b78bab960e6 Mon Sep 17 00:00:00 2001 From: Jason Numeroff Date: Mon, 14 Nov 2022 16:14:02 -0500 Subject: [PATCH 4/4] Update documentation for referencing parent nodes and internal data --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index f28f30c..110b5f4 100644 --- a/README.md +++ b/README.md @@ -452,6 +452,32 @@ operation :post do end ``` +Additionally, many APIs have standard responses based on the path or operation. You can retrieve references to these in order to DRY up code. + +```ruby +module SwaggerResponses + module PostResponses + def self.extended(base) + operation = base.operation + path = base.parent.path + + return unless operation == :post + base.response 201 do + key :description, dynamic_description_based_on_path + schema do + key :'$ref', dynamic_ref_name_based_on_path + end + end + end + end +end + +operation :post do + extend SwaggerResponses::PostResponses + # ... +end +``` + ## Reference See the [swagger_v2_blocks_spec.rb](https://github.com/fotinakis/swagger-blocks/blob/master/spec/lib/swagger_v2_blocks_spec.rb) for examples of more complex features and declarations possible.