Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Fix attribute translator setter #2375

Merged
merged 1 commit into from
Dec 21, 2023

Conversation

Jell
Copy link
Contributor

@Jell Jell commented Nov 20, 2023

This was simply not working before. Doesn't seem like there are any unit tests for this class, so I haven't added new ones, but might be worth considering.

Copy link
Member

@dblock dblock left a comment

Choose a reason for hiding this comment

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

Thanks, and yes, please add a test / CHANGELOG.

@grape-bot
Copy link

grape-bot commented Nov 20, 2023

1 Warning
⚠️ There're library changes, but not tests. That's OK as long as you're refactoring existing code.

Generated by 🚫 Danger

@dblock
Copy link
Member

dblock commented Nov 20, 2023

Not sure if failed tests are related, but I suspect they are.

@ericproulx
Copy link
Contributor

ends_with? on symbol comes in 2.7 but we're still >= 2.6.
https://blog.saeloun.com/2019/12/09/ruby-2-7-added-symbol-start_with-and-symbol-end_with-method
@dblock I think we should consider deprecating 2.6. After all, rubocop dropped it and rubygems-update also. Might be a good time.

@dblock
Copy link
Member

dblock commented Dec 18, 2023

I am not against it.

@ericproulx
Copy link
Contributor

@Jell if you rebase your branch, all tests should pass.

@Jell Jell force-pushed the fix-attribute-translator-setter branch 2 times, most recently from e195beb to 2cbdb8b Compare December 20, 2023 13:05
@Jell
Copy link
Contributor Author

Jell commented Dec 20, 2023

@ericproulx @dblock I've rebased, added tests and a line in the changelog

@ericproulx
Copy link
Contributor

@dblock I thought I messed up my refactoring in 2019 but it always been like this since #1351. What @Jell did makes total sense but it changes the setter behavior. For instance,

describe "#header=" do
  subject { instance.header = 'new_value' }
  let(:instance) { Grape::Router::AttributeTranslator.new(header: 'value') }
  it "sets value for header" do
    expect do
      subject
      puts "to_h = #{instance.to_h}"
    end.to change(instance, :header).from('value').to('new_value')
  end
end
Grape::Router::AttributeTranslator
  #header=
to_h = {:header=>"value", "header="=>["new_value"]}
    sets value for header (FAILED - 1)

Failures:

  1) Grape::Router::AttributeTranslator#header= sets value for header
     Failure/Error:
       expect do
         subject
         puts "to_h = #{instance.to_h}"
       end.to change(instance, :header).from('value').to('new_value')
     
       expected `Grape::Router::AttributeTranslator#header` to have changed from "value" to "new_value", but did not change
     # ./spec/grape/router/attribute_translator_spec.rb:32:in `block (3 levels) in <top (required)>'

Finished in 0.0123 seconds (files took 0.28833 seconds to load)
1 example, 1 failure

On the other hand, I feel the setter methods aren't really used and everything is done through the initialize. For instance, removing the setter part in the method_missing and respond_to_missing? like this doesn't break any specs.

def method_missing(method_name, *args)
  return attributes[method_name] unless setter?(method_name[-1])

  super
end

def respond_to_missing?(method_name, _include_private = false)
  @attributes.key?(method_name)
end

Maybe we should consider removing the setter part and let the initialize do its work. After all, these attributes doesn't change after the APIs are compiled.

@Jell
Copy link
Contributor Author

Jell commented Dec 21, 2023

@ericproulx FYI the reason for me doing the PR in the first place is because I wanted to set some default headers for Swagger documentation purposes after the route was compiled, something along the lines of:

routes.each do |route|
  add_default_headers(route)
  add_default_response_codes(route)
end

and I had to do some workaround like:

  route.attributes.attributes[:headers] ||= {}
  route.attributes.attributes[:http_codes] ||= []

But I think it would also be OK if headers and http_codes where initialized with an empty collection?

@ericproulx
Copy link
Contributor

ericproulx commented Dec 21, 2023

@dblock #1348 your ruby bug has been fixed 3 years ago. Its been fix in ruby > =3.0 and the issue remains in 2.7 unfortunately.

CHANGELOG.md Outdated Show resolved Hide resolved
This was simply not working before.
@Jell Jell force-pushed the fix-attribute-translator-setter branch from 2cbdb8b to da31f80 Compare December 21, 2023 16:41
@Jell Jell requested a review from dblock December 21, 2023 16:58
@dblock
Copy link
Member

dblock commented Dec 21, 2023

Good work @Jell!

@dblock dblock merged commit 274d2bc into ruby-grape:master Dec 21, 2023
30 checks passed
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants