| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Those are assertions that I really do miss from the standard
`ActiveSupport::TestCase`. Think of those as a more general version of
`assert_difference` and `assert_no_difference` (those can be implemented
by assert_changes, should this change be accepted).
Why do we need those? They are useful when you want to check a
side-effect of an operation. `assert_difference` do cover a really
common case, but we `assert_changes` gives us more control. Having a
global error flag? You can test it easily with `assert_changes`. In
fact, you can be really specific about the initial state and the
terminal one.
```ruby
error = Error.new(:bad)
assert_changes -> { Error.current }, from: nil, to: error do
expected_bad_operation
end
```
`assert_changes` follows `assert_difference` and a string can be given
for evaluation as well.
```ruby
error = Error.new(:bad)
assert_changes 'Error.current', from: nil, to: error do
expected_bad_operation
end
```
Check out the test cases if you wanna see more examples.
:beers:
|
| |
|
|
|
|
|
|
| |
This test was added to protect the test suite from our mistakes but now
it is failing because bundler does add duplicated libs in the load path
by design (if the repository has more than one gem)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|\
| |
| | |
Pathname might not be always initialized.
|
| |
| |
| |
| | |
Require 'pathname' explicitly
|
|\ \
| | |
| | | |
`travel/travel_to` travel time helpers, now raise on nested calls
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
as this can lead to confusing time stubbing.
Instead of:
travel_to 2.days.from_now do
# 2 days from today
travel_to 3.days.from_now do
# 5 days from today
end
end
preferred way to achieve above is:
travel_to 2.days.from_now
# 2 days from today
travel_back
travel_to 5.days.from_now
# 5 days from today
Closes #24690
Fixes #24689
|
|\ \ \
| | | |
| | | | |
Dry downloader
|
| | | | |
|
| | |/
| |/| |
|
|/ /
| |
| |
| | |
Require 'pathname' explicitly
|
|/ |
|
|
|
|
|
|
| |
KeyGenerator is used in other contexts, and we cannot change its
output... even if it does accidentally default to generating excess key
material for our primary internal usage.
|
|
|
|
|
|
|
|
|
|
| |
accept key lengths of 128, 192 or 256-bit, whereas currently we were providing twice the acceptable value.
ruby < 2.4 allowed accepting these values, as extra key bits were ignored. Since https://github.com/ruby/ruby/commit/ce635262f53b760284d56bb1027baebaaec175d1 this now has a strict checking on key length.
Default to key length 32 bytes, to match the compatible length for aes-256-cbc
Fixes #25185
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When the Pathname object is converted as JSON,
it should be a string that means itself.
Expected:
```
>> Pathname.new('/path/to/somewhere.txt').as_json
"/path/to/somewhere.txt"
```
Actual:
```
>> Pathname.new('/path/to/somewhere.txt').as_json
{"path"=>"/path/to/somewhere.txt"}
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When the URI object is converted as JSON,
it is expected that it is a string that means its URI.
Expected:
```
>> URI.parse('http://example.com').as_json
"http://example.com"
```
Actual:
```
>> URI.parse('http://example.com').as_json
{"scheme"=>"http",
"user"=>nil,
"password"=>nil,
"host"=>"example.com",
"port"=>80,
"path"=>"",
"query"=>nil,
"opaque"=>nil,
"fragment"=>nil,
"parser"=>
{"regexp"=>
{"SCHEME"=>"(?-mix:\\A[A-Za-z][A-Za-z0-9+\\-.]*\\z)",
"USERINFO"=>"(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=A-Z_a-z~])*\\z)",
"HOST"=>
"(?-mix:\\A(?:(?<IP-literal>\\[(?:(?<IPv6address>(?:\\h{1,4}:){6}(?<ls32>\\h{1,4}:\\h{1,4}|(?<IPv4address>(?<dec-octet>[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5]|\\d)\\.\\g<dec-octet>\\.\\g<dec-octet>\\.\\g<dec-octet>))|::(?:\\h{1,4}:){5}\\g<ls32>|\\h{,4}::(?:\\h{1,4}:){4}\\g<ls32>|(?:(?:\\h{1,4}:)?\\h{1,4})?::(?:\\h{1,4}:){3}\\g<ls32>|(?:(?:\\h{1,4}:){,2}\\h{1,4})?::(?:\\h{1,4}:){2}\\g<ls32>|(?:(?:\\h{1,4}:){,3}\\h{1,4})?::\\h{1,4}:\\g<ls32>|(?:(?:\\h{1,4}:){,4}\\h{1,4})?::\\g<ls32>|(?:(?:\\h{1,4}:){,5}\\h{1,4})?::\\h{1,4}|(?:(?:\\h{1,4}:){,6}\\h{1,4})?::)|(?<IPvFuture>v\\h+\\.[!$&-.0-;=A-Z_a-z~]+))\\])|\\g<IPv4address>|(?<reg-name>(?:%\\h\\h|[!$&-.0-9;=A-Z_a-z~])*))\\z)",
"ABS_PATH"=>
"(?-mix:\\A\\/(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])*(?:\\/(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])*)*\\z)",
"REL_PATH"=>
"(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])+(?:\\/(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~])*)*\\z)",
"QUERY"=>"(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~\\/?])*\\z)",
"FRAGMENT"=>"(?-mix:\\A(?:%\\h\\h|[!$&-.0-;=@-Z_a-z~\\/?])*\\z)",
"OPAQUE"=>"(?-mix:\\A(?:[^\\/].*)?\\z)",
"PORT"=>
"(?-mix:\\A[\\x09\\x0a\\x0c\\x0d ]*\\d*[\\x09\\x0a\\x0c\\x0d ]*\\z)"}}}
```
|
|\
| |
| |
| | |
Use correct timezone when parsing date in json
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Fixes https://github.com/rails/rails/issues/22171
Time specified in ISO 8601 format without `Z` should be considered as local
time, yet until now it was treated as UTC.
This commit fixes problem by parsing time using timezone specified in
application config.
The downside of this solution is performance hit (`Time.zone.parse` is ~ 1.6x
slower than `Time.parse`), so maybe there's a better solution.
|
|\ \
| | |
| | |
| | |
| | | |
schneems/schneems/evented-file-boot-at-check-time-master
EventedFileUpdateChecker boots once per process
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Pretty proud of this. We are testing distributed processes synchronized via pipes which makes it deterministic. Pretty cool.
We boot a listener in the parent process we then fork. Before we touch the file we verify the fork is booted using pipes. Then the parent process will touch the file while the fork waits on a pipe. Once the parent process signals that the file has been touched we continue inside of the fork.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
We need one file checker booted per process as talked about in #24990. Before we do a check to see if any updates have been registered by the listener we first check to make sure that the current process has booted a listener.
We are intentionally not starting a listener when the checker is created. This way we can avoid #25259 in which puma warns of multiple threads created before fork. As written the listener for each process will be invoked by the `ActionDispatch::Executor` middleware when the `updated?` method is called. This is the first middleware on the stack and will be invoked before application code is read into memory.
The downside of this approach is that the API is a little less obvious. I.e. that you have to call `updated?` to get the listener to start is not intuitive. We could make `boot!` not private if we want to make the API a little nicer. Alternatively we could boot when the checker is initialized however this reintroduces the puma threads warning, and also means that in cases of `rails server` or when using `preload!` that we have extra threads notifying of changes on a process that we don't care about.
[close #24990] [close #25259]
|
| | | |
|
| | | |
|
| | | |
|
| | | |
|
| | | |
|
|/ /
| |
| |
| |
| |
| |
| | |
Make it clear what should be returned when no changes were made to the
hash.
{ c: true }.compact! # => nil
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
We are currently using `%e` which adds a space before the result if the
digit is a single number. This leads to strings like `February 2, 2016`
which is undesireable. I've opted to replace with 0 padding instead of
removing the padding entirely, to preserve compatibility for those
relying on the fact that the width is constant, and to be consistent
with time formatting.
Fixes #25251.
|
| | |
|
| | |
|
| |
| |
| |
| | |
And make sure that it doesn't even try to call the method in the target.
|
|\ \
| | |
| | |
| | | |
Introduce Module#delegate_missing_to
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
When building decorators, a common pattern may emerge:
class Partition
def initialize(first_event)
@events = [ first_event ]
end
def people
if @events.first.detail.people.any?
@events.collect { |e| Array(e.detail.people) }.flatten.uniq
else
@events.collect(&:creator).uniq
end
end
private
def respond_to_missing?(name, include_private = false)
@events.respond_to?(name, include_private)
end
def method_missing(method, *args, &block)
@events.send(method, *args, &block)
end
end
With `Module#delegate_missing_to`, the above is condensed to:
class Partition
delegate_missing_to :@events
def initialize(first_event)
@events = [ first_event ]
end
def people
if @events.first.detail.people.any?
@events.collect { |e| Array(e.detail.people) }.flatten.uniq
else
@events.collect(&:creator).uniq
end
end
end
David suggested it in #23824.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
This reverts commit 28492204ee59a5aca2f3bc7b161d45724552686d.
Reason: `suppress` without an argument doesn't actually tell what is
supressing. Also, it can be confused with ActiveRecord::Base#suppress.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
* Add default exceptions affected by suppress
suppress { do_something_that_might_fail }
# instead of
begin
do_something_that_might_fail
rescue
end
# or
do_something_that_might_fail rescue nil
* Do not add default exceptions list constant
[Rafael Mendonça França + Alexey Zapparov]
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
* Hash#from_xml works with frozen strings
Fixes #24647
* Fix rexml engine test
[Marek Kirejczyk + Rafael Mendonça França]
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
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.
|
|\ \ \
| | | |
| | | |
| | | | |
Fixes Inflector#titleize to work with SafeBuffer
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The way Inflector#titleize was implemented did not work properly when
called on a SafeBuffer object. Using the global `$&` variable in the
gsub resulted in calling capitalize on a nil object for reasons I still
do not fully understand. Removing the UNSAFE_STRING_METHODS override for
the gsub method in SafeBuffer "fixed" the bug but is obviously
unacceptable.
An example of this is very easy to see in rails console:
ActiveSupport::SafeBuffer.new("my test").titleize
> NoMethodError: undefined method `capitalize' for nil:NilClass
Using the non global version of gsub with a |match| arg passed to the
block fixes the problem. Again I do not quite understand why. I noticed
that other parts of Inflector were already using the standard block arg
version of gsub so I don't think it should be a problem to convert this
method to using it as well.
|
|\ \ \ \
| | | | |
| | | | | |
Introduce Date#all_day
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Useful for queries like:
Item.where(created_at: Date.current.all_day)
There was already a Time#all_day with the same behaviour, but for
queries like the above, Date is more convenient.
|
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | |
| | | | | |
Follows the same pattern as controllers and jobs. Exceptions raised in
delivery jobs (enqueued by `#deliver_later`) are also delegated to the
mailer's rescue_from handlers, so you can handle the DeserializationError
raised by delivery jobs:
```ruby
class MyMailer < ApplicationMailer
rescue_from ActiveJob::DeserializationError do
…
end
```
ActiveSupport::Rescuable polish:
* Add the `rescue_with_handler` class method so exceptions may be
handled at the class level without requiring an instance.
* Rationalize `exception.cause` handling. If no handler matches the
exception, fall back to the handler that matches its cause.
* Handle exceptions raised elsewhere. Pass `object: …` to execute
the `rescue_from` handler (e.g. a method call or a block to
instance_exec) against a different object. Defaults to `self`.
|
| | | | | |
|
|/ / / / |
|
| | | |
| | | |
| | | |
| | | |
| | | | |
Add to the matrix of Travis tests an entry that runs the Active Support
tests when `ActiveSupport.to_time_preserves_timezone = true`.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
These two tests are explicitly testing that to_time is returning times
with the sytem timezone's UTC offset, therefore they will fail when
running them with `ActiveSupport.to_time_preserves_timezone = true`.
|
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | | |
The to_yaml method is undefined when running the test as:
$ ruby -I lib:test test/core_ext/string_ext_test.rb
Doesn't fail when running rake test:isolated presumably because
something else has required 'yaml' already.
|
| | | |
| | | |
| | | |
| | | | |
[ci skip]
|