-
Notifications
You must be signed in to change notification settings - Fork 0
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
10 changed files
with
181 additions
and
24 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
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,55 @@ | ||
module Granite | ||
module Form | ||
module Util | ||
extend ActiveSupport::Concern | ||
|
||
# Evaluates value and returns result based on what was passed: | ||
# - if Proc was passed, then executes it in context of self | ||
# - if Symbol was passed, then calls a method with that name and returns result | ||
# - otherwise just returns the value itself | ||
# @param value [Object] value to evaluate | ||
# @return [Object] result of evaluation | ||
def evaluate(value, *args) | ||
value.is_a?(Symbol) ? evaluate_symbol(value, *args) : evaluate_if_proc(value, *args) | ||
end | ||
|
||
# Evaluates value and returns result based on what was passed: | ||
# - if Proc was passed, then executes it in context of self | ||
# - otherwise just returns the value itself | ||
# @param value [Object] value to evaluate | ||
# @return [Object] result of evaluation | ||
def evaluate_if_proc(value, *args) | ||
value.is_a?(Proc) ? evaluate_proc(value, *args) : value | ||
end | ||
|
||
# Evaluates `if` or `unless` conditions present in the supplied | ||
# `options` being it a symbol or callable. | ||
# | ||
# @param [Hash] options The method options to evaluate. | ||
# @option options :if method name or callable | ||
# @option options :unless method name or callable | ||
# @return [Boolean] whether conditions are satisfied | ||
def conditions_satisfied?(**options) | ||
raise ArgumentError, 'You cannot specify both if and unless' if options.key?(:if) && options.key?(:unless) | ||
|
||
if options.key?(:if) | ||
evaluate(options[:if]) | ||
elsif options.key?(:unless) | ||
!evaluate(options[:unless]) | ||
else | ||
true | ||
end | ||
end | ||
|
||
private | ||
|
||
def evaluate_proc(value, *args) | ||
instance_exec(*args, &value) | ||
end | ||
|
||
def evaluate_symbol(value, *args) | ||
__send__(value, *args) | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
require 'spec_helper' | ||
|
||
RSpec.describe Granite::Form::Util do | ||
subject(:dummy) { Dummy.new('John') } | ||
|
||
before do | ||
stub_class(:dummy, Object) do | ||
attr_accessor :name | ||
|
||
def initialize(name) | ||
@name = name | ||
end | ||
|
||
def full_name(last_name) | ||
[name, last_name].join(' ') | ||
end | ||
end | ||
|
||
Dummy.include described_class | ||
end | ||
|
||
describe '#evaluate' do | ||
subject { dummy.evaluate(target) } | ||
let(:target) { 'Peter' } | ||
|
||
it { is_expected.to eq('Peter') } | ||
|
||
context 'when symbol is passed' do | ||
let(:target) { :name } | ||
|
||
it { is_expected.to eq('John') } | ||
end | ||
|
||
context 'when lambda is passed' do | ||
let(:target) { -> { name } } | ||
|
||
it { is_expected.to eq('John') } | ||
end | ||
|
||
context 'with extra arguments' do | ||
subject { dummy.evaluate(target, 'Doe') } | ||
|
||
context 'when symbol is passed' do | ||
let(:target) { :full_name } | ||
|
||
it { is_expected.to eq('John Doe') } | ||
end | ||
|
||
context 'when lambda is passed' do | ||
let(:target) { ->(last_name) { ['John', last_name].join(' ') } } | ||
|
||
it { is_expected.to eq('John Doe') } | ||
end | ||
end | ||
end | ||
|
||
describe '#evaluate_if_proc' do | ||
subject { dummy.evaluate(target) } | ||
let(:target) { 'Peter' } | ||
|
||
it { is_expected.to eq('Peter') } | ||
|
||
context 'when lambda is passed' do | ||
let(:target) { -> { name } } | ||
|
||
it { is_expected.to eq('John') } | ||
end | ||
|
||
context 'with extra arguments' do | ||
subject { dummy.evaluate(target, 'Doe') } | ||
|
||
let(:target) { ->(last_name) { ['John', last_name].join(' ') } } | ||
|
||
it { is_expected.to eq('John Doe') } | ||
end | ||
end | ||
|
||
describe '#conditions_satisfied?' do | ||
subject { dummy.conditions_satisfied?(**conditions) } | ||
let(:conditions) { {if: -> { name == 'John' }} } | ||
|
||
it { is_expected.to be_truthy } | ||
|
||
context 'when if condition is satisfied' do | ||
before { dummy.name = 'Peter' } | ||
|
||
it { is_expected.to be_falsey } | ||
end | ||
|
||
context 'when unless condition is passed' do | ||
let(:conditions) { {unless: :name} } | ||
|
||
it { is_expected.to be_falsey } | ||
end | ||
|
||
context 'when no condition is passed' do | ||
let(:conditions) { {} } | ||
|
||
it { is_expected.to be_truthy } | ||
end | ||
|
||
context 'when both if & unless are passed' do | ||
let(:conditions) { {if: :name, unless: :name} } | ||
|
||
it { expect { subject }.to raise_error(ArgumentError) } | ||
end | ||
end | ||
end |