Skip to content

Commit

Permalink
Merge pull request #182 from orgsync/interface-filter
Browse files Browse the repository at this point in the history
Add interface filter
  • Loading branch information
tfausak committed May 6, 2014
2 parents ff0d775 + a5d81d8 commit bfc7a49
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# [Master][]

- Add an interface filter.
- Add missing translation for symbol filters.

# [1.2.1][] (2014-05-02)
Expand Down
1 change: 1 addition & 0 deletions benchmarks/filters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
float: [0.0, '0.0', 0],
hash: [Hash.new], # TODO
integer: [0, '0', 0.0],
interface: [Object.new],
model: [Object.new], # TODO: Reconstantizing.
string: [''], # TODO: Without strip.
symbol: [:'', ''],
Expand Down
1 change: 1 addition & 0 deletions lib/active_interaction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
require 'active_interaction/filters/float_filter'
require 'active_interaction/filters/hash_filter'
require 'active_interaction/filters/integer_filter'
require 'active_interaction/filters/interface_filter'
require 'active_interaction/filters/model_filter'
require 'active_interaction/filters/string_filter'
require 'active_interaction/filters/symbol_filter'
Expand Down
42 changes: 42 additions & 0 deletions lib/active_interaction/filters/interface_filter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# coding: utf-8

module ActiveInteraction
class Base
# @!method self.interface(*attributes, options = {})
# Creates accessors for the attributes and ensures that values passed to
# the attributes implement an interface.
#
# @!macro filter_method_params
# @option options [Array<Symbol>] :methods ([]) the methods that objects
# conforming to this interface should respond to
#
# @example
# interface :anything
# @example
# interface :serializer,
# methods: [:dump, :load]
end

# @private
class InterfaceFilter < Filter
def cast(value)
matches?(value) ? value : super
end

private

# @param object [Object]
#
# @return [Boolean]
def matches?(object)
methods.all? { |method| object.respond_to?(method) }
rescue NoMethodError
false
end

# @return [Array<Symbol>]
def methods
options.fetch(:methods, [])
end
end
end
1 change: 1 addition & 0 deletions lib/active_interaction/locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ en:
float: float
hash: hash
integer: integer
interface: interface
model: model
string: string
symbol: symbol
Expand Down
46 changes: 46 additions & 0 deletions spec/active_interaction/filters/interface_filter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# coding: utf-8

require 'spec_helper'
require 'json'
require 'yaml'

describe ActiveInteraction::InterfaceFilter, :filter do
include_context 'filters'
it_behaves_like 'a filter'

before { options[:methods] = [:dump, :load] }

describe '#cast' do
let(:result) { filter.cast(value) }

context 'with an Object' do
let(:value) { Object.new }

it 'raises an error' do
expect { result }.to raise_error ActiveInteraction::InvalidValueError
end
end

context 'with JSON' do
let(:value) { JSON }

it 'returns an Array' do
expect(result).to eql value
end
end

context 'with YAML' do
let(:value) { YAML }

it 'returns an Hash' do
expect(result).to eql value
end
end
end

describe '#database_column_type' do
it 'returns :string' do
expect(filter.database_column_type).to eql :string
end
end
end
12 changes: 12 additions & 0 deletions spec/active_interaction/integration/interface_interaction_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# coding: utf-8

require 'spec_helper'
require 'json'
require 'yaml'

describe 'InterfaceInteraction' do
it_behaves_like 'an interaction',
:interface,
-> { [JSON, YAML].sample },
methods: [:dump, :load]
end

0 comments on commit bfc7a49

Please sign in to comment.