Skip to content

Commit

Permalink
Add State#unwrap
Browse files Browse the repository at this point in the history
  • Loading branch information
pabloh committed Aug 6, 2024
1 parent 3720962 commit e3c6602
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [0.12.2] - 2024-08-06
### Added
- Add `Pathway::State#unwrap` and `Pathway::State#u` to access internal state

## [0.12.1] - 2024-06-23
### Added
- Add support for pattern matching on `Result`, `State` and `Error` instances
Expand Down
18 changes: 17 additions & 1 deletion lib/pathway.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,23 @@ def to_hash
@hash
end

alias :to_h :to_hash
def unwrap(&bl)
raise 'a block must be provided' if !block_given?
params = bl.parameters
unless params.all? { |(type,_)| [:block, :key, :keyreq, :keyrest].member?(type) }
raise 'only keyword arguments are supported for unwraping'
end

if params.any? {|(type,_)| type == :keyrest }
bl.call(**to_hash)
else
keys = params.select {|(type,_)| type == :key || type == :keyreq }.map(&:last)
bl.call(**to_hash.slice(*keys))
end
end

alias_method :to_h, :to_hash
alias_method :u, :unwrap
end

module Plugins
Expand Down
1 change: 1 addition & 0 deletions lib/pathway/plugins/auto_deconstruct_state/ruby3.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module DSLMethods

def _callable(callable)
if callable.is_a?(Symbol) && @operation.respond_to?(callable, true) &&
@operation.method(callable).arity != 0 &&
@operation.method(callable).parameters.all? { _1 in [:key|:keyreq|:keyrest|:block,*] }

-> state { @operation.send(callable, **state) }
Expand Down
2 changes: 1 addition & 1 deletion lib/pathway/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Pathway
VERSION = '0.12.1'
VERSION = '0.12.2'
end
1 change: 1 addition & 0 deletions pathway.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "pry"
spec.add_development_dependency "pry-byebug"
spec.add_development_dependency "pry-doc"
spec.add_development_dependency "pry-stack"
end
6 changes: 4 additions & 2 deletions spec/plugins/auto_deconstruct_state_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ def create_model(name:, email:, **)
UserModel.new(name, email)
end

def notify(value:, **)
@notifier.call(value)
def notify(s)
s.u do |value:|
@notifier.call(value)
end
end
end

Expand Down
49 changes: 49 additions & 0 deletions spec/state_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,55 @@ class SimpleOp < Operation
end
end

describe '#unwrap' do
before { state.update(val: 'RESULT', foo: 99, bar: 131) }
it 'fails if no block is provided' do
expect { state.unwrap }.to raise_error('a block must be provided')
end

context 'when a block is provided' do
it 'passes specified values by the keyword params', :aggregate_failures do
expect(state.unwrap {|val:| val }).to eq('RESULT')
expect(state.unwrap {|foo:| foo }).to eq(99)
expect(state.unwrap {|val:, bar:| [val, bar] })
.to eq(['RESULT', 131])
end

it 'passes all values if **kwargs is part of the params', :aggregate_failures do
expect(state.unwrap {|**kargs| kargs })
.to eq(foo: 99, bar: 131, val: 'RESULT', input: 'some value')
expect(state.unwrap {|input:, **kargs| input }).to eq('some value')
expect(state.unwrap {|input:, **kargs| kargs })
.to eq(foo: 99, bar: 131, val: 'RESULT')
end

it 'passes no arguments if no keyword params are defined' do
expect(state.unwrap { 77 }).to eq(77)
end

it 'fails if at least one positional param is defined', :aggregate_failures do
expect { state.unwrap {|pos, input:| } }
.to raise_error('only keyword arguments are supported for unwraping')
expect { state.unwrap {|input| } }
.to raise_error('only keyword arguments are supported for unwraping')
end

context 'and it takes a block argument' do
it 'fails if it has positional params' do
expect { state.unwrap {|input, &bl| } }
.to raise_error('only keyword arguments are supported for unwraping')
end

it 'does not fails if only keyword params', :aggregate_failures do
expect(state.unwrap {|val:, &bl| val }).to eq('RESULT')
expect(state.unwrap {|val:, &_| val }).to eq('RESULT')
expect(state.unwrap {|&_| 77 }).to eq(77)
end
end

end
end

describe '#update' do
let(:result) { state.update(qux: 33, quz: 11) }
it 'returns and updated state with the passed values' do
Expand Down

0 comments on commit e3c6602

Please sign in to comment.