Skip to content

Commit

Permalink
Support infinite ranges for datetime filter
Browse files Browse the repository at this point in the history
  • Loading branch information
bogdan committed Jan 30, 2024
1 parent 844a36b commit bddbd7f
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 42 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## master

* Support infinite ranges for date filter
* Support infinite ranges for date, datetime and integer filters

## 1.8.1

Expand Down
2 changes: 1 addition & 1 deletion lib/datagrid/filters/base_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
97 changes: 57 additions & 40 deletions spec/datagrid/filters/date_time_filter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -18,90 +18,107 @@
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))}
it { should include(entry_dated(Time.now.end_of_day.to_time))}
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)
expect(report.assets).not_to include(e3)
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)
expect(report.assets).to include(e3)
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)
expect(report.assets).not_to include(e3)
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)
Expand All @@ -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


Expand All @@ -130,15 +147,15 @@ 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
expect(report.created_at).to eq(Time.new(2013,10,01,1,0))
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
Expand All @@ -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
Expand Down

0 comments on commit bddbd7f

Please sign in to comment.