[Discussion] Allow arity -1 in ROP to improve testability
MR: Allow arity -1 in ROP to improve testability (!151574 - closed)
Description
In the Remote-Development codebase where we implement a Railway-Oriented-Programming style, should we update validate_lambda_or_singleton_method
to allow functions with arity -1
https://apidock.com/ruby/Method/arity to support directly mocking collaborators (see Context for example)?
Context
The following discussion from !147718 (merged) should be addressed:
-
@pslaughter started a discussion: (+3 comments) suggestion: There's a lot of mocking indirection here (e.g. the need to mock
:method
). I'd expect to be able to do just something like:allow(RemoteDevelopment::Workspaces::Create::PersonalAccessTokenCreator).to receive(:create).with(value) do create(:personal_access_token) Result.ok(value) end
which actually works if I update this check in
result.rb
diff --git a/lib/result.rb b/lib/result.rb index 5e72b3f13cb3..289f4393a34d 100644 --- a/lib/result.rb +++ b/lib/result.rb @@ -198,7 +198,7 @@ def validate_lambda_or_singleton_method(lambda_or_singleton_method) arity = lambda_or_singleton_method.arity - return if arity == 1 + return if arity == 1 || arity == -1 err_msg = "'Result##{__method__}' expects a lambda or singleton method object with a single argument " \ "(arity of 1), but instead received '#{lambda_or_singleton_method.inspect}' with an arity of #{arity}."
An
arity
of-1
means it takes a variable number of arguments which means we can interact with it as if it just included a single argument and it won't break the pipeline. It's weird thatrspec
changes the arity of this when you start stubbing things, but allowing-1
seems reasonable (and more preferable than all the mocking indirection at the moment).The issue with the mocking indirection on
:method
is that we actually miss that we're trying to include the:create
method. The tests still pass with a bug like this:diff --git a/ee/lib/remote_development/workspaces/create/creator.rb b/ee/lib/remote_development/workspaces/create/creator.rb index 12b6e484b2fa..7385ad613a84 100644 --- a/ee/lib/remote_development/workspaces/create/creator.rb +++ b/ee/lib/remote_development/workspaces/create/creator.rb @@ -30,7 +30,7 @@ def self.create(value) result = initial_result - .and_then(PersonalAccessTokenCreator.method(:create)) + .and_then(PersonalAccessTokenCreator.method(:foo)) .and_then(WorkspaceCreator.method(:create)) .and_then(WorkspaceVariablesCreator.method(:create))
WDYT? Are you up for updating our
result.rb
check to allowarity
of-1
here? Is there a better way we can make sure we're testing things a bit more integrated?