Skip to content
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

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants