Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
FROM ruby:2.3.1
FROM ruby:2.6.5

ENV TEST_HOME=/pipes
ADD *.gemspec $TEST_HOME/
ADD Gemfile $TEST_HOME/
WORKDIR $TEST_HOME

RUN gem install bundler
RUN bundle install --jobs 8 --retry 5

ADD . $TEST_HOME
4 changes: 0 additions & 4 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
source 'https://rubygems.org'

gemspec

group :test do
gem 'rspec'
end
7 changes: 5 additions & 2 deletions codequest_pipes.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ Gem::Specification.new do |spec|
spec.files = Dir['lib/**/*.rb'] + Dir['spec/**/*.rb']
spec.test_files = spec.files.grep(/^spec/)

spec.add_development_dependency 'bundler', '~> 1.6', '>= 1.6.9'
spec.add_development_dependency 'rake', '~> 10.3'
spec.add_development_dependency 'bundler', '~> 2.0'
spec.add_development_dependency 'rake', '~> 13.0'
spec.add_development_dependency 'rspec', '~> 3.9'

spec.add_dependency 'ice_nine', '~> 0.11'
end
27 changes: 20 additions & 7 deletions lib/codequest_pipes/context.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'ice_nine'

require 'codequest_pipes/context/error_collector'

module Pipes
Expand All @@ -16,19 +18,23 @@ class ExecutionTerminated < ::StandardError; end
# Context constructor.
#
# @param values [Hash]
def initialize(values = {})
add(values)
def initialize(values = {}, mutable_values = {})
@error_collector = ErrorCollector.new
@mutable_values = Set.new
add(values, mutable_values)
end

# Method `add` allows adding new properties (as a Hash) to the Context.
#
# @param values [Hash]
def add(values)
def add(values, mutable_values = {})
values.each do |key, val|
k_sym = key.to_sym
fail Override, "Property :#{key} already present" if respond_to?(k_sym)
define_singleton_method(k_sym) { val }
add_value(key.to_sym, IceNine.deep_freeze(val))
end

mutable_values.each do |key, val|
add_value(key.to_sym, val)
@mutable_values << key
end
end

Expand Down Expand Up @@ -101,6 +107,13 @@ def add_errors(collectable_errors)

private

attr_reader :error_collector
attr_reader :error_collector, :mutable_values

def add_value(key, value)
if respond_to?(key) && !mutable_values.include?(key)
fail Override, "Property :#{key} already exists and is non-mutable"
end
define_singleton_method(key) { value }
end
end # class Context
end # module Pipes
17 changes: 17 additions & 0 deletions spec/context_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,23 @@
expect { subject.add(key: 'other_val') }
.to raise_error(Pipes::Context::Override)
end

it 'does not allow modifying existing fields' do
subject.add(key: 'val')
expect { subject.key << 'ue' }.to raise_error(FrozenError)
end

it 'allows rewriting existing mutable fields' do
subject.add({}, key: 'val')
expect { subject.add(key: 'other_val') }
.to change { subject.key }.from('val').to 'other_val'
end

it 'allows modifying existing mutable fields' do
subject.add({}, key: 'val')
expect { subject.key << 'ue' }
.to change { subject.key }.from('val').to 'value'
end
end # describe '#add'

describe '#inspect' do
Expand Down
2 changes: 1 addition & 1 deletion spec/pipe_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class RequiringNumericChild < Parent
class NoMethodPipe < Pipes::Pipe; end

describe Pipes::Pipe do
let(:ctx) { Pipes::Context.new(flow: []) }
let(:ctx) { Pipes::Context.new({}, flow: []) }

subject { pipe.call(ctx) }

Expand Down