Permalink
Browse files

Rescue specific NameErrors when inferring classes

The previous behavior swallowed genuine NameErrors (as opposed to
failure to find the inferred class), for example when the user has
not updated the decorator base class from Draper::Base.
  • Loading branch information...
haines committed Mar 5, 2013
1 parent 2d5756b commit 09ad84fb712a30dd4302b9daa03d11281ac7d169
Showing with 38 additions and 9 deletions.
  1. +2 −1 lib/draper/decoratable.rb
  2. +8 −4 lib/draper/decorator.rb
  3. +7 −0 spec/draper/decoratable_spec.rb
  4. +21 −4 spec/draper/decorator_spec.rb
@@ -68,7 +68,8 @@ def decorator_class(namespace=nil)
decorator_name = [(namespace && namespace.name), "#{prefix}Decorator"].compact.join("::")
decorator_name.constantize
- rescue NameError
+ rescue NameError => error
+ raise unless error.missing_name?(decorator_name)
raise Draper::UninferrableDecoratorError.new(self)
end
View
@@ -212,8 +212,10 @@ def attributes
# @return [Class] the class created by {decorate_collection}.
def self.collection_decorator_class(namespace=nil)
- collection_decorator_name(namespace).constantize
- rescue NameError
+ name = collection_decorator_name(namespace)
+ name.constantize
+ rescue NameError => error
+ raise if name && !error.missing_name?(name)
Draper::CollectionDecorator
end
@@ -225,8 +227,10 @@ def self.source_name
end
def self.inferred_source_class
- source_name.constantize
- rescue NameError
+ name = source_name
+ name.constantize
+ rescue NameError => error
+ raise if name && !error.missing_name?(name)
raise Draper::UninferrableSourceError.new(self)
end
@@ -179,6 +179,13 @@ module Draper
expect{Model.decorator_class}.to raise_error UninferrableDecoratorError
end
end
+
+ context "when an unrelated NameError is thrown" do
+ it "re-raises that error" do
+ String.any_instance.stub(:constantize).and_return{Draper::Base}
+ expect{Product.decorator_class}.to raise_error NameError, /Draper::Base/
+ end
+ end
end
end
@@ -154,6 +154,13 @@ module Draper
Decorator.decorate_collection(source, with: nil, namespace: DecoratorNamespace)
end
end
+
+ context "when a NameError is thrown" do
+ it "re-raises that error" do
+ String.any_instance.stub(:constantize).and_return{Draper::DecoratedEnumerableProxy}
+ expect{ProductDecorator.decorate_collection([])}.to raise_error NameError, /Draper::DecoratedEnumerableProxy/
+ end
+ end
end
describe ".decorates" do
@@ -179,20 +186,23 @@ module Draper
end
describe ".source_class" do
+ protect_class ProductDecorator
+ protect_class Namespaced::ProductDecorator
+
context "when not set by .decorates" do
- it "raises an error for a so-named 'Decorator'" do
+ it "raises an UninferrableSourceError for a so-named 'Decorator'" do
expect{Decorator.source_class}.to raise_error UninferrableSourceError
end
- it "raises an error for anonymous decorators" do
+ it "raises an UninferrableSourceError for anonymous decorators" do
expect{Class.new(Decorator).source_class}.to raise_error UninferrableSourceError
end
- it "raises an error for a decorator without a model" do
+ it "raises an UninferrableSourceError for a decorator without a model" do
expect{OtherDecorator.source_class}.to raise_error UninferrableSourceError
end
- it "raises an error for other naming conventions" do
+ it "raises an UninferrableSourceError for other naming conventions" do
expect{ProductPresenter.source_class}.to raise_error UninferrableSourceError
end
@@ -203,6 +213,13 @@ module Draper
it "infers namespaced sources" do
expect(Namespaced::ProductDecorator.source_class).to be Namespaced::Product
end
+
+ context "when an unrelated NameError is thrown" do
+ it "re-raises that error" do
+ String.any_instance.stub(:constantize).and_return{SomethingThatDoesntExist}
+ expect{ProductDecorator.source_class}.to raise_error NameError, /SomethingThatDoesntExist/
+ end
+ end
end
end

0 comments on commit 09ad84f

Please sign in to comment.