Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc #25

Merged
merged 7 commits into from
May 1, 2018
Merged

Misc #25

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ This format is still supported indirectly, by converting from a Google API docum
class MyModel < Scorpio::ResourceBase
rest_description_doc = YAML.load_file('path/to/doc.yml')
rest_description = Scorpio::Google::RestDescription.new(rest_description_doc)
set_openapi_document(rest_description.to_openapi_document)
self.openapi_document = rest_description.to_openapi_document

# ... the remainder of your setup and model code here
end
Expand Down
1 change: 1 addition & 0 deletions lib/scorpio.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class NetworkAuthenticationRequired511Error < ServerError; status(511); end
autoload :OpenAPI, 'scorpio/openapi'
autoload :Google, 'scorpio/google_api_document'
autoload :JSON, 'scorpio/json'
autoload :SchemaObjectBase, 'scorpio/schema_object_base'
autoload :Schema, 'scorpio/schema'
autoload :Typelike, 'scorpio/typelike_modules'
autoload :Hashlike, 'scorpio/typelike_modules'
Expand Down
19 changes: 16 additions & 3 deletions lib/scorpio/resource_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ def define_inheritable_accessor(accessor, options = {})
# (except in the unlikely event it is overwritten by a subclass)
define_inheritable_accessor(:openapi_document_class)
# the openapi document
define_inheritable_accessor(:openapi_document, on_set: proc { self.openapi_document_class = self })
define_inheritable_accessor(:tag_name, update_methods: true)
define_inheritable_accessor(:definition_keys, default_value: [], update_methods: true, on_set: proc do
definition_keys.each do |key|
Expand Down Expand Up @@ -89,10 +88,24 @@ def define_inheritable_accessor(accessor, options = {})
define_inheritable_accessor(:faraday_adapter, default_getter: proc { Faraday.default_adapter })
define_inheritable_accessor(:faraday_response_middleware, default_value: [])
class << self
def set_openapi_document(openapi_document)
def openapi_document
nil
end

def openapi_document=(openapi_document)
self.openapi_document_class = self

if openapi_document.is_a?(Hash)
openapi_document = OpenAPI::V2::Document.new(openapi_document)
end

begin
singleton_class.instance_exec { remove_method(:openapi_document) }
rescue NameError
end
define_singleton_method(:openapi_document) { openapi_document }
update_dynamic_methods

openapi_document.paths.each do |path, path_item|
path_item.each do |http_method, operation|
next if http_method == 'parameters' # parameters is not an operation. TOOD maybe just select the keys that are http methods?
Expand All @@ -108,7 +121,6 @@ def set_openapi_document(openapi_document)
self.schemas_by_path = {}
self.schemas_by_key = {}
self.schemas_by_id = {}
self.openapi_document = openapi_document
(openapi_document.definitions || {}).each do |schema_key, schema|
if schema['id']
# this isn't actually allowed by openapi's definition. whatever.
Expand All @@ -117,6 +129,7 @@ def set_openapi_document(openapi_document)
self.schemas_by_path = self.schemas_by_path.merge(schema.object.fragment => schema)
self.schemas_by_key = self.schemas_by_key.merge(schema_key => schema)
end

update_dynamic_methods
end

Expand Down
60 changes: 31 additions & 29 deletions lib/scorpio/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,6 @@ def initialize(schema_node)
end
attr_reader :schema_node

def subschema_for_property(property_name)
if schema_node['properties'].respond_to?(:to_hash) && schema_node['properties'][property_name].respond_to?(:to_hash)
self.class.new(schema_node['properties'][property_name].deref)
else
if schema_node['patternProperties'].respond_to?(:to_hash)
_, pattern_schema_node = schema_node['patternProperties'].detect do |pattern, _|
property_name =~ Regexp.new(pattern) # TODO map pattern to ruby syntax
end
end
if pattern_schema_node
self.class.new(pattern_schema_node.deref)
else
if schema_node['additionalProperties'].is_a?(Scorpio::JSON::Node)
self.class.new(schema_node['additionalProperties'].deref)
else
nil
end
end
end
end

def id
@id ||= begin
# start from schema_node and ascend parents looking for an 'id' property.
Expand All @@ -39,14 +18,16 @@ def id
# TODO: track what parents are schemas. somehow.
# look at 'id' if node_for_id is a schema, or the document root.
# decide whether to look at '$id' for all parent nodes or also just schemas.
if node_for_id.path.empty? || node_for_id.object_id == schema_node.object_id
# I'm only looking at 'id' for the document root and the schema node
# until I track what parents are schemas.
parent_id = node_for_id['$id'] || node_for_id['id']
else
# will look at '$id' everywhere since it is less likely to show up outside schemas than
# 'id', but it will be better to only look at parents that are schemas for this too.
parent_id = node_for_id['$id']
if node_for_id.respond_to?(:to_hash)
if node_for_id.path.empty? || node_for_id.object_id == schema_node.object_id
# I'm only looking at 'id' for the document root and the schema node
# until I track what parents are schemas.
parent_id = node_for_id['$id'] || node_for_id['id']
else
# will look at '$id' everywhere since it is less likely to show up outside schemas than
# 'id', but it will be better to only look at parents that are schemas for this too.
parent_id = node_for_id['$id']
end
end

if parent_id || node_for_id.path.empty?
Expand Down Expand Up @@ -97,6 +78,27 @@ def match_to_object(object)
return self
end

def subschema_for_property(property_name)
if schema_node['properties'].respond_to?(:to_hash) && schema_node['properties'][property_name].respond_to?(:to_hash)
self.class.new(schema_node['properties'][property_name].deref)
else
if schema_node['patternProperties'].respond_to?(:to_hash)
_, pattern_schema_node = schema_node['patternProperties'].detect do |pattern, _|
property_name.to_s =~ Regexp.new(pattern) # TODO map pattern to ruby syntax
end
end
if pattern_schema_node
self.class.new(pattern_schema_node.deref)
else
if schema_node['additionalProperties'].is_a?(Scorpio::JSON::Node)
self.class.new(schema_node['additionalProperties'].deref)
else
nil
end
end
end
end

def subschema_for_index(index)
if schema_node['items'].is_a?(Scorpio::JSON::ArrayNode)
if index < schema_node['items'].size
Expand Down
4 changes: 4 additions & 0 deletions lib/scorpio/schema_object_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ def initialize(object)

attr_reader :object

def deref
self.class.new(object.deref)
end

def modified_copy(&block)
modified_object = object.modified_copy(&block)
self.class.new(modified_object)
Expand Down
2 changes: 1 addition & 1 deletion test/blog_scorpio_models.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# it describes the API by setting the API document, but this class itself represents no
# resources - it sets no resource_name and defines no schema_keys.
class BlogModel < Scorpio::ResourceBase
set_openapi_document(YAML.load_file('test/blog.openapi.yml'))
self.openapi_document = YAML.load_file('test/blog.openapi.yml')
self.base_url = File.join('https://blog.example.com/', openapi_document.basePath)
self.faraday_request_middleware = [[:api_hammer_request_logger, Blog.logger]]
self.faraday_adapter = [:rack, Blog.new]
Expand Down
2 changes: 1 addition & 1 deletion test/scorpio_json_hashnode_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
end
it 'iterates, two arguments' do
out = []
retval = node.each do |k, v|
node.each do |k, v|
out << [k, v]
end
assert_instance_of(Scorpio::JSON::HashNode, node['c'])
Expand Down