Skip to content

Commit

Permalink
Merge 09d312c into 6b8d9cb
Browse files Browse the repository at this point in the history
  • Loading branch information
notEthan committed Nov 24, 2020
2 parents 6b8d9cb + 09d312c commit 7cc6451
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 9 deletions.
8 changes: 7 additions & 1 deletion lib/jsi/base.rb
Expand Up @@ -174,7 +174,11 @@ def initialize(instance,
end

jsi_schemas.each do |schema|
if schema.describes_schema?
# if this JSI is a schema - i.e. if it is described by a (meta)schema which indicates it describes
# schemas - and the class doesn't already include JSI::Schema, extend self with JSI::Schema.
# this may be the case when a jsi schema module includes JSI::Schema::DescribesSchema without
# setting jsi_schema_instance_modules to include JSI::Schema
if !is_a?(JSI::Schema) && schema.describes_schema?
extend JSI::Schema
end
end
Expand Down Expand Up @@ -433,6 +437,8 @@ def jsi_fingerprint
class: jsi_class,
jsi_document: jsi_document,
jsi_ptr: jsi_ptr,
# only defined for JSI::Schema instances:
jsi_schema_instance_modules: is_a?(Schema) ? jsi_schema_instance_modules : nil,
}
end
include Util::FingerprintHash
Expand Down
17 changes: 15 additions & 2 deletions lib/jsi/metaschema_node.rb
Expand Up @@ -32,16 +32,21 @@ class MetaschemaNode

# @param jsi_document the document containing the metaschema
# @param jsi_ptr [JSI::JSON::Pointer] ptr to this MetaschemaNode in jsi_document
# @param metaschema_instance_modules [Set<Module>] modules which implement the functionality of the
# schema, to be applied to every schema instance of the metaschema. this must include JSI::Schema
# directly or indirectly.
# @param metaschema_root_ptr [JSI::JSON::Pointer] ptr to the root of the metaschema in the jsi_document
# @param root_schema_ptr [JSI::JSON::Pointer] ptr to the schema describing the root of the jsi_document
def initialize(
jsi_document,
jsi_ptr: JSI::JSON::Pointer[],
metaschema_instance_modules: ,
metaschema_root_ptr: JSI::JSON::Pointer[],
root_schema_ptr: JSI::JSON::Pointer[]
)
@jsi_document = jsi_document
@jsi_ptr = jsi_ptr
@metaschema_instance_modules = metaschema_instance_modules
@metaschema_root_ptr = metaschema_root_ptr
@root_schema_ptr = root_schema_ptr

Expand Down Expand Up @@ -73,10 +78,13 @@ def initialize(

schema_ptrs.each do |schema_ptr|
if schema_ptr == metaschema_root_ptr
extend JSI::Schema
metaschema_instance_modules.each do |metaschema_instance_module|
extend metaschema_instance_module
end
end
if schema_ptr == jsi_ptr
extend Metaschema
self.jsi_schema_instance_modules = metaschema_instance_modules
end
end

Expand All @@ -101,7 +109,7 @@ def initialize(
addtlItemsanyOf = metaschema_root_ptr["properties"]["additionalItems"]["anyOf"]

if !jsi_ptr.root? && [addtlPropsanyOf, addtlItemsanyOf].include?(jsi_ptr.parent)
extend JSI::Schema::DescribesSchema
self.jsi_schema_instance_modules = metaschema_instance_modules
end
end
end
Expand All @@ -110,6 +118,10 @@ def initialize(
attr_reader :jsi_document
# ptr to this metaschema node. see PathedNode#jsi_ptr.
attr_reader :jsi_ptr

# Set of modules to apply to schemas which are instances of (described by) the metaschema
attr_reader :metaschema_instance_modules

# ptr to the root of the metaschema in the jsi_document
attr_reader :metaschema_root_ptr
# ptr to the schema of the root of the jsi_document
Expand Down Expand Up @@ -219,6 +231,7 @@ def jsi_fingerprint
def our_initialize_params
{
jsi_ptr: jsi_ptr,
metaschema_instance_modules: metaschema_instance_modules,
metaschema_root_ptr: metaschema_root_ptr,
root_schema_ptr: root_schema_ptr,
}
Expand Down
20 changes: 17 additions & 3 deletions lib/jsi/schema.rb
Expand Up @@ -50,8 +50,8 @@ def supported_metaschemas
# will be the {JSI::Schema.default_metaschema}.
#
# if the given schema_object is a JSI::Base but not already a JSI::Schema, an error
# will be raised. JSI::Base _should_ already extend a given instance with JSI::Schema
# when its schema describes a schema (by extending with JSI::Schema::DescribesSchema).
# will be raised. schemas which describe schemas must have JSI::Schema in their
# Schema#jsi_schema_instance_modules.
#
# @param schema_object [#to_hash, Boolean, JSI::Schema] an object to be instantiated as a schema.
# if it's already a schema, it is returned as-is.
Expand Down Expand Up @@ -162,7 +162,21 @@ def new_jsi(instance, *a, &b)

# @return [Boolean] does this schema itself describe a schema?
def describes_schema?
is_a?(JSI::Schema::DescribesSchema)
jsi_schema_instance_modules.any? { |m| m <= JSI::Schema } || is_a?(DescribesSchema)
end

# @return [Set<Module>] modules to apply to instances described by this schema. these modules are included
# on this schema's {#jsi_schema_module}
def jsi_schema_instance_modules
return @jsi_schema_instance_modules if instance_variable_defined?(:@jsi_schema_instance_modules)
return Set[]
end

# @return [void]
def jsi_schema_instance_modules=(jsi_schema_instance_modules)
raise(TypeError) unless jsi_schema_instance_modules.is_a?(Set)
raise(TypeError) unless jsi_schema_instance_modules.all? { |m| m.is_a?(Module) }
@jsi_schema_instance_modules = jsi_schema_instance_modules
end

# @return [JSI::Base] resource containing this schema
Expand Down
7 changes: 6 additions & 1 deletion lib/jsi/schema_classes.rb
Expand Up @@ -73,8 +73,13 @@ def module_for_schema(schema_object)

extend SchemaModule

schema.jsi_schema_instance_modules.each do |mod|
include(mod)
end

include JSI::SchemaClasses.accessor_module_for_schema(schema,
conflicting_modules: Set[JSI::Base, JSI::PathedArrayNode, JSI::PathedHashNode],
conflicting_modules: Set[JSI::Base, JSI::PathedArrayNode, JSI::PathedHashNode] +
schema.jsi_schema_instance_modules,
)

if schema.describes_schema?
Expand Down
4 changes: 3 additions & 1 deletion lib/schemas/json-schema.org/draft-04/schema.rb
Expand Up @@ -3,5 +3,7 @@
module JSI
schema_id = 'http://json-schema.org/draft-04/schema'
schema_content = ::JSON.parse(File.read(::JSON::Validator.validators[schema_id].metaschema))
JSONSchemaOrgDraft04 = MetaschemaNode.new(schema_content).jsi_schema_module
JSONSchemaOrgDraft04 = MetaschemaNode.new(schema_content,
metaschema_instance_modules: Set[JSI::Schema],
).jsi_schema_module
end
4 changes: 3 additions & 1 deletion lib/schemas/json-schema.org/draft-06/schema.rb
Expand Up @@ -3,5 +3,7 @@
module JSI
schema_id = 'http://json-schema.org/draft/schema' # I don't know why this is not http://json-schema.org/draft-06/schema
schema_content = ::JSON.parse(File.read(::JSON::Validator.validators[schema_id].metaschema))
JSONSchemaOrgDraft06 = MetaschemaNode.new(schema_content).jsi_schema_module
JSONSchemaOrgDraft06 = MetaschemaNode.new(schema_content,
metaschema_instance_modules: Set[JSI::Schema],
).jsi_schema_module
end
4 changes: 4 additions & 0 deletions test/metaschema_node_test.rb
@@ -1,8 +1,12 @@
require_relative 'test_helper'

describe JSI::MetaschemaNode do
let(:metaschema_instance_modules) do
Set[JSI::Schema]
end
let(:root_node) do
JSI::MetaschemaNode.new(jsi_document,
metaschema_instance_modules: metaschema_instance_modules,
metaschema_root_ptr: metaschema_root_ptr,
root_schema_ptr: root_schema_ptr,
)
Expand Down

0 comments on commit 7cc6451

Please sign in to comment.