travisjeffery / timecop

A gem providing "time travel", "time freezing", and "time acceleration" capabilities, making it simple to test time-dependent code. It provides a unified method to mock Time.now, Date.today, and DateTime.now in a single call.
MIT License
3.36k stars 223 forks source link

Using timecop with psych 4.0.5, behavior differs between the test environment and other environments #390

Closed sanfrecce-osaka closed 1 year ago

sanfrecce-osaka commented 1 year ago

Steps to reproduce

Under the following conditions,

run the following.

$ bin/rails c
irb(main):001:0> YAML.unsafe_load('foo: 2020-12-30')
=> {"foo"=>Wed, 30 Dec 2020}

This is the expected result.

Next, run the following.

$ bin/rails c -e test
irb(main):001:0> YAML.unsafe_load('foo: 2020-12-30')
=> {"foo"=>"2020-12-30"}

I was expecting that value is Date as well, but it turned out to be String.

Expected behavior

Value is Date.

Actual behavior

Value is String.

Reason

Since psych 4.0.5, Psych::ScalarScanner#tokenize passes Date::GREGORIAN as the third argument of Date.strptime.

cf. https://github.com/ruby/psych/pull/573

However, when using timecop, Date.strptime_with_mock_date(This is an alias of Date.strptime) only allows Date::ITALY as the third argument.

cf. https://github.com/travisjeffery/timecop/blob/v0.9.5/lib/timecop/time_extensions.rb#L47-L51

So ArgumentError is raised and Psych::ScalarScanner#tokenize returns String.

cf. https://github.com/ruby/psych/blob/v4.0.5/lib/psych/scalar_scanner.rb#L63-L69

korny commented 1 year ago

Same problem with psych 3.3.3. #389 works for me :)

johnnyshields commented 1 year ago

Please fix this, I spent about 2 hours debugging to find this issue.

mishina2228 commented 1 year ago

@sanfrecce-osaka @joshuacronemeyer #389 has been merged, so it looks like we can close this issue.