Skip to content

Commit 4e84492

Browse files
johnnyshieldsclaudejoshuacronemeyer
authored
Fix Time.new keyword arguments on JRuby 10 (#443)
* Fix Time.new with keyword arguments on JRuby 10 and Ruby 3.1+ Replace `ruby2_keywords` approach with explicit `**kwargs` in `new_with_mock_time`. On JRuby 10 (Ruby 3.4 compat), the `ruby2_keywords` flag doesn't properly forward keyword arguments through `new_without_mock_time`, causing `TypeError: no implicit conversion of Hash into Integer` when ActiveModel deserializes datetime columns. The fix uses explicit `**kwargs` which works correctly across all Ruby versions and implementations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * replaced rescue ArgumentError with skip + version guard. This ensures a TypeError (or any other error) on older Ruby won't silently mask a failure. Also new test covering kwargs only, no positional args), which exercises the args.empty? && kwargs.any? branch --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Josh Cronemeyer <joshuacronemeyer@gmail.com>
1 parent b06405e commit 4e84492

2 files changed

Lines changed: 34 additions & 4 deletions

File tree

lib/timecop/time_extensions.rb

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,16 @@ def now_with_mock_time
1818

1919
alias_method :new_without_mock_time, :new
2020

21-
def new_with_mock_time(*args)
22-
args.size <= 0 ? now : new_without_mock_time(*args)
21+
def new_with_mock_time(*args, **kwargs)
22+
if args.empty? && kwargs.empty?
23+
now
24+
elsif kwargs.any?
25+
new_without_mock_time(*args, **kwargs)
26+
else
27+
new_without_mock_time(*args)
28+
end
2329
end
2430

25-
ruby2_keywords :new_with_mock_time if Module.private_method_defined?(:ruby2_keywords)
26-
2731
alias_method :new, :new_with_mock_time
2832
end
2933
end

test/timecop_test.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,32 @@ def test_mock_time_new_same_as_now
519519
assert_equal date, Time.new
520520
end
521521

522+
def test_time_new_with_keyword_arguments
523+
skip "Time.new with in: keyword requires Ruby 3.1+" if RUBY_VERSION < "3.1"
524+
Timecop.freeze(2011, 1, 2) do
525+
t = Time.new(2020, 1, 1, 0, 0, 0, in: "+05:00")
526+
assert_equal 2020, t.year
527+
assert_equal 18000, t.utc_offset
528+
end
529+
end
530+
531+
def test_time_new_with_only_keyword_arguments
532+
skip "Time.new with in: keyword requires Ruby 3.1+" if RUBY_VERSION < "3.1"
533+
Timecop.freeze(2011, 1, 2) do
534+
t = Time.new(in: "+05:00")
535+
assert_equal 18000, t.utc_offset
536+
end
537+
end
538+
539+
def test_time_new_with_positional_args_still_works
540+
Timecop.freeze(2011, 1, 2) do
541+
t = Time.new(2020, 6, 15, 12, 30, 0)
542+
assert_equal 2020, t.year
543+
assert_equal 6, t.month
544+
assert_equal 15, t.day
545+
end
546+
end
547+
522548
def test_not_callable_send_travel
523549
assert_raises NoMethodError do
524550
Timecop.send_travel(:travel, Time.now - 100)

0 commit comments

Comments
 (0)