From bddbd7f6eeae21e25080014a1a7398ca7690b6d2 Mon Sep 17 00:00:00 2001 From: Bogdan Gusiev Date: Tue, 30 Jan 2024 14:54:50 +0100 Subject: [PATCH] Support infinite ranges for datetime filter --- CHANGELOG.md | 2 +- lib/datagrid/filters/base_filter.rb | 2 +- .../datagrid/filters/date_time_filter_spec.rb | 97 +++++++++++-------- 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82034fd1..45969844 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## master -* Support infinite ranges for date filter +* Support infinite ranges for date, datetime and integer filters ## 1.8.1 diff --git a/lib/datagrid/filters/base_filter.rb b/lib/datagrid/filters/base_filter.rb index 57865497..fcbd746c 100644 --- a/lib/datagrid/filters/base_filter.rb +++ b/lib/datagrid/filters/base_filter.rb @@ -155,7 +155,7 @@ def normalize_multiple_value(value) when String value.split(separator) when Range - [value.first, value.last] + [value.begin, value.end] when Array value else diff --git a/spec/datagrid/filters/date_time_filter_spec.rb b/spec/datagrid/filters/date_time_filter_spec.rb index 0d80b98d..41c833cc 100644 --- a/spec/datagrid/filters/date_time_filter_spec.rb +++ b/spec/datagrid/filters/date_time_filter_spec.rb @@ -7,9 +7,9 @@ let(:klass) { klass } let(:grid) do - test_report(:created_at => _created_at) do + test_report(created_at: _created_at) do scope { klass } - filter(:created_at, :datetime, :range => true) + filter(:created_at, :datetime, range: true) end end @@ -18,17 +18,17 @@ end def entry_dated(date) - klass.create(:created_at => date) + klass.create!(created_at: date) end - context "when single datetime paramter given" do + context "with single datetime paramter given" do let(:_created_at) { Time.now.change(sec: 0) } it { should include(entry_dated(_created_at)) } it { should_not include(entry_dated(_created_at - 1.second))} it { should_not include(entry_dated(_created_at + 1.second))} end - context "when range datetime range given" do + context "with range datetime range given" do let(:_created_at) { [Time.now.beginning_of_day, Time.now.end_of_day] } it { should include(entry_dated(1.second.ago))} it { should include(entry_dated(Date.today.to_time))} @@ -36,18 +36,36 @@ def entry_dated(date) it { should_not include(entry_dated(Date.yesterday.end_of_day))} it { should_not include(entry_dated(Date.tomorrow.beginning_of_day))} end + + context "with right open range" do + let(:_created_at) { Time.now.beginning_of_day..nil } + it { should include(entry_dated(1.second.ago))} + it { should include(entry_dated(Date.today.to_time))} + it { should include(entry_dated(Time.now.end_of_day.to_time))} + it { should include(entry_dated(Date.tomorrow.beginning_of_day))} + it { should_not include(entry_dated(Date.yesterday.end_of_day))} + end + + context "with left open range" do + let(:_created_at) { nil..Time.now.end_of_day } + it { should include(entry_dated(1.second.ago))} + it { should include(entry_dated(Date.today.to_time))} + it { should include(entry_dated(Time.now.end_of_day.to_time))} + it { should include(entry_dated(Date.yesterday.end_of_day))} + it { should_not include(entry_dated(Date.tomorrow.beginning_of_day))} + end end end end it "should support datetime range given as array argument" do - e1 = Entry.create!(:created_at => Time.new(2013, 1, 1, 1, 0)) - e2 = Entry.create!(:created_at => Time.new(2013, 1, 1, 2, 0)) - e3 = Entry.create!(:created_at => Time.new(2013, 1, 1, 3, 0)) - report = test_report(:created_at => [Time.new(2013, 1, 1, 1, 30).to_s, Time.new(2013, 1, 1, 2, 30).to_s]) do + e1 = Entry.create!(created_at: Time.new(2013, 1, 1, 1, 0)) + e2 = Entry.create!(created_at: Time.new(2013, 1, 1, 2, 0)) + e3 = Entry.create!(created_at: Time.new(2013, 1, 1, 3, 0)) + report = test_report(created_at: [Time.new(2013, 1, 1, 1, 30).to_s, Time.new(2013, 1, 1, 2, 30).to_s]) do scope { Entry } - filter(:created_at, :datetime, :range => true) + filter(:created_at, :datetime, range: true) end expect(report.assets).not_to include(e1) expect(report.assets).to include(e2) @@ -55,12 +73,12 @@ def entry_dated(date) end it "should support minimum datetime argument" do - e1 = Entry.create!(:created_at => Time.new(2013, 1, 1, 1, 0)) - e2 = Entry.create!(:created_at => Time.new(2013, 1, 1, 2, 0)) - e3 = Entry.create!(:created_at => Time.new(2013, 1, 1, 3, 0)) - report = test_report(:created_at => [Time.new(2013, 1, 1, 1, 30).to_s, nil]) do + e1 = Entry.create!(created_at: Time.new(2013, 1, 1, 1, 0)) + e2 = Entry.create!(created_at: Time.new(2013, 1, 1, 2, 0)) + e3 = Entry.create!(created_at: Time.new(2013, 1, 1, 3, 0)) + report = test_report(created_at: [Time.new(2013, 1, 1, 1, 30).to_s, nil]) do scope { Entry } - filter(:created_at, :datetime, :range => true) + filter(:created_at, :datetime, range: true) end expect(report.assets).not_to include(e1) expect(report.assets).to include(e2) @@ -68,12 +86,12 @@ def entry_dated(date) end it "should support maximum datetime argument" do - e1 = Entry.create!(:created_at => Time.new(2013, 1, 1, 1, 0)) - e2 = Entry.create!(:created_at => Time.new(2013, 1, 1, 2, 0)) - e3 = Entry.create!(:created_at => Time.new(2013, 1, 1, 3, 0)) - report = test_report(:created_at => [nil, Time.new(2013, 1, 1, 2, 30).to_s]) do + e1 = Entry.create!(created_at: Time.new(2013, 1, 1, 1, 0)) + e2 = Entry.create!(created_at: Time.new(2013, 1, 1, 2, 0)) + e3 = Entry.create!(created_at: Time.new(2013, 1, 1, 3, 0)) + report = test_report(created_at: [nil, Time.new(2013, 1, 1, 2, 30).to_s]) do scope { Entry } - filter(:created_at, :datetime, :range => true) + filter(:created_at, :datetime, range: true) end expect(report.assets).to include(e1) expect(report.assets).to include(e2) @@ -81,27 +99,26 @@ def entry_dated(date) end it "should find something in one second interval" do - - e1 = Entry.create!(:created_at => Time.new(2013, 1, 1, 1, 0)) - e2 = Entry.create!(:created_at => Time.new(2013, 1, 1, 2, 0)) - e3 = Entry.create!(:created_at => Time.new(2013, 1, 1, 3, 0)) - report = test_report(:created_at => Time.new(2013, 1, 1, 2, 0)..Time.new(2013, 1, 1, 2, 0)) do + e1 = Entry.create!(created_at: Time.new(2013, 1, 1, 1, 0)) + e2 = Entry.create!(created_at: Time.new(2013, 1, 1, 2, 0)) + e3 = Entry.create!(created_at: Time.new(2013, 1, 1, 3, 0)) + report = test_report(created_at: Time.new(2013, 1, 1, 2, 0)..Time.new(2013, 1, 1, 2, 0)) do scope { Entry } - filter(:created_at, :datetime, :range => true) + filter(:created_at, :datetime, range: true) end expect(report.assets).not_to include(e1) expect(report.assets).to include(e2) expect(report.assets).not_to include(e3) end - it "should reverse invalid range" do + it "should reverse invalid range" do range = Time.new(2013, 1, 1, 3, 0)..Time.new(2013, 1, 1, 1, 0) - e1 = Entry.create!(:created_at => Time.new(2013, 1, 1, 1, 0)) - e2 = Entry.create!(:created_at => Time.new(2013, 1, 1, 2, 0)) - e3 = Entry.create!(:created_at => Time.new(2013, 1, 1, 3, 0)) - report = test_report(:created_at => range) do + e1 = Entry.create!(created_at: Time.new(2013, 1, 1, 1, 0)) + e2 = Entry.create!(created_at: Time.new(2013, 1, 1, 2, 0)) + e3 = Entry.create!(created_at: Time.new(2013, 1, 1, 3, 0)) + report = test_report(created_at: range) do scope { Entry } - filter(:created_at, :datetime, :range => true) + filter(:created_at, :datetime, range: true) end expect(report.created_at).to eq([range.last, range.first]) expect(report.assets).to include(e1) @@ -111,14 +128,14 @@ def entry_dated(date) it "should support block" do - report = test_report(:created_at => Time.now) do + report = test_report(created_at: Time.now) do scope { Entry } - filter(:created_at, :datetime, :range => true) do |value| + filter(:created_at, :datetime, range: true) do |value| where("created_at >= ?", value) end end - expect(report.assets).not_to include(Entry.create!(:created_at => 1.day.ago)) - expect(report.assets).to include(Entry.create!(:created_at => Time.now+1.day)) + expect(report.assets).not_to include(Entry.create!(created_at: 1.day.ago)) + expect(report.assets).to include(Entry.create!(created_at: Time.now+1.day)) end @@ -130,7 +147,7 @@ def entry_dated(date) end it "should have configurable datetime format" do - report = test_report(:created_at => "10/01/2013 01:00") do + report = test_report(created_at: "10/01/2013 01:00") do scope {Entry} filter(:created_at, :datetime) end @@ -138,7 +155,7 @@ def entry_dated(date) end it "should support default explicit datetime" do - report = test_report(:created_at => Time.parse("2013-10-01 01:00")) do + report = test_report(created_at: Time.parse("2013-10-01 01:00")) do scope {Entry} filter(:created_at, :datetime) end @@ -148,9 +165,9 @@ def entry_dated(date) it "should automatically reverse Array if first more than last" do - report = test_report(:created_at => ["2013-01-01 01:00", "2012-01-01 01:00"]) do + report = test_report(created_at: ["2013-01-01 01:00", "2012-01-01 01:00"]) do scope {Entry} - filter(:created_at, :datetime, :range => true) + filter(:created_at, :datetime, range: true) end expect(report.created_at).to eq([Time.new(2012, 01, 01, 1, 0), Time.new(2013, 01, 01, 1, 0)]) end