We recently started to drag a very old Rails app up to date (or at least out of obsolescence). One of the changes was an update of Cucumber from 1.3.x to 2.99.
Many of our rspec specs on this app used a helper for loading test data which leveraged Cucumber::Ast::DataTable
. (The helper declared its own subclass which inherited from Cucumber::Ast::DataTable
.) This was deprecated, so as suggested, I replaced the inheritance with Cucumber::MultilineArgument::DataTable
.
The subclass looks like this:
class ParsedTable < ::Cucumber::MultilineArgument::DataTable
def initialize(string)
super(string.split("\n").map do |line|
line = line.split('|').map(&:squish)
line.slice(1, line.length)
end)
end
end
Then there are a bunch of test helpers which create test data like this (assume "role" is a model we'll be testing against):
def create_roles(string)
table = ParsedTable.new(string)
table.hashes.each do |hash|
create :role,
name: hash['Name'],
short_name: hash['Short Name'],
contracted_work_day: hash['Contracted workday in minutes']
end
end
These helpers get called like this:
create_roles <<-eos
| Name | Contracted workday in minutes |
| Therapist | 390 |
eos
But when that kind of call goes in, I get ArgumentError: data must be a Core::Ast::DataTable
. The stack says this exception is from lib/cucumber/multiline_argument/data_table.rb:93:in 'initialize'
which is the super
call in the ParsedTable
definition.
I've been trying to chase this around the Cucumber source and I can't figure out what I'm doing wrong.
The API documentation for Cucumber states that the constructor for Cucumber::MultilineArgument::DataTable takes a Core::Ast::DataTable
object.
Source: https://www.rubydoc.info/gems/cucumber/Cucumber/MultilineArgument/DataTable#constructor_details
You will need an instance of Core::Ast::DataTable
rather than custom parsing it from a string.
Creates a new instance. +raw+ should be an Array of Array of String or an Array of Hash You don't typically create your own DataTable objects - Cucumber will do it internally and pass them to your Step Definitions.
Source: https://www.rubydoc.info/gems/cucumber-core/1.3.1/Cucumber/Core/Ast/DataTable#constructor_details
It looks like cucumber should have already parsed the table as a Core::Ast::DataTable
object in the step binding, so all you should need to do is pass this along to the constructor of your ParsedTable
class.
When this isn't available, then you'll need to provide an array of array of strings instead.