summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Allen <dan.j.allen@gmail.com>2018-03-24 01:28:47 -0600
committerGitHub <noreply@github.com>2018-03-24 01:28:47 -0600
commitc5122e926f185645ffb153a40fcc0900166704da (patch)
tree04d3122d3106b9caa642e1f6ca9400d417725e54
parentbd1c5288dcb6ed2bea61ddbdd3142e470b77fec6 (diff)
resolves #2622 raise clearer exception when extension class cannot be resolved (PR #2623)
- split impl of class_for_name by Ruby version - add tests to verify correct error message is thrown when passed an illegal constant name - add tests to verify top-level class is not resolved when namespaced class is requested
-rw-r--r--lib/asciidoctor/extensions.rb35
-rw-r--r--test/extensions_test.rb42
2 files changed, 68 insertions, 9 deletions
diff --git a/lib/asciidoctor/extensions.rb b/lib/asciidoctor/extensions.rb
index 4e9b34d8..acb8988e 100644
--- a/lib/asciidoctor/extensions.rb
+++ b/lib/asciidoctor/extensions.rb
@@ -1481,17 +1481,36 @@ module Extensions
# Public: Resolves the Class object for the qualified name.
#
# Returns Class
- def class_for_name qualified_name
- resolved = ::Object
- (qualified_name.split '::').each do |name|
- unless name.empty? || ((resolved.const_defined? name) && ::Module === (resolved = resolved.const_get name))
- raise ::NameError, %(Could not resolve class for name: #{qualified_name})
+ if RUBY_MIN_VERSION_2
+ def class_for_name qualified_name
+ resolved = ::Object.const_get qualified_name, false
+ raise unless ::Class === resolved
+ resolved
+ rescue
+ raise ::NameError, %(Could not resolve class for name: #{qualified_name})
+ end
+ elsif RUBY_MIN_VERSION_1_9
+ def class_for_name qualified_name
+ resolved = (qualified_name.split '::').reduce ::Object do |current, name|
+ name.empty? ? current : (current.const_get name, false)
+ end
+ raise unless ::Class === resolved
+ resolved
+ rescue
+ raise ::NameError, %(Could not resolve class for name: #{qualified_name})
+ end
+ else
+ def class_for_name qualified_name
+ resolved = (qualified_name.split '::').reduce ::Object do |current, name|
+ # NOTE on Ruby 1.8, const_defined? only checks for constant in current scope
+ name.empty? ? current : ((current.const_defined? name) ? (current.const_get name) : raise)
end
+ raise unless ::Class === resolved
+ resolved
+ rescue
+ raise ::NameError, %(Could not resolve class for name: #{qualified_name})
end
- raise ::NameError, %(Could not resolve class for name: #{qualified_name}) unless ::Class === resolved
- resolved
end
end
-
end
end
diff --git a/test/extensions_test.rb b/test/extensions_test.rb
index b4f3d51e..c2d3ea6a 100644
--- a/test/extensions_test.rb
+++ b/test/extensions_test.rb
@@ -340,6 +340,24 @@ context 'Extensions' do
end
end
+ test 'should raise exception if constant name is invalid' do
+ begin
+ Asciidoctor::Extensions.class_for_name 'foobar'
+ flunk 'Expecting RuntimeError to be raised'
+ rescue NameError => e
+ assert_equal 'Could not resolve class for name: foobar', e.message
+ end
+ end
+
+ test 'should raise exception if class not found in scope' do
+ begin
+ Asciidoctor::Extensions.class_for_name 'Asciidoctor::Extensions::String'
+ flunk 'Expecting RuntimeError to be raised'
+ rescue NameError => e
+ assert_equal 'Could not resolve class for name: Asciidoctor::Extensions::String', e.message
+ end
+ end
+
test 'should raise exception if name resolves to module' do
begin
Asciidoctor::Extensions.class_for_name 'Asciidoctor::Extensions'
@@ -361,6 +379,29 @@ context 'Extensions' do
assert_equal Asciidoctor::Document, clazz
end
+ test 'should not resolve class if not in scope' do
+ begin
+ Asciidoctor::Extensions.resolve_class 'Asciidoctor::Extensions::String'
+ flunk 'Expecting RuntimeError to be raised'
+ rescue NameError => e
+ assert_equal 'Could not resolve class for name: Asciidoctor::Extensions::String', e.message
+ end
+ end
+
+ test 'should raise NameError if extension class cannot be resolved from string' do
+ begin
+ Asciidoctor::Extensions.register do
+ block 'foobar'
+ end
+ doc = empty_document
+ flunk 'Expecting RuntimeError to be raised'
+ rescue NameError => e
+ assert_equal 'Could not resolve class for name: foobar', e.message
+ ensure
+ Asciidoctor::Extensions.unregister_all
+ end
+ end
+
test 'should allow standalone registry to be created but not registered' do
registry = Asciidoctor::Extensions.create 'sample' do
block do
@@ -1197,7 +1238,6 @@ sample content
end
end
-
test 'should add multiple docinfo to document' do
input = <<-EOS
= Document Title