使Ruby类与Date类相当

时间:2013-06-28 23:01:20

标签: ruby date rspec compare

如何指定一个与日期相当的类?

class FolderDate

  attr_reader :folder

  def initialize folder
    @folder = folder
  end
end

class AsteriskFolderDate < FolderDate

  include Comparable

  attr_reader :date

  def initialize folder
    super
    @date = get_date
  end

  def <=>(other)
    @date <=> other
  end

  private
    #omitted
end

在Rails控制台中......

AsteriskFolderDate.new("20130628") > Date.today-1
 => true
AsteriskFolderDate.new("20130627") > Date.today
 => false 

规格文件......

describe "An instance of", AsteriskFolderDate do
  let(:folder) { DateFolder.new(Date.today).asterisk_folder }

  subject { AsteriskFolderDate.new(folder) }

  #omitted

  it "should compare based on @date" do
    expect( Date.today-1 ).to be < subject
    expect( subject ).to be > Date.today-1
  end
end

测试失败......

Failure/Error: expect( Date.today-1 ).to be < subject
  ArgumentError:
   comparison of Date with AsteriskFolderDate failed

控制台输出让我觉得它有效,但测试失败了。我是在正确的轨道上,还是测试指出我在控制台中缺少的一个缺陷?

2 个答案:

答案 0 :(得分:1)

问题在于您进行比较的顺序。如果你在Rails控制台中执行此操作:

Date.today < AsteriskFolderDate.new("20130627")

你会看到同样的错误。只有一个断言会抛出错误:

it "should compare based on @date" do
  expect( Date.today-1 ).to be < subject  # Fails
  expect( subject ).to be > Date.today-1  # Works
end

这是因为AsteriskFolderDate知道如何将自己与Date进行比较,但标准的ruby Date对象对AsteriskFolderDate(预期的)一无所知。

如果您希望比较双向工作,则需要以某种方式修改Date类。

答案 1 :(得分:1)

您已在AsteriskFolderDate课程中指定了与Date相媲美的方法。所以以下工作正常:

AsteriskFolderDate.new(Date.today.strftime("%Y%m%d")) > Date.today-1
#=> true
AsteriskFolderDate.new((Date.today - 1).strftime("%Y%m%d")) > Date.today
#=> false

但是你没有使补丁Date与你的自定义类AsteriskFolderDate相媲美。当您撰写Date.today < AsteriskFolderDate.new("20130627")时,<邮件会发送到Date的实例,但Date不知道如何与AsteriskFolderDate进行比较,因此从Date#<引发参数错误。

Date.today-1 < AsteriskFolderDate.new(Date.today.strftime("%Y%m%d"))
# folder_date.rb:23:in `<': comparison of Date with FolderDate failed (ArgumentError)
#        from folder_date.rb:23:in `<main>'