Skip to content

Instantly share code, notes, and snippets.

@nepalez
Forked from solnic/checkproc_poc.rb
Last active August 29, 2015 14:24
Show Gist options
  • Save nepalez/ea7f60d2b6637f915602 to your computer and use it in GitHub Desktop.
Save nepalez/ea7f60d2b6637f915602 to your computer and use it in GitHub Desktop.
require 'equalizer'
module Checkproc
InvalidValueError = Class.new(StandardError) { include Equalizer.new(:message) }
class Composite
attr_reader :left
attr_reader :right
def initialize(left, right)
@left, @right = left, right
end
def call(data, errors = [])
right.call(*left.call(data, errors))
end
end
class Constraint
attr_reader :check
def self.define(&block)
new(block)
end
def initialize(check)
@check = check
end
def call(data, errors = [])
check.call(data, errors)
[data, errors]
rescue InvalidValueError => e
[data, errors + [e]]
end
def &(other)
Composite.new(self, other)
end
end
end
describe Checkproc::Constraint do
it 'composes many constraints and provides errors' do
check1 = Checkproc::Constraint.define do |data|
raise Checkproc::InvalidValueError, 'name cannot be nil' if data[:name].nil?
end
check2 = Checkproc::Constraint.define do |data|
raise Checkproc::InvalidValueError, 'age must be over 18' unless data[:age] > 18
end
validation = check1 & check2
data, errors = validation.call(name: nil, age: 17)
expect(data).to eql(name: nil, age: 17)
expect(errors).to include(Checkproc::InvalidValueError.new('name cannot be nil'))
expect(errors).to include(Checkproc::InvalidValueError.new('age must be over 18'))
data, errors = validation.call(name: 'Jane', age: 19)
expect(data).to eql(name: 'Jane', age: 19)
expect(errors).to be_empty
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment