Skip to content

Commit

Permalink
Make hanami-validation a soft-dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
jodosha committed May 10, 2016
1 parent 1b179b0 commit 64f3cef
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 168 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
@@ -1,7 +1,7 @@
language: ruby
sudo: false
cache: bundler
script: 'bundle exec rake test:coverage --trace'
script: 'script/ci'
before_install:
- rvm get head # required by JRuby > 9.0.1.0
- rvm reload
Expand Down
13 changes: 8 additions & 5 deletions Gemfile
Expand Up @@ -8,12 +8,15 @@ end

gem 'hanami-utils', '~> 0.8', require: false, github: 'hanami/utils', branch: '0.8.x'
gem 'hanami-router', '~> 0.7', require: false, github: 'hanami/router', branch: '0.7.x'
gem 'hanami-validations', '~> 0.6', require: false, github: 'hanami/validations', branch: 'predicates-with-new-backend'

# This is required until dry-validation 0.8 will be out
gem 'dry-types', require: false, github: 'dry-rb/dry-types'
gem 'dry-logic', require: false, github: 'dry-rb/dry-logic'
gem 'dry-validation', require: false, github: 'dry-rb/dry-validation'
group :validations do
gem 'hanami-validations', '~> 0.6', require: false, github: 'hanami/validations', branch: 'predicates-with-new-backend'

# This is required until dry-validation 0.8 will be out
gem 'dry-types', require: false, github: 'dry-rb/dry-types'
gem 'dry-logic', require: false, github: 'dry-rb/dry-logic'
gem 'dry-validation', require: false, github: 'dry-rb/dry-validation'
end

gem 'minitest-line'
gem 'coveralls', require: false
5 changes: 4 additions & 1 deletion Rakefile
Expand Up @@ -3,7 +3,10 @@ require 'rake/testtask'
require 'bundler/gem_tasks'

Rake::TestTask.new do |t|
t.pattern = 'test/**/*_test.rb'
t.test_files = Dir['test/**/*_test.rb'].reject do |path|
path.include?('isolation')
end

t.libs.push 'test'
end

Expand Down
5 changes: 2 additions & 3 deletions hanami-controller.gemspec
Expand Up @@ -19,9 +19,8 @@ Gem::Specification.new do |spec|
spec.require_paths = ['lib']
spec.required_ruby_version = '>= 2.2.0'

spec.add_dependency 'rack', '~> 1.6', '>= 1.6.2'
spec.add_dependency 'hanami-utils', '~> 0.8'
spec.add_dependency 'hanami-validations', '~> 0.6'
spec.add_dependency 'rack', '~> 1.6', '>= 1.6.2'
spec.add_dependency 'hanami-utils', '~> 0.8'

spec.add_development_dependency 'bundler', '~> 1.6'
spec.add_development_dependency 'minitest', '~> 5'
Expand Down
8 changes: 6 additions & 2 deletions lib/hanami/action.rb
Expand Up @@ -5,7 +5,11 @@
require 'hanami/action/exposable'
require 'hanami/action/throwable'
require 'hanami/action/callbacks'
require 'hanami/action/validatable'
begin
require 'hanami/validations'
require 'hanami/action/validatable'
rescue LoadError
end
require 'hanami/action/head'
require 'hanami/action/callable'

Expand Down Expand Up @@ -53,7 +57,7 @@ def self.included(base)
include Exposable
include Throwable
include Callbacks
include Validatable
include Validatable if defined?(Validatable)
include Configurable
include Head
prepend Callable
Expand Down
2 changes: 1 addition & 1 deletion lib/hanami/action/base_params.rb
Expand Up @@ -69,7 +69,7 @@ def initialize(env)
#
# @return [Object,nil] return the associated object, if found
#
# @since 0.2.0
# @since x.x.x
def [](key)
@params[key]
end
Expand Down
2 changes: 0 additions & 2 deletions lib/hanami/action/callable.rb
@@ -1,5 +1,3 @@
require 'hanami/action/base_params'

module Hanami
module Action
module Callable
Expand Down
5 changes: 4 additions & 1 deletion lib/hanami/action/exposable.rb
Expand Up @@ -16,7 +16,10 @@ module Exposable
#
# @see http://www.ruby-doc.org/core-2.1.2/Module.html#method-i-included
def self.included(base)
base.extend ClassMethods
base.class_eval do
extend ClassMethods
expose :params

This comment has been minimized.

Copy link
@parndt

parndt Jan 5, 2017

Contributor

@jodosha did you intend for this to make params available everywhere? This makes def call(params) redundant, because it's available regardless and might as well be def call. Of course, I'd rather that params wasn't magically available throughout the class, so can we revisit this please? ❤️

This comment has been minimized.

Copy link
@jodosha

jodosha Jan 5, 2017

Author Member

I removed my comment, please let's continue the discussion here #198 😄

end
end

# Exposures API class methods
Expand Down
141 changes: 7 additions & 134 deletions lib/hanami/action/params.rb
@@ -1,6 +1,5 @@
require 'hanami/action/base_params'
require 'hanami/validations/form'
require 'hanami/utils/hash'
require 'hanami/utils/class_attribute'

module Hanami
module Action
Expand All @@ -14,66 +13,13 @@ module Action
# * Default: it returns the given hash as it is. It's useful for testing purposes.
#
# @since 0.1.0
class Params
# The key that returns raw input from the Rack env
#
# @since 0.1.0
RACK_INPUT = 'rack.input'.freeze

# The key that returns router params from the Rack env
# This is a builtin integration for Hanami::Router
#
# @since 0.1.0
ROUTER_PARAMS = 'router.params'.freeze

# CSRF params key
#
# This key is shared with <tt>hanamirb</tt> and <tt>hanami-helpers</tt>
#
# @since 0.4.4
# @api private
CSRF_TOKEN = '_csrf_token'.freeze

# Set of params that are never filtered
#
# @since 0.4.4
# @api private
DEFAULT_PARAMS = Hash[CSRF_TOKEN => true].freeze

# Separator for #get
#
# @since 0.4.0
# @api private
#
# @see Hanami::Action::Params#get
GET_SEPARATOR = '.'.freeze

class Params < BaseParams
include Hanami::Validations::Form

def self.inherited(klass)
klass.class_eval do
include Hanami::Utils::ClassAttribute

class_attribute :_validations
self._validations = false
end
end

def self.params(&blk)
if blk.nil?
validations {}
else
validations(&blk)
self._validations = true
end
validations(&blk || ->() {})
end

# @attr_reader env [Hash] the Rack env
#
# @since 0.2.0
# @api private
attr_reader :env

# Initialize the params and freeze them.
#
# @param env [Hash] a Rack env or an hash of params.
Expand Down Expand Up @@ -106,63 +52,6 @@ def valid?
@result.success?
end

# Returns the object associated with the given key
#
# @param key [Symbol] the key
#
# @return [Object,nil] return the associated object, if found
#
# @since 0.2.0
def [](key)
@params[key]
end

# Get an attribute value associated with the given key.
# Nested attributes are reached with a dot notation.
#
# @param key [String] the key
#
# @return [Object,NilClass] return the associated value, if found
#
# @since 0.4.0
#
# @example
# require 'hanami/controller'
#
# module Deliveries
# class Create
# include Hanami::Action
#
# params do
# param :customer_name
# param :address do
# param :city
# end
# end
#
# def call(params)
# params.get('customer_name') # => "Luca"
# params.get('uknown') # => nil
#
# params.get('address.city') # => "Rome"
# params.get('address.unknown') # => nil
#
# params.get(nil) # => nil
# end
# end
# end
def get(key)
key, *keys = key.to_s.split(GET_SEPARATOR)
result = self[key.to_sym]

Array(keys).each do |k|
break if result.nil?
result = result[k.to_sym]
end

result
end

# Serialize params to Hash
#
# @return [::Hash]
Expand All @@ -173,18 +62,6 @@ def to_h
end
alias_method :to_hash, :to_h

# Assign CSRF Token.
# This method is here for compatibility with <tt>Hanami::Validations</tt>.
#
# NOTE: When we will not support indifferent access anymore, we can probably
# remove this method.
#
# @since 0.4.4
# @api private
def _csrf_token=(value)
@params.set(CSRF_TOKEN, value)
end

private

# @since x.x.x
Expand All @@ -205,16 +82,12 @@ def _extract_params
end

def _params
if self.class._validations
result = @result.output
result = @result.output

if _csrf_token = raw['_csrf_token']
result.merge(:_csrf_token => _csrf_token)
else
result
end
if _csrf_token = raw['_csrf_token']
result.merge(:_csrf_token => _csrf_token)
else
Utils::Hash.new(raw).symbolize!.to_h
result
end
end

Expand Down
15 changes: 15 additions & 0 deletions lib/hanami/action/rack.rb
@@ -1,5 +1,6 @@
require 'securerandom'
require 'hanami/action/request'
require 'hanami/action/base_params'
require 'hanami/action/rack/callable'
require 'hanami/action/rack/file'

Expand Down Expand Up @@ -102,6 +103,20 @@ def rack_builder
def use(middleware, *args, &block)
rack_builder.use middleware, *args, &block
end

# Returns the class which defines the params
#
# Returns the class which has been provided to define the
# params. By default this will be Hanami::Action::Params.
#
# @return [Class] A params class (when whitelisted) or
# Hanami::Action::Params
#
# @api private
# @since x.x.x
def params_class
@params_class ||= BaseParams
end
end

# @since x.x.x
Expand Down
21 changes: 3 additions & 18 deletions lib/hanami/action/validatable.rb
@@ -1,3 +1,5 @@
require 'hanami/action/params'

module Hanami
module Action
module Validatable
Expand All @@ -8,10 +10,7 @@ module Validatable
PARAMS_CLASS_NAME = 'Params'.freeze

def self.included(base)
base.class_eval do
extend ClassMethods
expose :params
end
base.extend ClassMethods
end

# Validatable API class methods
Expand Down Expand Up @@ -100,20 +99,6 @@ def params(klass = nil, &blk)

@params_class = klass
end

# Returns the class which defines the params
#
# Returns the class which has been provided to define the
# params. By default this will be Hanami::Action::Params.
#
# @return [Class] A params class (when whitelisted) or
# Hanami::Action::Params
#
# @api private
# @since 0.3.0
def params_class
@params_class ||= BaseParams
end
end
end
end
Expand Down
37 changes: 37 additions & 0 deletions script/ci
@@ -0,0 +1,37 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'

run_unit_tests() {
bundle exec rake test:coverage
}

run_integration_tests() {
local pwd=$PWD
local root="$pwd/test/isolation"

for test in $(find $root -name '*_test.rb')
do
run_test $test

if [ $? -ne 0 ]; then
local exit_code=$?
echo "Failing test: $test"
exit $exit_code
fi
done
}

run_test() {
local test=$1

printf "\n\n\nRunning: $test\n"
ruby -Itest $test
}

main() {
run_unit_tests &&
run_integration_tests
}

main

0 comments on commit 64f3cef

Please sign in to comment.