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
2 changes: 1 addition & 1 deletion .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
ruby_version: [2.6.9, 2.7.5, 3.0.3]
ruby_version: [2.7.8, 3.0.7]
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
Expand Down
24 changes: 14 additions & 10 deletions lib/active_operation/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ class ActiveOperation::Base
define_callbacks :halted, scope: [:name]

class << self
def perform(*args)
new(*args).call
def perform(...)
new(...).call
end

def from_proc(execute)
Expand All @@ -30,8 +30,8 @@ def from_proc(execute)
when :req
input name, type: :positional, required: true
positional_arguments << name
when :keyreq
input name, type: :keyword, required: true
when :keyreq, :key
input name, type: :keyword, required: (type == :keyreq)
Comment on lines +33 to +34

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this change and why was it required?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously the API was method(*args), now it supports both method(*args, **kwargs) so this is to ensure positional arg is required and kwargs aren't

keyword_arguments << name
else
raise ArgumentError, "Argument type not supported: #{type}"
Expand All @@ -51,17 +51,17 @@ def from_proc(execute)
end
end

def call(*args)
perform(*args)
def call(...)
perform(...)
end

def inputs
[]
end

def to_proc
->(*args) {
perform(*args)
->(*args, **kwargs) {
perform(*args, **kwargs)
}
end

Expand Down Expand Up @@ -130,15 +130,19 @@ def inherited(subclass)
def initialize(*args)
arity = self.class.inputs.count(&:positional?)
arguments = args.shift(arity)
attributes = args.last.kind_of?(Hash) ? args.pop : {}
attributes = if args.last.is_a?(Hash)
args.pop.transform_keys(&:to_sym)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to do symbols?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some test cases were failing and this fixed them

else
{}
end

raise ArgumentError, "wrong number of arguments #{arguments.length + args.length} for #{arity}" unless args.empty?

self.class.inputs.select(&:positional?).each_with_index do |input, index|
attributes[input.name] = arguments[index]
end

super(attributes)
super(**attributes)
end

def perform
Expand Down
5 changes: 3 additions & 2 deletions spec/active_operation/pipeline_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,9 @@ def execute
expect { described_class.compose { use ->(a = 1) {} } }.to raise_error(ArgumentError)
end

it "does not support optional keyword arguments as Ruby's reflection mechanism does not support accessing the default value which is required to setup the operation inputs correctly" do
expect { described_class.compose { use ->(a: 1) {} } }.to raise_error(ArgumentError)
it "supports optional keyword arguments" do
pipeline = described_class.compose { use ->(a: 1) { a } }
expect(pipeline.call(a: 2)).to eq(2)
end
end
end