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

have_enqueued_job supports time object #2157

Merged
merged 1 commit into from Sep 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 9 additions & 1 deletion lib/rspec/rails/matchers/active_job.rb
Expand Up @@ -140,8 +140,9 @@ def job_match?(job)

def arguments_match?(job)
if @args.any?
args = serialize_and_deserialize_arguments(@args)
deserialized_args = deserialize_arguments(job)
RSpec::Mocks::ArgumentListMatcher.new(*@args).args_match?(*deserialized_args)
RSpec::Mocks::ArgumentListMatcher.new(*args).args_match?(*deserialized_args)
else
true
end
Expand Down Expand Up @@ -172,6 +173,13 @@ def set_expected_number(relativity, count)
end
end

def serialize_and_deserialize_arguments(args)
serialized = ::ActiveJob::Arguments.serialize(args)
Copy link
Member

@benoittgt benoittgt Aug 19, 2019

Choose a reason for hiding this comment

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

I am surprise we have to serialize then deserialize. I am wondering if it can be simpler?

https://github.com/rails/rails/blob/6-0-stable/activejob/lib/active_job/serializers/time_serializer.rb

Also maybe we can avoid using exception to validate the correct behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed to use simple time rounder instead of serializer/deserializer.
It is copied from ActiveJob::TestHelper.

https://github.com/rails/rails/blob/c986369095ad89fd68fd84d21aa39006ea77904d/activejob/lib/active_job/test_helper.rb#L638

Copy link
Member

Choose a reason for hiding this comment

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

I prefer the original implementation, it's simpler as it replicates what Rails does without special casing, the new implementation may not catch other edgecases and we're just reinventing what Rails is doing.

Copy link
Member

Choose a reason for hiding this comment

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

I'd also like to see a green build, which is why I started #2158

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I also like the original implementation, so I reverted. And, I deleted ActiveJob::DeserializationError because it never occurred.

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the change and sorry for the back and forth.

::ActiveJob::Arguments.deserialize(serialized)
rescue ::ActiveJob::SerializationError
args
end

def deserialize_arguments(job)
::ActiveJob::Arguments.deserialize(job[:args])
rescue ::ActiveJob::DeserializationError
Expand Down
18 changes: 18 additions & 0 deletions spec/rspec/rails/matchers/active_job_spec.rb
Expand Up @@ -328,6 +328,24 @@ def self.name; "LoggingJob"; end
expect(arg).to eq("asdf")
}
end

if Rails.version.to_f >= 6.0
it "passes with Time" do
usec_time = Time.iso8601('2016-07-01T00:00:00.000001Z')

expect {
hello_job.perform_later(usec_time)
}.to have_enqueued_job(hello_job).with(usec_time)
end

it "passes with ActiveSupport::TimeWithZone" do
usec_time = Time.iso8601('2016-07-01T00:00:00.000001Z').in_time_zone

expect {
hello_job.perform_later(usec_time)
}.to have_enqueued_job(hello_job).with(usec_time)
end
end
end

describe "have_been_enqueued" do
Expand Down