0

I am trying to write some scopes that are meant to pull events for future, past, and current events from my sqlite database. Here are the scopes I have set in my Event model with their accompanying predicate methods:

  scope :upcoming, where("start_at >= :time", time: Time.current ).order('start_at asc')
  scope :recent, where("end_at <= :time", time: Time.current ).order('end_at desc')
  scope :current, where("start_at <= :time AND end_at >= :time", time: Time.current ).order('start_at asc')



  def upcoming?
    start_at.future?
  end

  def recent?
    end_at.past?
  end

  def current?
    end_at.future? && start_at.past?
  end

And here are the results I'm getting from my rspec tests

  is in the future
    should be upcoming
    should not be recent
    should not be current
    should be in upcoming
    should not be in recent (FAILED - 1)
    should not be in current (FAILED - 2)
  is in the past
    should not be upcoming
    should be recent
    should not be current
    should not be in upcoming
    should be in recent (FAILED - 3)
    should not be in current
  is happening now
    should not be upcoming
    should not be recent
    should be current
    should not be in upcoming
    should not be in recent
    should be in current (FAILED - 4)

As you can see the predicate method tests run fine once the dates are pulled from the database, but when actually querying the database things go haywire.

Here is the rspec I'm running to test it(I'm a little bit new to it, so there might be some issues here, but I have seen the scopes failing with manual testing as well):

  let(:future) { Event.create(start_at: start_time, end_at: end_time ) }
  let(:past) { Event.create(start_at: start_time, end_at: end_time ) }
  let(:happening) { Event.create(start_at: start_time, end_at: end_time ) }

  context "#upcoming?" do
    it { should respond_to(:upcoming?) }
  end
  context "#recent?" do
    it { should respond_to(:recent?) }
  end
  context "#current?" do
    it { should respond_to(:current?) }
  end

  context "is in the future" do
    subject(:event) { future }
    let(:start_time) { Time.now + 1.minute }
    let(:end_time) { Time.now + 1.minute + 1.second }
    it { should be_upcoming }
    it { should_not be_recent }
    it { should_not be_current }
    it "should be in upcoming" do
      Event.upcoming.should include(event)
    end
    it "should not be in recent" do
      Event.upcoming.should_not include(event)
    end
    it "should not be in current" do
      Event.upcoming.should_not include(event)
    end
  end

  context "is in the past" do
    subject(:event) { past }
    let(:start_time) { Time.now - 1.minute }
    let(:end_time) { Time.now - 1.minute + 1.second }
    it { should_not be_upcoming }
    it { should be_recent }
    it { should_not be_current }
    it "should not be in upcoming" do
      Event.upcoming.should_not include(event)
    end
    it "should be in recent" do
      Event.upcoming.should include(event)
    end
    it "should not be in current" do
      Event.upcoming.should_not include(event)
    end
  end

  context "is happening now" do
    subject(:event) { happening }
    let(:start_time) { Time.now - 1.minute }
    let(:end_time) { Time.now + 1.minute }
    it { should_not be_upcoming }
    it { should_not be_recent }
    it { should be_current }
    it "should not be in upcoming" do
      Event.upcoming.should_not include(event)
    end
    it "should not be in recent" do
      Event.upcoming.should_not include(event)
    end
    it "should be in current" do
      Event.upcoming.should include(event)
    end
  end

Any idea on what's going wrong? I've tried several variants of Time.current And they all produce similar results.

4

1 に答える 1

0

@jdoe がコメントで述べているように、ラムダを使用して Time.current が 1 回だけフェッチされないようにする必要があります。

于 2013-01-28T08:29:41.493 に答える