-
Notifications
You must be signed in to change notification settings - Fork 11
Add support for options hashes without braces #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
5ce286e
Add failing test for options hash arity
calebhearth fc6c6d4
Add BuildsMethodSignature
calebhearth ba6f7c7
Plug in BuildsMethodSignature
calebhearth 9c1d71e
Use eval instead of class_eval
calebhearth 7a81192
Apply suggestions from code review
calebhearth def814a
live with this evil
searls 23e6916
make all params & keyword params optional in our signatures
searls 7353b13
committing crimes against ruby to get this thing passing again
searls 3b0d269
Fix linting & tests for Ruby 3.0 by adding YET MORE EVAL oh no
searls 49fd88b
avoid a ruby warning that's hard to shake now that we're doing eval b…
searls ac22915
No evidence this change was necessary
searls 71bb11f
Outdated comment
searls f1b97ad
remove unit-of-work/transactional ivars
searls 0d10f79
rename dependency, structure test more consistently with others
searls 37decc3
Found a new edge case (implicit block args broke), wrote a failing te…
searls 7baf4a8
Fixes the case of stubbing/verifying mocked methods that act on impli…
searls 98029db
extract magic strings to constants
searls a8e9253
Now that the block param is always supplied and its name is always kn…
searls 7496e98
Failing test for yet another edge case: using eval to define methods …
searls 5a00de1
Makes the test pass by prepending everything we reference with __mock…
searls 55d4d8a
I should maybe stop metaprogramming inside a heredoc
searls 0f30710
start refactoring this logic -- just realized it introduces a bug I n…
searls ee389e2
Fix the issue of out-of-order parameters by selecting on all instead …
searls c594f69
lol this test wasn't running b/c the filename didn't end in _test
searls d99ccdb
Add assertions to this test and pull it into the SAFE suite
searls efe316d
wups
searls 1c12118
detangle this black hole of density a bit
searls 06029da
Update test/unit/stringifies_method_signature_test.rb
searls f53a733
Revert "Update test/unit/stringifies_method_signature_test.rb"
searls File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
lib/mocktail/imitates_type/makes_double/declares_dry_class/reconstructs_call.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| module Mocktail | ||
| class ReconstructsCall | ||
| def reconstruct(double:, call_binding:, default_args:, dry_class:, type:, method:, original_method:, signature:) | ||
| Call.new( | ||
| singleton: false, | ||
| double: double, | ||
| original_type: type, | ||
| dry_type: dry_class, | ||
| method: method, | ||
| original_method: original_method, | ||
| args: args_for(signature, call_binding, default_args), | ||
| kwargs: kwargs_for(signature, call_binding, default_args), | ||
| block: call_binding.local_variable_get(signature.block_param || ::Mocktail::Signature::DEFAULT_BLOCK_PARAM) | ||
| ) | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def args_for(signature, call_binding, default_args) | ||
| arg_names, rest_name = non_default_args(signature.positional_params, default_args) | ||
|
|
||
| arg_values = arg_names.map { |p| call_binding.local_variable_get(p) } | ||
| rest_value = call_binding.local_variable_get(rest_name) if rest_name | ||
|
|
||
| arg_values + (rest_value || []) | ||
| end | ||
|
|
||
| def kwargs_for(signature, call_binding, default_args) | ||
| kwarg_names, kwrest_name = non_default_args(signature.keyword_params, default_args) | ||
|
|
||
| kwarg_values = kwarg_names.to_h { |p| [p, call_binding.local_variable_get(p)] } | ||
| kwrest_value = call_binding.local_variable_get(kwrest_name) if kwrest_name | ||
|
|
||
| kwarg_values.merge(kwrest_value || {}) | ||
| end | ||
|
|
||
| def non_default_args(params, default_args) | ||
| named_args = params.allowed | ||
| .reject { |p| default_args&.key?(p) } | ||
| rest_arg = if params.rest && !default_args&.key?(params.rest) | ||
| params.rest | ||
| end | ||
|
|
||
| [named_args, rest_arg] | ||
| end | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| module Mocktail | ||
| class StringifiesMethodSignature | ||
| def stringify(signature) | ||
| positional_params = positional(signature) | ||
| keyword_params = keyword(signature) | ||
| block_param = block(signature) | ||
|
|
||
| "(#{[positional_params, keyword_params, block_param].compact.join(", ")})" | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def positional(signature) | ||
| params = signature.positional_params.all.map do |name| | ||
| if signature.positional_params.allowed.include?(name) | ||
| "#{name} = ((__mocktail_default_args ||= {})[:#{name}] = nil)" | ||
| elsif signature.positional_params.rest == name | ||
| "*#{(name == :*) ? Signature::DEFAULT_REST_ARGS : name}" | ||
| end | ||
| end.compact | ||
|
|
||
| params.join(", ") if params.any? | ||
| end | ||
|
|
||
| def keyword(signature) | ||
| params = signature.keyword_params.all.map do |name| | ||
| if signature.keyword_params.allowed.include?(name) | ||
| "#{name}: ((__mocktail_default_args ||= {})[:#{name}] = nil)" | ||
| elsif signature.keyword_params.rest == name | ||
| "**#{(name == :**) ? Signature::DEFAULT_REST_KWARGS : name}" | ||
| end | ||
| end.compact | ||
|
|
||
| params.join(", ") if params.any? | ||
| end | ||
|
|
||
| def block(signature) | ||
| if signature.block_param && signature.block_param != :& | ||
| "&#{signature.block_param}" | ||
| else | ||
| "&#{Signature::DEFAULT_BLOCK_PARAM}" | ||
| end | ||
| end | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| require "test_helper" | ||
|
|
||
| class KwargsVsOptionsHashTest < Minitest::Test | ||
| include Mocktail::DSL | ||
|
|
||
| class Charity | ||
| def donate(amount:) | ||
| raise "Unimplemented" | ||
| end | ||
|
|
||
| def give(opts) | ||
| raise "Unimplemented" | ||
| end | ||
| end | ||
|
|
||
| def test_handles_kwargs | ||
| aclu = Mocktail.of(Charity) | ||
|
|
||
| stubs { |m| aclu.donate(amount: m.numeric) }.with { :receipt } | ||
|
|
||
| assert_equal :receipt, aclu.donate(amount: 100) | ||
| assert_nil aclu.donate(amount: "money?") | ||
| end | ||
|
|
||
| def test_handles_options_hashes | ||
| wbc = Mocktail.of(Charity) | ||
|
|
||
| stubs { wbc.give(to: "poor") }.with { :stringy_thanks } | ||
| stubs { wbc.give({to: :poor}) }.with { :symbol_thanks } | ||
|
|
||
| assert_equal :stringy_thanks, wbc.give(to: "poor") | ||
| assert_equal :stringy_thanks, wbc.give({to: "poor"}) | ||
| assert_equal :symbol_thanks, wbc.give(to: :poor) | ||
| assert_equal :symbol_thanks, wbc.give({to: :poor}) | ||
| end | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
test/unit/imitates_type/makes_double/declares_dry_class_test.rb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| require "test_helper" | ||
|
|
||
| module Mocktail | ||
| class DeclaresDryClassTest < Minitest::Test | ||
| include Mocktail::DSL | ||
|
|
||
| def setup | ||
| @subject = DeclaresDryClass.new | ||
| end | ||
|
|
||
| class Fib | ||
| def lie(truth, lies:) | ||
| end | ||
| end | ||
|
|
||
| def test_calls_handle_dry_call_with_what_we_want | ||
| fake_fib_class = @subject.declare(Fib, [:lie]) | ||
searls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| fake_fib = fake_fib_class.new | ||
| handles_dry_call = Mocktail.of_next(HandlesDryCall) | ||
|
|
||
| fake_fib.lie("truth", lies: "lies") | ||
|
|
||
| verify { | ||
| handles_dry_call.handle(Call.new( | ||
| singleton: false, | ||
| double: fake_fib, | ||
| original_type: Fib, | ||
| dry_type: fake_fib_class, | ||
| method: :lie, | ||
| original_method: Fib.instance_method(:lie), | ||
| args: ["truth"], | ||
| kwargs: {lies: "lies"}, | ||
| block: nil | ||
| )) | ||
| } | ||
| end | ||
|
|
||
| class ExtremelyUnfortunateArgNames | ||
| def welp(binding, type, dry_class, method, signature) | ||
| end | ||
| end | ||
|
|
||
| def test_handles_args_with_unfortunate_names | ||
| fake_class = @subject.declare(ExtremelyUnfortunateArgNames, [:welp]) | ||
| fake = fake_class.new | ||
| handles_dry_call = Mocktail.of_next(HandlesDryCall) | ||
|
|
||
| fake.welp(:a_binding, :a_type, :a_dry_class, :a_method, :a_signature) | ||
|
|
||
| verify { | ||
| handles_dry_call.handle(Call.new( | ||
| singleton: false, | ||
| double: fake, | ||
| original_type: ExtremelyUnfortunateArgNames, | ||
| dry_type: fake_class, | ||
| method: :welp, | ||
| original_method: ExtremelyUnfortunateArgNames.instance_method(:welp), | ||
| args: [:a_binding, :a_type, :a_dry_class, :a_method, :a_signature], | ||
| kwargs: {}, | ||
| block: nil | ||
| )) | ||
| } | ||
| end | ||
| end | ||
| end | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.