Skip to content

Commit

Permalink
new_schema, new_schema_module pass block to Schema#jsi_schema_module_…
Browse files Browse the repository at this point in the history
…exec
  • Loading branch information
notEthan committed Oct 10, 2023
1 parent 34345dc commit 08d2757
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 12 deletions.
4 changes: 2 additions & 2 deletions lib/jsi.rb
Expand Up @@ -52,8 +52,8 @@ class Bug < NotImplementedError
# {JSI.new_schema}, and returns its {Schema#jsi_schema_module JSI Schema Module}.
#
# @return (see JSI::Schema::DescribesSchema#new_schema_module)
def self.new_schema_module(schema_content, **kw)
new_schema(schema_content, **kw).jsi_schema_module
def self.new_schema_module(schema_content, **kw, &block)
new_schema(schema_content, **kw, &block).jsi_schema_module
end

# Instantiates the given document as a JSI Metaschema.
Expand Down
20 changes: 14 additions & 6 deletions lib/jsi/schema.rb
Expand Up @@ -166,26 +166,32 @@ module DescribesSchema
# @param stringify_symbol_keys [Boolean] Whether the schema content will have any Symbol keys of Hashes
# replaced with Strings (recursively through the document).
# Replacement is done on a copy; the given schema content is not modified.
# @yield If a block is given, it is evaluated in the context of the schema's JSI schema module
# using [Module#module_exec](https://ruby-doc.org/core/Module.html#method-i-module_exec).
# @return [JSI::Base subclass + JSI::Schema] a JSI which is a {JSI::Schema} whose content comes from
# the given `schema_content` and whose schemas are this schema's inplace applicators.
def new_schema(schema_content,
uri: nil,
stringify_symbol_keys: true
stringify_symbol_keys: true,
&block
)
schema_jsi = new_jsi(schema_content,
uri: uri,
stringify_symbol_keys: stringify_symbol_keys,
)
JSI.schema_registry.register(schema_jsi)
if block
schema_jsi.jsi_schema_module_exec(&block)
end
schema_jsi
end

# Instantiates the given schema content as a JSI Schema, passing all params to
# {Schema::DescribesSchema#new_schema}, and returns its {Schema#jsi_schema_module JSI Schema Module}.
#
# @return [Module + JSI::SchemaModule] the JSI Schema Module of the instantiated schema
def new_schema_module(schema_content, **kw)
new_schema(schema_content, **kw).jsi_schema_module
def new_schema_module(schema_content, **kw, &block)
new_schema(schema_content, **kw, &block).jsi_schema_module
end
end

Expand Down Expand Up @@ -262,14 +268,16 @@ def default_metaschema=(default_metaschema)
# or a URI (as would be in a `$schema` keyword).
# @param uri (see Schema::DescribesSchema#new_schema)
# @param stringify_symbol_keys (see Schema::DescribesSchema#new_schema)
# @yield (see Schema::DescribesSchema#new_schema)
# @return [JSI::Base subclass + JSI::Schema] a JSI which is a {JSI::Schema} whose content comes from
# the given `schema_content` and whose schemas are inplace applicators of the indicated metaschema
def new_schema(schema_content,
default_metaschema: nil,
# params of DescribesSchema#new_schema have their default values repeated here. delegating in a splat
# would remove repetition, but yard doesn't display delegated defaults with its (see X) directive.
uri: nil,
stringify_symbol_keys: true
stringify_symbol_keys: true,
&block
)
new_schema_params = {
uri: uri,
Expand All @@ -292,7 +300,7 @@ def new_schema(schema_content,
"instantiating schema_content: #{schema_content.pretty_inspect.chomp}",
].join("\n"))
end
default_metaschema.new_schema(schema_content, **new_schema_params)
default_metaschema.new_schema(schema_content, **new_schema_params, &block)
}
if schema_content.is_a?(Schema)
raise(TypeError, [
Expand All @@ -311,7 +319,7 @@ def new_schema(schema_content,
raise(ArgumentError, "given schema_content keyword `$schema` is not a string")
end
metaschema = Schema.ensure_describes_schema(id, name: '$schema')
metaschema.new_schema(schema_content, **new_schema_params)
metaschema.new_schema(schema_content, **new_schema_params, &block)
else
default_metaschema_new_schema.call
end
Expand Down
9 changes: 5 additions & 4 deletions lib/jsi/schema_classes.rb
Expand Up @@ -65,15 +65,16 @@ module SchemaModule::DescribesSchemaModule
# see {JSI::Schema::DescribesSchema#new_schema}
#
# @param (see JSI::Schema::DescribesSchema#new_schema)
# @yield (see JSI::Schema::DescribesSchema#new_schema)
# @return [JSI::Base subclass + JSI::Schema] a JSI which is a {JSI::Schema} whose content comes from
# the given `schema_content` and whose schemas are inplace applicators of this module's schema
def new_schema(schema_content, **kw)
schema.new_schema(schema_content, **kw)
def new_schema(schema_content, **kw, &block)
schema.new_schema(schema_content, **kw, &block)
end

# (see Schema::DescribesSchema#new_schema_module)
def new_schema_module(schema_content, **kw)
schema.new_schema(schema_content, **kw).jsi_schema_module
def new_schema_module(schema_content, **kw, &block)
schema.new_schema(schema_content, **kw, &block).jsi_schema_module
end

# @return [Set<Module>]
Expand Down
11 changes: 11 additions & 0 deletions test/schema_test.rb
Expand Up @@ -7,6 +7,17 @@
assert_equal({'type' => 'object'}, schema.jsi_instance)
end

it 'initializes with a block' do
schema1 = JSI.new_schema({'$id' => 'tag:gxif'}, default_metaschema: JSI::JSONSchemaOrgDraft07) do
define_method(:foo) { :foo }
end
schema2 = JSI::JSONSchemaOrgDraft07.new_schema({'$id' => 'tag:ijpa'}) do
define_method(:foo) { :foo }
end
assert_equal(:foo, schema1.new_jsi([]).foo)
assert_equal(:foo, schema2.new_jsi([]).foo)
end

it 'cannot instantiate from a non-string $schema' do
err = assert_raises(ArgumentError) { JSI.new_schema({'$schema' => Object.new}) }
assert_equal("given schema_content keyword `$schema` is not a string", err.message)
Expand Down

0 comments on commit 08d2757

Please sign in to comment.