Skip to content

Commit

Permalink
Add named regexp resolvers
Browse files Browse the repository at this point in the history
`ecma` maintains the current behavior of rewriting Ruby's `\A` and `\z`
anchors.
`ruby` uses Ruby's `Regexp` directly.

In the future, I think it may make sense to switch the default to `ruby`
since it's the least surprising behavior. That way people could opt in
to expression rewrites and the rewrites could be more aggressive.
  • Loading branch information
davishmcclurg committed Oct 27, 2022
1 parent 0de8f1e commit 890b549
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ JSONSchemer.schema(
ref_resolver: 'net/http',

# use different method to match regexes
# Proc/lambda/respond_to?(:call)
# 'ecma'/'ruby'/proc/lambda/respond_to?(:call)
# default: 'ecma'
regexp_resolver: proc do |pattern|
RE2::Regexp.new(pattern)
end
Expand Down
13 changes: 10 additions & 3 deletions lib/json_schemer/schema/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def merge(
:eol => '\z'
}.freeze

DEFAULT_REGEXP_RESOLVER = proc do |pattern|
ECMA_262_REGEXP_RESOLVER = proc do |pattern|
Regexp.new(
Regexp::Scanner.scan(pattern).map do |type, token, text|
type == :anchor ? RUBY_REGEX_ANCHORS_TO_ECMA_262.fetch(token, text) : text
Expand All @@ -53,7 +53,7 @@ def initialize(
formats: nil,
keywords: nil,
ref_resolver: DEFAULT_REF_RESOLVER,
regexp_resolver: CachedResolver.new(&DEFAULT_REGEXP_RESOLVER)
regexp_resolver: 'ecma'
)
raise InvalidSymbolKey, 'schemas must use string keys' if schema.is_a?(Hash) && !schema.empty? && !schema.first.first.is_a?(String)
@root = schema
Expand All @@ -64,7 +64,14 @@ def initialize(
@formats = formats
@keywords = keywords
@ref_resolver = ref_resolver == 'net/http' ? CachedResolver.new(&NET_HTTP_REF_RESOLVER) : ref_resolver
@regexp_resolver = regexp_resolver
@regexp_resolver = case regexp_resolver
when 'ecma'
CachedResolver.new(&ECMA_262_REGEXP_RESOLVER)
when 'ruby'
CachedResolver.new(&Regexp.method(:new))
else
regexp_resolver
end
end

def valid?(data)
Expand Down
12 changes: 12 additions & 0 deletions test/json_schemer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,18 @@ def initialize(*args)
assert_equal(1, new_regexp_class.counts)
end

def test_it_allows_named_regexp_resolvers
schema = JSONSchemer.schema({ 'pattern' => '^test$' })
assert(schema.valid?("test"))
refute(schema.valid?("\ntest\n"))
schema = JSONSchemer.schema({ 'pattern' => '^test$' }, :regexp_resolver => 'ecma')
assert(schema.valid?("test"))
refute(schema.valid?("\ntest\n"))
schema = JSONSchemer.schema({ 'pattern' => '^test$' }, :regexp_resolver => 'ruby')
assert(schema.valid?("test"))
assert(schema.valid?("\ntest\n"))
end

def test_it_raises_for_invalid_regexp_resolution
schema = JSONSchemer.schema(
{ 'pattern' => 'whatever' },
Expand Down

0 comments on commit 890b549

Please sign in to comment.