21

I have a Cucumber table, one of the fields is a date which I would like to have populated with todays date. Is there a way of doing this without having to hard code todays date into the table?

Basically I would like to enter Time.now.strftime("%Y-%m-%d") into the table and not have it break.

Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
KJF
  • 2,083
  • 4
  • 21
  • 38
  • Note: yes, I know how to click on a tag. I am playing dumb to show the importance of: proper capitalization, providing context in a question, correct tagging... – PhiLho Oct 24 '09 at 13:52
  • A quick search with Google suggests that BDD and Cucumber are related to Ruby on Rails - which might be transparently obvious if you move in those circles but not if you don't. – Jonathan Leffler Oct 24 '09 at 14:35
  • 4
    Cucumber is actually related to ruby, not RoR. Non rails developers use it to test their code. I use it to test Java code. And BDD is not related to Rails, it is Behavioral Driven Development, a different style than TDD, Test Driven Development. – Brandon Bodnar Oct 24 '09 at 14:57

4 Answers4

23

Since the table is being processed by your step definition, you could put a special place holder in the table, such as the string "TODAYS_DATE", and then use map_column! to process the data in the column to the format you want.

For example given the following table

Given the following user records
  | username | date        |
  | alice    | 2001-01-01  |
  | bob      | TODAYS_DATE |

In your step definition you would have

Given /^the following user records$/ do |table|
  table.map_column!('date') do |date| 
    if date == 'TODAYS_DATE'
      date = Time.now.strftime("%Y-%m-%d")
    end
    date
  end
  table.hashes.each do |hash|
    #Whatever you need to do
  end
end

Note this only changes the values when you ask for the hash. table and table.raw will remain the same, but whenever you need the row hashes, they will be converted by the code within the map_column!

Brandon Bodnar
  • 8,202
  • 2
  • 36
  • 42
8

I know it's been ages since this question was asked but I was doing something similar with Cucumber recently so here's an alternative solution if anyone's interested...

Given the following user records
 | username | date                             |
 | bob      | Time.now.strftime("%Y-%m-%d")    |

And then in your step definition just eval() the date string

Given /^the following user records$/ do |table|
  table.hashes.each do |hash|
    date = eval(hash["date"])
  end
end

Though unlike Brandon's example this wont let you put in exact dates as well without some further logic.

Ganesh Shankar
  • 4,826
  • 8
  • 43
  • 56
  • shouldn't it be hash["date"] = eval(hash["date"]) ? it worked that way for me – santuxus Aug 17 '12 at 12:16
  • Unfortunately, this doesn't work for the case given by the OP which contains an entry '2001-01-01' -- this evals to 1999 as it's just simple integer arithmetic. You'd have to put something like Date.parse('2001-01-01') in your table to get the general result. – JESii Mar 29 '15 at 16:31
4

bodnarbm's answer is pretty good if that is what you want to do. My own suggestion would be to take a look at the timecop gem. Use it to set time to a known day then adjust your tables accordingly.

John F. Miller
  • 26,961
  • 10
  • 71
  • 121
0

Based on fixtures files I created this code:

Feature:

Given the following "Inquirers":
  | id | email                    | start_date        |
  |  1 | alberto@deco.proteste.pt | <%= Time.now %>   |

Helper:

Given(/^the following "(.*?)":$/) do |model, table|
  table.hashes.each do |hash|
    attributes = Rack::Utils.parse_nested_query(hash.to_query)
    object     = model_name.classify.constantize.new

    attributes.keys.each do |key|
      object.send("#{key}=", ERB.new(value).result())
    end
    ...
  end
end
raphox
  • 119
  • 1
  • 4