From 3835b658e8f044ef899afdbdd85683b6f88774f4 Mon Sep 17 00:00:00 2001 From: johnnyshields Date: Tue, 11 Apr 2023 23:30:27 +0900 Subject: [PATCH 1/3] MONGOID-5559 - Fix BigDecimal evolution to Time --- .../criteria/queryable/extensions/numeric.rb | 2 + .../queryable/extensions/big_decimal_spec.rb | 76 +++++++++++++++ .../queryable/extensions/float_spec.rb | 76 +++++++++++++++ .../queryable/extensions/integer_spec.rb | 96 +++++++++++++++++-- 4 files changed, 240 insertions(+), 10 deletions(-) diff --git a/lib/mongoid/criteria/queryable/extensions/numeric.rb b/lib/mongoid/criteria/queryable/extensions/numeric.rb index f4ca47d08..d11f86264 100644 --- a/lib/mongoid/criteria/queryable/extensions/numeric.rb +++ b/lib/mongoid/criteria/queryable/extensions/numeric.rb @@ -71,3 +71,5 @@ def evolve(object) ::Float.__send__(:include, Mongoid::Criteria::Queryable::Extensions::Numeric) ::Float.__send__(:extend, Mongoid::Criteria::Queryable::Extensions::Numeric::ClassMethods) + +::BigDecimal.__send__(:include, Mongoid::Criteria::Queryable::Extensions::Numeric) diff --git a/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb b/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb index 97379077c..b6c7a45f7 100644 --- a/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +++ b/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb @@ -166,4 +166,80 @@ end end end + + describe "#__evolve_time__" do + + context 'UTC time zone' do + let(:time) do + Time.parse("2022-01-01 16:15:01 UTC") + end + + let(:evolved) do + time.to_i.to_d.__evolve_time__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(time) + end + end + + context 'other time zone' do + let(:time) do + Time.parse("2022-01-01 16:15:01 +0900") + end + + let(:evolved) do + time.to_i.to_d.__evolve_time__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(time) + end + end + end + + describe "#__evolve_date__" do + + context 'exact match' do + let(:date) do + Date.parse("2022-01-01") + end + + let(:evolved) do + Time.parse("2022-01-01 0:00 UTC").to_i.to_d.__evolve_date__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(date) + end + end + + context 'one second earlier' do + let(:date) do + Date.parse("2021-12-31") + end + + let(:evolved) do + (Time.parse("2022-01-01 0:00 UTC").to_i.to_d - 1).__evolve_date__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(date) + end + end + + context 'one second later' do + let(:date) do + Date.parse("2022-01-01") + end + + let(:evolved) do + (Time.parse("2022-01-01 0:00 UTC").to_i.to_d + 1).__evolve_date__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(date) + end + end + end end diff --git a/spec/mongoid/criteria/queryable/extensions/float_spec.rb b/spec/mongoid/criteria/queryable/extensions/float_spec.rb index d05d55df8..8c403a02f 100644 --- a/spec/mongoid/criteria/queryable/extensions/float_spec.rb +++ b/spec/mongoid/criteria/queryable/extensions/float_spec.rb @@ -64,4 +64,80 @@ end end end + + describe "#__evolve_time__" do + + context 'UTC time zone' do + let(:time) do + Time.parse("2022-01-01 16:15:01 UTC") + end + + let(:evolved) do + time.to_f.__evolve_time__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(time) + end + end + + context 'other time zone' do + let(:time) do + Time.parse("2022-01-01 16:15:01 +0900") + end + + let(:evolved) do + time.to_f.__evolve_time__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(time) + end + end + end + + describe "#__evolve_date__" do + + context 'exact match' do + let(:date) do + Date.parse("2022-01-01") + end + + let(:evolved) do + Time.parse("2022-01-01 0:00 UTC").to_f.__evolve_date__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(date) + end + end + + context 'one second earlier' do + let(:date) do + Date.parse("2021-12-31") + end + + let(:evolved) do + (Time.parse("2022-01-01 0:00 UTC").to_f - 1).__evolve_date__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(date) + end + end + + context 'one second later' do + let(:date) do + Date.parse("2022-01-01") + end + + let(:evolved) do + (Time.parse("2022-01-01 0:00 UTC").to_f + 1).__evolve_date__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(date) + end + end + end end diff --git a/spec/mongoid/criteria/queryable/extensions/integer_spec.rb b/spec/mongoid/criteria/queryable/extensions/integer_spec.rb index ecf20700a..98dd884a9 100644 --- a/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +++ b/spec/mongoid/criteria/queryable/extensions/integer_spec.rb @@ -39,29 +39,105 @@ end end end + + context "when provided a number" do + + context "when the number is an integer" do + + it "returns an integer" do + expect(described_class.evolve(1)).to eq(1) + end + end + + context "when the number is a float" do + + it "returns the float" do + expect(described_class.evolve(2.23)).to eq(2.23) + end + end + end + + context "when provided nil" do + + it "returns nil" do + expect(described_class.evolve(nil)).to be_nil + end + end end - context "when provided a number" do + describe "#__evolve_time__" do + + context 'UTC time zone' do + let(:time) do + Time.parse("2022-01-01 16:15:01 UTC") + end - context "when the number is an integer" do + let(:evolved) do + time.to_i.__evolve_time__ + end - it "returns an integer" do - expect(described_class.evolve(1)).to eq(1) + it 'evolves the correct time' do + expect(evolved).to eq(time) end end - context "when the number is a float" do + context 'other time zone' do + let(:time) do + Time.parse("2022-01-01 16:15:01 +0900") + end + + let(:evolved) do + time.to_i.__evolve_time__ + end - it "returns the float" do - expect(described_class.evolve(2.23)).to eq(2.23) + it 'evolves the correct time' do + expect(evolved).to eq(time) end end end - context "when provided nil" do + describe "#__evolve_date__" do - it "returns nil" do - expect(described_class.evolve(nil)).to be_nil + context 'exact match' do + let(:date) do + Date.parse("2022-01-01") + end + + let(:evolved) do + Time.parse("2022-01-01 0:00 UTC").to_i.__evolve_date__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(date) + end + end + + context 'one second earlier' do + let(:date) do + Date.parse("2021-12-31") + end + + let(:evolved) do + (Time.parse("2022-01-01 0:00 UTC").to_i - 1).__evolve_date__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(date) + end + end + + context 'one second later' do + let(:date) do + Date.parse("2022-01-01") + end + + let(:evolved) do + (Time.parse("2022-01-01 0:00 UTC").to_i + 1).__evolve_date__ + end + + it 'evolves the correct time' do + expect(evolved).to eq(date) + end end end end From dd6afa1aa6d64b4df3282f2180be5533b25b4859 Mon Sep 17 00:00:00 2001 From: johnnyshields Date: Tue, 11 Apr 2023 23:34:31 +0900 Subject: [PATCH 2/3] Add readme line --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 9730fb991..d4d3de1c7 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,10 @@ Refer to the [Roadmap issue](https://github.com/tablecheck/mongoid-ultra/issues/ - ✅ [MONGOID-5556](https://jira.mongodb.org/browse/MONGOID-5556) - Add `Criteria#tally` `:unwind` arg to splat array results. - More to come soon! +#### Bug Fixes + +- 🐞 [MONGOID-5559](https://jira.mongodb.org/browse/MONGOID-5559) - `BigDecimal` should correctly type-cast to `Time`. + #### Best Practices - ✅ [MONGOID-5572](https://jira.mongodb.org/browse/MONGOID-5572) - RSpec: Use expectation syntax, enforced with RSpec config setting. From 6bf5324a20f633d54a47165035f599a8a93e8800 Mon Sep 17 00:00:00 2001 From: johnnyshields Date: Wed, 12 Apr 2023 00:16:55 +0900 Subject: [PATCH 3/3] Fix specs --- spec/integration/criteria/raw_value_spec.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/integration/criteria/raw_value_spec.rb b/spec/integration/criteria/raw_value_spec.rb index e1756d9bf..50f28c73d 100644 --- a/spec/integration/criteria/raw_value_spec.rb +++ b/spec/integration/criteria/raw_value_spec.rb @@ -311,8 +311,8 @@ expect(Band.where(founded: Mongoid::RawValue(BigDecimal('1577923200'))).to_a).to eq [band7] end - it 'matches objects without raw value because BigDecimal cannot be evolved to Date' do - expect(Band.where(founded: BigDecimal('1577923200')).to_a).to eq [band7] + it 'matches objects without raw value' do + expect(Band.where(founded: BigDecimal('1577923200')).to_a).to eq [band3, band4] end end @@ -321,8 +321,8 @@ expect(Band.where(updated: Mongoid::RawValue(BigDecimal('1578153600'))).to_a).to eq [band7] end - it 'matches objects without raw value because BigDecimal cannot be evolved to Time' do - expect(Band.where(updated: BigDecimal('1578153600')).to_a).to eq [band7] + it 'matches objects without raw value' do + expect(Band.where(updated: BigDecimal('1578153600')).to_a).to eq [band4, band5] end end end