-
-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
328 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
require 'hanami/controller/error' | ||
|
||
module Hanami | ||
module Controller | ||
# Exposure of reserved words | ||
# | ||
# @since 0.7.1 | ||
class IllegalExposureError < Error | ||
end | ||
end | ||
|
||
module Action | ||
module Exposable | ||
# Guard for Exposures API. | ||
# Prevents exposure of reserved words | ||
# | ||
# @since 0.7.1 | ||
# | ||
# @see Hanami::Action::Exposable::Guard::ClassMethods#expose | ||
# @see Hanami::Action::Exposable::Guard::ClassMethods#reserved_word? | ||
module Guard | ||
# Override Ruby's hook for modules. | ||
# It prepends a guard for the exposures logic | ||
# | ||
# @param base [Class] the target action | ||
# | ||
# @since 0.7.1 | ||
# @api private | ||
# | ||
# @see http://www.ruby-doc.org/core-2.1.2/Module.html#method-i-included | ||
def self.included(base) | ||
class << base | ||
prepend ClassMethods | ||
end | ||
end | ||
|
||
# Exposures API Guard class methods | ||
# | ||
# @since 0.7.1 | ||
# @api private | ||
module ClassMethods | ||
# Prevents exposure if names contain a reserved word. | ||
# | ||
# @param names [Array<Symbol>] the name(s) of the attribute(s) to be | ||
# exposed | ||
# | ||
# @return [void] | ||
# | ||
# @since 0.7.1 | ||
def expose(*names) | ||
detect_reserved_words!(names) | ||
|
||
super | ||
end | ||
|
||
private | ||
|
||
# Raises error if given names contain a reserved word. | ||
# | ||
# @param names [Array<Symbol>] a list of names to be checked. | ||
# | ||
# @return [void] | ||
# | ||
# @raise [IllegalExposeError] if names contain one or more of reserved | ||
# words | ||
# | ||
# @since 0.7.1 | ||
# @api private | ||
def detect_reserved_words!(names) | ||
names.each do |name| | ||
if reserved_word?(name) | ||
raise Hanami::Controller::IllegalExposureError.new("#{name} is a reserved word. It cannot be exposed") | ||
end | ||
end | ||
end | ||
|
||
# Checks if a string is a reserved word | ||
# | ||
# Reserved word is a name of the method defined in one of the modules | ||
# of a given namespace. | ||
# | ||
# @param name [Symbol] the word to be checked | ||
# @param namespace [String] the namespace containing internal modules | ||
# | ||
# @return [true, false] | ||
# | ||
# @since 0.7.1 | ||
# @api private | ||
def reserved_word?(name, namespace = 'Hanami') | ||
if method_defined?(name) || private_method_defined?(name) | ||
method_owner = instance_method(name).owner | ||
|
||
Utils::String.new(method_owner).namespace == namespace | ||
else | ||
false | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
require 'test_helper' | ||
|
||
describe Hanami::Action::Exposable do | ||
describe '#expose' do | ||
it 'creates a getter for the given ivar' do | ||
action = ExposeAction.new | ||
|
||
response = action.call({}) | ||
response[0].must_equal 200 | ||
|
||
action.exposures.fetch(:film).must_equal '400 ASA' | ||
action.exposures.fetch(:time).must_equal nil | ||
end | ||
|
||
describe 'when reserved word is used' do | ||
subject { ExposeReservedWordAction.expose_reserved_word } | ||
|
||
it 'should raise an exception' do | ||
->() { subject }.must_raise Hanami::Controller::IllegalExposureError | ||
end | ||
end | ||
|
||
describe 'when reserved word is not used' do | ||
let(:action_class) do | ||
Class.new do | ||
include Hanami::Action | ||
|
||
include Module.new { def flash; end } | ||
|
||
expose :flash | ||
end | ||
end | ||
|
||
subject { action_class.new.exposures } | ||
|
||
it 'adds a key to exposures list' do | ||
subject.must_include :flash | ||
end | ||
end | ||
end | ||
|
||
describe '#_expose' do | ||
describe 'when exposuring a reserved word' do | ||
it 'does not fail' do | ||
ExposeReservedWordAction.expose_reserved_word(using_internal_method: true) | ||
|
||
action = ExposeReservedWordAction.new | ||
action.call({}) | ||
|
||
action.exposures.must_include :flash | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.