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

After upgrade from 4.0.1 to 5.3.1 option[:vague] raises error #126

Merged
merged 11 commits into from
Aug 18, 2021

Conversation

mozcomp
Copy link
Contributor

@mozcomp mozcomp commented Jun 18, 2021

In relation to Issue: #125

Following further tests as to cause of the issue, it relates to the interaction between the optional 3rd argument for "include seconds" and the 4th argument "options". If the 3rd argument was supplied (true/false), then the code worked as expected.
This was included and passed in spec tests.
Adding same specs, but without the optional "include_seconds" argument, gave a series of fails as found in the Issue raised.

My solution may not be acceptable, as I'm changing the arguments supplied, but by testing for a valid true/false of the "include_seconds" argument, and if "options" are nil, then swap the contents.

Once this is done, with the minor tweak of excluding the vague option before passing to the ActiveSupport support version, the code now passes all tests.

@mozcomp mozcomp marked this pull request as ready for review June 18, 2021 01:35
@dblock
Copy link
Collaborator

dblock commented Jun 18, 2021

I think what we really want is a test calling ActionView time_ago_in_words(..., vague: true), that's the only external API. And it is documented as something that accepts include_seconds: true, but nothing else. Finally, in our README we don't even show examples of vague.

So... first question first, how do we want it to work?

@mozcomp
Copy link
Contributor Author

mozcomp commented Jun 18, 2021

On reading your comment about time_ago_in_words I realised I was getting the same error as @MSCAU but mine was coming from distance_of_time_in_words.

My PR had already skipped a step as to the cause of the problem.

You're correct there are no tests for time_ago_in_words(..., vague: true) but there are for distance_of_time_in_words(..., vague: true) and it's at this point that we get the error.

Our entry point for the error is helper.distance_of_time_in_words and it's here that the code chooses to call the original method aliased as _distance_of_time_in_words or the new DOTIW method.

Looking at the arguments to the method distance_of_time_in_words(from_time, to_time = 0, include_seconds_or_options = {}, options = {}) then at the DOTIW method, you'll see the expected handling of the arguments ...

  def distance_of_time_in_words(from_time, to_time = 0, include_seconds_or_options = {}, options = {})
    raise ArgumentError, "nil can't be converted to a Time value" if from_time.nil? || to_time.nil?
    if include_seconds_or_options.is_a?(Hash)
         options = include_seconds_or_options
     else
         options = options.dup
         options[:include_seconds] ||= !!include_seconds_or_options
      end

But this is done after we have supposedly made use of the vague option and called the original ActionView method.

However, if the include_seconds_or_options argument is the options hash, rather than the include_seconds true/false, two things happen

  1. the ActionView method ISN'T called because the vague option was in include_seconds_or_options not in options
  2. the vague option isn't excluded from the arguments passed to the DOTIW method as expected, so is then passed to the downstream to_sentence where it throws ArgumentError (Unknown key: :vague. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale)

My thoughts are that the argument handling that is done in the DOTIW method, should be moved/duplicated to the ActionView method.

Failing that make the include_seconds argument mandatory thereby avoiding the whole issue.

@dblock
Copy link
Collaborator

dblock commented Jun 18, 2021

Ok I’m with you @mozcomp.

Before we do this, … we inherited this mess … do you think it would be better to collapse these two arguments (include_seconds_or_options and options) into just options to match time_ago_in_words, and break backwards compatibility in a major version? I think that would fix the confusion once and for all and avoid edge cases. I’d vote to do that.

@mozcomp
Copy link
Contributor Author

mozcomp commented Jun 21, 2021

@dblock I'm torn, the non-intrusive fix is to copy the existing argument handling within the DOTIW method to the Actionview method, this would make it work as in the original version.

However, as you say, the cleaner solution would be to collapse these arguments into a single argument options.

My main problem with the latter - considering how long it has been since the change that broke the gem (about 12 months I think), there is obviously only a few people implementing the gem with the 3 argument vague option, so if you collapse the options, we might be breaking more than we're fixing.

I'm inclined to vote for the first option rather than the second.

having collapsed arguments, pass options as single hash
@dblock
Copy link
Collaborator

dblock commented Jun 21, 2021

@mozcomp Ok, I agree we should just fix the problem in the first place

The code looks good. We also need specs for when include_seconds_or_options = true/false here, right?

Please also update https://github.com/radar/distance_of_time_in_words/blob/master/CHANGELOG.md

@mozcomp
Copy link
Contributor Author

mozcomp commented Jun 22, 2021 via email

additional tests include/exclude seconds argument
@mozcomp
Copy link
Contributor Author

mozcomp commented Jul 1, 2021

Sorry so long getting back to this ...

Added specs to cover all the permutations of the seconds & vague arguments
Updated the readme to be more specific on both the above arguments.

Feel free to change all the above as these are all new for me to be contributing.

@dblock
Copy link
Collaborator

dblock commented Jul 4, 2021

Sorry so long getting back to this ...

Added specs to cover all the permutations of the seconds & vague arguments
Updated the readme to be more specific on both the above arguments.

Feel free to change all the above as these are all new for me to be contributing.

I think you forgot to push the code up here ;) Thank you!

@mozcomp
Copy link
Contributor Author

mozcomp commented Jul 4, 2021

That's a rookie error - done now.

@dblock
Copy link
Collaborator

dblock commented Jul 5, 2021

One more thing, please add a line to https://github.com/radar/distance_of_time_in_words/blob/master/CHANGELOG.md. I think this is good to go otherwise!

Copy link
Collaborator

@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.

One more thing I spotted.

if include_seconds_or_options.is_a?(Hash)
options = include_seconds_or_options
else
options[:include_seconds] ||= !!include_seconds_or_options
Copy link
Collaborator

Choose a reason for hiding this comment

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

This modifies the incoming hash, which is bad (TM). Do options = options.merge(...) here.

@mozcomp
Copy link
Contributor Author

mozcomp commented Jul 10, 2021

I think I have the arguments handling right, but I didn't like that the same code was being repeated for the two calls to the actionview methods, so moved it to a private method

Copy link
Collaborator

@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.

Some more nitpicks

CHANGELOG.md Show resolved Hide resolved
CHANGELOG.md Outdated
@@ -1,6 +1,6 @@
## 5.3.2 (Next)

* Your contribution here.
* [#126](https://github.com/radar/distance_of_time_in_words/pull/126): Fixes `#distance_of_time_in_words_to_now` with `vague: true` when supplied without include_seconds argument - [@mozcomp](https://github.com/mozcomp)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Quote include_seconds


private
def merge_options(include_seconds_or_options, options)
merged_options = options.dup
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems like it's doing more work than needed in all cases, duping and merging. This is simpler:

def merge_options(include_seconds_or_options, options)
  if include_seconds_or_options.is_a?(Hash)
    options.merge(include_seconds_or_options)
  else
    options.merge(include_seconds: !!include_seconds_or_options)
  end
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, newbie error, I thought you were making the change, not waiting for me to do it.
Change as suggested

@dblock
Copy link
Collaborator

dblock commented Aug 16, 2021

Thank you. See comments above, please make the minor changes to CHANGELOG, and I think this will be good to merge!

@@ -65,7 +65,8 @@ The third argument for this method is whether or not to include seconds. By defa
=> "1 year, and 1 second"
```

Yes this could just be merged into the options hash but I'm leaving it here to ensure "backwards-compatibility", because that's just an insanely radical thing to do. \m/
Yes this could just be merged into the options hash but I'm leaving it here to ensure "backwards-compatibility", because that's just an insanely radical thing to do.
Copy link
Collaborator

@dblock dblock Aug 16, 2021

Choose a reason for hiding this comment

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

I think you should put back the original author's \m/ here, keep the spirit of the project alive.

CHANGELOG.md Outdated
@@ -1,6 +1,7 @@
## 5.3.2 (Next)

- * Your contribution here.
* Your contribution here.
* [#126](https://github.com/radar/distance_of_time_in_words/pull/126): Fixes `#distance_of_time_in_words_to_now` with `vague: true` when supplied without `include_seconds` argument - [@mozcomp](https://github.com/mozcomp)
Copy link
Collaborator

Choose a reason for hiding this comment

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

You're missing a period at the end. A bot will complain.

@dblock dblock merged commit fec81b2 into radar:master Aug 18, 2021
@dblock
Copy link
Collaborator

dblock commented Nov 8, 2021

Release in 5.3.2

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.

2 participants