aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/test/core_ext/duration_test.rb
Commit message (Collapse)AuthorAgeFilesLines
* Add missing support for modulo operations on durationsSayan Chakraborty2017-07-281-13/+62
| | | | | | | | | | | Rails 5.1 introduce an `ActiveSupport::Duration::Scalar` class as a wrapper around a numeric value as a way of ensuring a duration was the outcome of an expression. However the implementation was missing support for modulo operations. This commit adds support for those operations and should result in a duration being returned from expressions involving them. Fixes #29603 and #29743.
* Fix division where a duration is the denominatorAndrew White2017-07-271-10/+14
| | | | | | | | | PR #29163 introduced a change in behavior when a duration was the denominator in a calculation - this was incorrect as dividing by a duration should always return a `Numeric`. The behavior of previous versions of Rails has been restored. Fixes #29592.
* [Active Support] `rubocop -a --only Layout/EmptyLineAfterMagicComment`Koichi ITO2017-07-111-0/+1
|
* Use frozen-string-literal in ActiveSupportKir Shatrov2017-07-091-0/+1
|
* Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"Matthew Draper2017-07-021-1/+0
| | | | | This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
* Enforce frozen string in RubocopKir Shatrov2017-07-011-0/+1
|
* prepare for Minitest 6utilum2017-06-201-1/+1
|
* Fix implicit calculations with scalars and durationsAndrew White2017-05-201-0/+34
| | | | | | | | | | | | | | | | | | | | | Previously calculations where the scalar is first would be converted to a duration of seconds but this causes issues with dates being converted to times, e.g: Time.zone = "Beijing" # => Asia/Shanghai date = Date.civil(2017, 5, 20) # => Mon, 20 May 2017 2 * 1.day # => 172800 seconds date + 2 * 1.day # => Mon, 22 May 2017 00:00:00 CST +08:00 Now the `ActiveSupport::Duration::Scalar` calculation methods will try to maintain the part structure of the duration where possible, e.g: Time.zone = "Beijing" # => Asia/Shanghai date = Date.civil(2017, 5, 20) # => Mon, 20 May 2017 2 * 1.day # => 2 days date + 2 * 1.day # => Mon, 22 May 2017 Fixes #29160, #28970.
* Fix test warningsAndrew White2017-03-161-5/+5
|
* Remove implicit coercion deprecation of durationsAndrew White2017-03-151-25/+117
| | | | | | | | | | | | | | | | In #28204 we deprecated implicit conversion of durations to a numeric which represented the number of seconds in the duration because of unwanted side effects with calculations on durations and dates. This unfortunately had the side effect of forcing a explicit cast when configuring third-party libraries like expiration in Redis, e.g: redis.expire("foo", 5.minutes) To work around this we've removed the deprecation and added a private class that wraps the numeric and can perform calculation involving durations and ensure that they remain a duration irrespective of the order of operations.
* Deprecate implicit coercion of `ActiveSupport::Duration`Andrew White2017-03-021-3/+55
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently `ActiveSupport::Duration` implicitly converts to a seconds value when used in a calculation except for the explicit examples of addition and subtraction where the duration is the receiver, e.g: >> 2 * 1.day => 172800 This results in lots of confusion especially when using durations with dates because adding/subtracting a value from a date treats integers as a day and not a second, e.g: >> Date.today => Wed, 01 Mar 2017 >> Date.today + 2 * 1.day => Mon, 10 Apr 2490 To fix this we're implementing `coerce` so that we can provide a deprecation warning with the intent of removing the implicit coercion in Rails 5.2, e.g: >> 2 * 1.day DEPRECATION WARNING: Implicit coercion of ActiveSupport::Duration to a Numeric is deprecated and will raise a TypeError in Rails 5.2. => 172800 In Rails 5.2 it will raise `TypeError`, e.g: >> 2 * 1.day TypeError: ActiveSupport::Duration can't be coerced into Integer This is the same behavior as with other types in Ruby, e.g: >> 2 * "foo" TypeError: String can't be coerced into Integer >> "foo" * 2 => "foofoo" As part of this deprecation add `*` and `/` methods to `AS::Duration` so that calculations that keep the duration as the receiver work correctly whether the final receiver is a `Date` or `Time`, e.g: >> Date.today => Wed, 01 Mar 2017 >> Date.today + 1.day * 2 => Fri, 03 Mar 2017 Fixes #27457.
* Add Duration#before and #after as aliases for #ago and #sinceNick Johnstone2017-02-261-0/+13
| | | | | | | | | | | | | | It's common in test cases at my job to have code like this: let(:today) { customer_start_date + 2.weeks } let(:earlier_date) { today - 5.days } With this change, we can instead write let(:today) { 2.weeks.after(customer_start_date) } let(:earlier_date) { 5.days.before(today) } Closes #27721
* Add additional tests for #27610Andrew White2017-01-121-1/+38
| | | | | | | Since 1.month no longer equals 30.days add some tests to ensure that addition maintains the same day in the month or is the last day in the month if the month has less days than the current day. Also add a test for the behaviour of 12.months == 1.year.
* Fix inconsistent results when parsing large durations and constructing ↵Andrey Novikov2017-01-091-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | durations from code ActiveSupport::Duration.parse('P3Y') == 3.years # It should be true Duration parsing made independent from any moment of time: Fixed length in seconds is assigned to each duration part during parsing. Changed duration of months and years in seconds to more accurate and logical: 1. The value of 365.2425 days in Gregorian year is more accurate as it accounts for every 400th non-leap year. 2. Month's length is bound to year's duration, which makes sensible comparisons like `12.months == 1.year` to be `true` and nonsensical ones like `30.days == 1.month` to be `false`. Calculations on times and dates with durations shouldn't be affected as duration's numeric value isn't used in calculations, only parts are used. Methods on `Numeric` like `2.days` now use these predefined durations to avoid duplicating of duration constants through the codebase and eliminate creation of intermediate durations.
* assert_equal takes expectation firstAkira Matsuda2016-12-261-2/+2
|
* Fix Fixnum deprecated warning in Ruby 2.4+utilum2016-12-161-1/+1
|
* Treat combined durations as a single unitSean Griffin2016-11-291-0/+11
| | | | | | | | | | | | Prior to this commit, `3.months - 3.months` would result in a duration that has the "parts" of `[[:months, 3], [:months, -3]]`. This would mean that it was subtly different than `2.months - 2.months`. When applied to a time, the date might actually change if the resulting day doesn't exist however many months in the future, even though in both cases we just wanted to add `0`, which should always be an identity operation. With this change, we now store the parts as a hash, so `3.months - 3.months` is simply stored as `{ months: 0 }`.
* Tweaking some test data due to sprintf behavior change in 2.4Akira Matsuda2016-11-051-5/+5
| | | | | | | | 2.3: sprintf('%0.1f', 5.55) #=> "5.5" 2.4: sprintf('%0.1f', 5.55) #=> "5.6" see: https://github.com/ruby/ruby/commit/6ed8c79ddb11ccfb580bb0a22b22cc1362250255 and https://github.com/ruby/ruby/commit/295f60b94d5ff6551fab7c55e18d1ffa6a4cf7e3
* Ensure duration parsing is consistent across DST changesAndrew White2016-10-311-0/+31
| | | | | | | | | | | | | | | | | | Previously `ActiveSupport::Duration.parse` used `Time.current` and `Time#advance` to calculate the number of seconds in the duration from an arbitrary collection of parts. However as `advance` tries to be consistent across DST boundaries this meant that either the duration was shorter or longer depending on the time of year. This was fixed by using an absolute reference point in UTC which isn't subject to DST transitions. An arbitrary date of Jan 1st, 2000 was chosen for no other reason that it seemed appropriate. Additionally, duration parsing should now be marginally faster as we are no longer creating instances of `ActiveSupport::TimeWithZone` every time we parse a duration string. Fixes #26941.
* Add more rubocop rules about whitespacesRafael Mendonça França2016-10-291-9/+9
|
* RuboCop is 100% green :tada:Xavier Noria2016-09-021-1/+5
|
* Add three new rubocop rulesRafael Mendonça França2016-08-161-1/+1
| | | | | | | | Style/SpaceBeforeBlockBraces Style/SpaceInsideBlockBraces Style/SpaceInsideHashLiteralBraces Fix all violations in the repository.
* remove redundant curlies from hash argumentsXavier Noria2016-08-061-1/+1
|
* applies new string literal convention in activesupport/testXavier Noria2016-08-061-53/+53
| | | | | The current code base is not uniform. After some discussion, we have chosen to go with double quotes by default.
* AS::Duration should serialize empty values correctly. (#25656)Paul Sadauskas2016-07-111-0/+1
| | | | | | | | | | | | | The current implementation serializes zero-length durations incorrectly (it serializes as `"-P"`), and cannot un-serialize itself: ``` [1] pry(main)> ActiveSupport::Duration.parse(0.minutes.iso8601) ActiveSupport::Duration::ISO8601Parser::ParsingError: Invalid ISO 8601 duration: "-P" is empty duration from /Users/rando/.gem/ruby/2.3.1/gems/activesupport-5.0.0/lib/active_support/duration/iso8601_parser.rb:96:in `raise_parsing_error' ``` Postgres empty intervals are serialized as `"PT0S"`, which is also parseable by the Duration deserializer, so I've modified the `ISO8601Serializer` to do the same. Additionally, the `#normalize` function returned a negative sign if `parts` was blank (all zero). Even though this fix does not rely on the sign, I've gone ahead and corrected that, too, in case a future refactoring of `#serialize` uses it.
* Support for unified Integer class in Ruby 2.4+Jeremy Daer2016-05-181-1/+1
| | | | | | | | Ruby 2.4 unifies Fixnum and Bignum into Integer: https://bugs.ruby-lang.org/issues/12005 * Forward compat with new unified Integer class in Ruby 2.4+. * Backward compat with separate Fixnum/Bignum in Ruby 2.2 & 2.3. * Drops needless Fixnum distinction in docs, preferring Integer.
* Change 1.week to create 1 week durations instead of 7 days durations.Andrey Novikov2016-04-281-2/+12
| | | | This is just to remove astonishment from getting `3600 seconds` from typing `1.hour`.
* Revert "Change 1.week to create 1 week durations instead of 7 days durations."Jeremy Daer2016-04-271-3/+2
| | | | | | Regression: adding minutes/hours to a time would change its time zone This reverts commit 1bf9fe75a6473cb7501cae544cab772713e68cef.
* `ActiveSupport::Duration` supports ISO8601 formatting and parsing.Arnau Siches, Andrey Novikov2016-04-181-0/+85
| | | | | | | | | | | | | | ```ruby ActiveSupport::Duration.parse('P3Y6M4DT12H30M5S') (3.years + 3.days).iso8601 ``` Inspired by Arnau Siches' [ISO8601 gem](https://github.com/arnau/ISO8601/) and rewritten by Andrey Novikov with suggestions from Andrew White. Test data from the ISO8601 gem redistributed under MIT license. (Will be used to support the PostgreSQL interval data type.)
* Change 1.week to create 1 week durations instead of 7 days durations.Andrey Novikov2016-04-181-2/+3
| | | | This is just to remove astonishment from getting `3600 seconds` from typing `1.hour`.
* Removed mocha stubbing in active_supportRonak Jangir2015-06-071-16/+18
|
* Removing :en in favor of I18n.default_locale in duration#inspectDominik Masur2015-01-121-0/+9
| | | | | | | | | | | | | | | | | Hi there, i have an app without english as available locale. So i got an error when we try to inspect something like 1.day. This is done automatically when we use the dalli cache. I would like to change the :en to ::I18n.default_locale to be sure that this is always constant and is an available locale. Tests are all green with this change. Calculating ------------------------------------- :locale => :en 2.024k i/100ms :locale => ::I18n.default_locale 2.236k i/100ms ------------------------------------------------- :locale => :en 25.758k (±26.3%) i/s - 117.392k :locale => ::I18n.default_locale 26.311k (±18.1%) i/s - 127.452k
* Merge pull request #17493 from petewest/duration-comparableAaron Patterson2014-11-071-0/+12
|\ | | | | Delegate comparison operator to value
| * Delegate comparison operator to valuePeter West2014-11-031-0/+12
| |
* | Removed the unused require of proxy_object and test related to itPrathamesh Sonpatki2014-11-051-1/+0
|/ | | | | - Reference : https://github.com/rails/rails/pull/17493#issuecomment-61739359 - Duration stopped inheriting from ProxyObject in https://github.com/rails/rails/pull/16574
* define hash on durationlsylvester2014-10-031-0/+4
|
* Fix another false assertionsYuki Nishijima2014-09-211-2/+2
| | | | | | | | | | | | * The assertions in AS::Duration don't actually assert. * The assertion in Railtie will pass even when `eager_load_namespaces` doesn't include `AppTemplate::Application` if `Rails.application` is truthy. For more details, see here: * https://github.com/rails/rails/pull/16998 * https://github.com/rails/rails/pull/17000
* Merge pull request #11794 from yoazt/duration-eqlRafael Mendonça França2014-09-171-0/+4
|\ | | | | | | | | | | | | | | | | Added method `#eql?` to `ActiveSupport::Duration`, in addition to `#==`. Conflicts: activesupport/CHANGELOG.md activesupport/lib/active_support/duration.rb activesupport/test/core_ext/duration_test.rb
| * Added method `#eql?` to `ActiveSupport::Duration`, in addition to `#==`.Joost Lubach2013-08-071-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | Currently, the following returns `false`, contrary to expectation: 1.minute.eql?(1.minute) Adding method `#eql?` will make this behave like expected. Method `#eql?` is just a bit stricter than `#==`, as it checks whether the argument is also a uration. Their parts may be different though. 1.minute.eql?(60.seconds) # => true 1.minute.eql?(60) # => false
* | add implementation of respond_to? for ActiveSupport::Durationlsylvester2014-09-151-0/+9
| |
* | Skip #eql? tests on Rubinius for AS::DurationRobin Dupret2014-08-241-0/+3
| | | | | | | | | | | | | | | | | | Since Rubinius is relying on #instance_of? for its definition of #eql? (http://git.io/MtmbbA) but ActiveSupport::Duration should behave like is_a? it returns true with `Fixnum`. Thus, for the moment, the last assertion is failing so we have to skip this test.
* | Follow-up to #16560Robin Dupret2014-08-241-5/+6
| | | | | | | | | | | | | | For the sake of backward-compatibility, we need to make #instance_of? return true for Fixnum. On the other hand, the method should still give true for ActiveSupport::Duration itself which was not the case before.
* | Define the Duration#instance_of? methodRobin Dupret2014-08-181-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | Since Duration is extending from ProxyObject which extends itself from BasicObject, the Duration object doesn't respond to the #instance_of? method. Thus, the #method_missing hook get triggered, delegating the method to its `value` attribute. However, Rubinius' #eql? definition relies on #instance_of?, thus this will equal to true with a Fixnum (since its `value` attribute is a Fixnum) while it should not. The previous behavior was wrong anyway, no matter the implementation.
* | missing activesupport test coverageEugene Gilburg2014-07-191-0/+4
| |
* | Extract out with_env_tz helper method.Zuhao Wan2014-06-181-8/+3
| | | | | | | | | | It’s used at so many places that extracting it out into a helper file is worth doing.
* | Fixed problem where `1.day.eql?(1.day)` is falseEmily Dobervich2014-04-081-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fixes: 1.second.eql?(1.second) #=> false The new `eql?` requires that `other` is an `ActiveSupport::Duration`. This requirement makes `ActiveSupport::Duration`'s behavior consistent with other numeric types in Ruby. 1.eql?(1.0) #=> false 1.0.eql?(1) #=> false 1.second.eql?(1) #=> false (was true) 1.eql?(1.second) #=> false { 1 => "foo", 1.0 => "bar" } #=> { 1 => "foo", 1.0 => "bar" } { 1 => "foo", 1.second => "bar" } # now => { 1 => "foo", 1.second => "bar" } # was => { 1 => "bar" } And though the behavior here hasn't changed, for reference: 1 == 1.0 #=> true 1.0 == 1 #=> true 1 == 1.second #=> true 1.second == 1 #=> true
* | Prefer assert_raise instead of flunk + rescue to test for exceptionsCarlos Antonio da Silva2013-12-191-5/+3
| | | | | | | | | | | | Change most tests to make use of assert_raise returning the raised exception rather than relying on a combination of flunk + rescue to check for exception types/messages.
* | Fix segmentation fault in Ruby 2.0.0-p353.Dmitriy Kiriyenko2013-11-301-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | In Ruby 2.0.0-p353 there was a [commit](https://github.com/ruby/ruby/commit/66915c507777c5e3a978fa73de25db763efd9206) that switched case matching from actual sending `===` method to magic lookup, that does not see it in `method_missing`. It's hard to predict how exactly and when exactly this bug will be solved so here I suggest a solution of defining it in Duration directly. In Ruby 2.0.0-p353 without the added fix added test crashes to segmentation fault.
* | Deprecated Numeric#{ago,until,since,from_now}Godfrey Chan2013-11-261-4/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The user is expected to explicitly convert the value into an AS::Duration, i.e. `5.ago` => `5.seconds.ago` This will help to catch subtle bugs like: def recent?(days = 3) self.created_at >= days.ago end The above code would check if the model is created within the last 3 **seconds**. In the future, `Numeric#{ago,until,since,from_now}` should be removed completely, or throw some sort of errors to indicate there are no implicit conversion from `Numeric` to `AS::Duration`. Also fixed & refactor the test cases for Numeric#{ago,since} and AS::Duration#{ago,since}. The original test case had the assertion flipped and the purpose of the test wasn't very clear.
* | Revert "Merge pull request #12480 from iwiznia/master"Jeremy Kemper2013-10-111-15/+0
| | | | | | | | | | This reverts commit e5f5a838b96a362534d9bb60d02334439ed9784c, reversing changes made to d7567f3290a50952494e9213556a1f283a6cf3a0.