cucumber-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.travis.yml +16 -0
- data/Gemfile +2 -0
- data/LICENSE +20 -0
- data/README.md +9 -0
- data/Rakefile +24 -0
- data/cucumber-core.gemspec +32 -0
- data/lib/cucumber/core.rb +37 -0
- data/lib/cucumber/core/ast.rb +13 -0
- data/lib/cucumber/core/ast/background.rb +33 -0
- data/lib/cucumber/core/ast/comment.rb +17 -0
- data/lib/cucumber/core/ast/data_table.rb +326 -0
- data/lib/cucumber/core/ast/describes_itself.rb +16 -0
- data/lib/cucumber/core/ast/doc_string.rb +83 -0
- data/lib/cucumber/core/ast/empty_background.rb +12 -0
- data/lib/cucumber/core/ast/examples_table.rb +95 -0
- data/lib/cucumber/core/ast/feature.rb +62 -0
- data/lib/cucumber/core/ast/location.rb +140 -0
- data/lib/cucumber/core/ast/multiline_argument.rb +33 -0
- data/lib/cucumber/core/ast/names.rb +19 -0
- data/lib/cucumber/core/ast/outline_step.rb +51 -0
- data/lib/cucumber/core/ast/scenario.rb +43 -0
- data/lib/cucumber/core/ast/scenario_outline.rb +44 -0
- data/lib/cucumber/core/ast/step.rb +38 -0
- data/lib/cucumber/core/ast/tag.rb +14 -0
- data/lib/cucumber/core/compiler.rb +136 -0
- data/lib/cucumber/core/gherkin/ast_builder.rb +315 -0
- data/lib/cucumber/core/gherkin/document.rb +20 -0
- data/lib/cucumber/core/gherkin/parser.rb +45 -0
- data/lib/cucumber/core/gherkin/writer.rb +220 -0
- data/lib/cucumber/core/gherkin/writer/helpers.rb +178 -0
- data/lib/cucumber/core/platform.rb +30 -0
- data/lib/cucumber/core/test/case.rb +143 -0
- data/lib/cucumber/core/test/filters.rb +48 -0
- data/lib/cucumber/core/test/filters/tag_filter.rb +110 -0
- data/lib/cucumber/core/test/hook_compiler.rb +109 -0
- data/lib/cucumber/core/test/mapper.rb +56 -0
- data/lib/cucumber/core/test/mapping.rb +67 -0
- data/lib/cucumber/core/test/result.rb +191 -0
- data/lib/cucumber/core/test/runner.rb +149 -0
- data/lib/cucumber/core/test/step.rb +69 -0
- data/lib/cucumber/core/test/timer.rb +31 -0
- data/lib/cucumber/core/version.rb +9 -0
- data/lib/cucumber/initializer.rb +18 -0
- data/spec/capture_warnings.rb +68 -0
- data/spec/coverage.rb +10 -0
- data/spec/cucumber/core/ast/data_table_spec.rb +139 -0
- data/spec/cucumber/core/ast/doc_string_spec.rb +77 -0
- data/spec/cucumber/core/ast/examples_table_spec.rb +87 -0
- data/spec/cucumber/core/ast/location_spec.rb +105 -0
- data/spec/cucumber/core/ast/outline_step_spec.rb +77 -0
- data/spec/cucumber/core/ast/step_spec.rb +44 -0
- data/spec/cucumber/core/compiler_spec.rb +249 -0
- data/spec/cucumber/core/gherkin/parser_spec.rb +182 -0
- data/spec/cucumber/core/gherkin/writer_spec.rb +332 -0
- data/spec/cucumber/core/test/case_spec.rb +416 -0
- data/spec/cucumber/core/test/hook_compiler_spec.rb +78 -0
- data/spec/cucumber/core/test/mapper_spec.rb +68 -0
- data/spec/cucumber/core/test/mapping_spec.rb +103 -0
- data/spec/cucumber/core/test/result_spec.rb +178 -0
- data/spec/cucumber/core/test/runner_spec.rb +265 -0
- data/spec/cucumber/core/test/step_spec.rb +58 -0
- data/spec/cucumber/core/test/timer_spec.rb +13 -0
- data/spec/cucumber/core_spec.rb +419 -0
- data/spec/cucumber/initializer_spec.rb +49 -0
- metadata +221 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ea9227a0b067303f1aa77c9f4f05e75a73a74da6
|
4
|
+
data.tar.gz: 5ec7e76b3ec7fe9e093e5091a0e7e80156153aea
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9b8b2ce54523d97a6107b334342578af32f865281ceccb891f035cd55d0df119f267f510713e3e893ed6cb4a6be4af278648f22f3c77364ec0cc5d7e4ab15635
|
7
|
+
data.tar.gz: faae23fd3346d6957260ea77836ec6162e15d562017723d6328e5f386eecc3c4628fbe54513d579febcf97118303ece2d2ef9de505f5cab2752a897683c62b9a
|
data/.coveralls.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
service_name: travis-ci
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
cucumber
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (C) 2013 The Cucumber Organisation
|
2
|
+
|
3
|
+
MIT License (Expat)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
cucumber-ruby-core
|
2
|
+
==================
|
3
|
+
|
4
|
+
[](http://travis-ci.org/cucumber/cucumber-ruby-core)
|
5
|
+
[](https://codeclimate.com/github/cucumber/cucumber-ruby-core)
|
7
|
+
[](https://coveralls.io/r/cucumber/cucumber-ruby-core?branch=master)
|
8
|
+
|
9
|
+
Core library for the Ruby flavour of Cucumber
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
7
|
+
|
8
|
+
require "rspec/core/rake_task"
|
9
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
10
|
+
t.ruby_opts = %w[-r./spec/coverage -w]
|
11
|
+
t.rspec_opts = %w[--color]
|
12
|
+
end
|
13
|
+
|
14
|
+
require_relative 'spec/capture_warnings'
|
15
|
+
include CaptureWarnings
|
16
|
+
namespace :spec do
|
17
|
+
task :warnings do
|
18
|
+
report_warnings do
|
19
|
+
Rake::Task['spec'].invoke
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
task default: ['spec:warnings']
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
3
|
+
require "cucumber/core/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'cucumber-core'
|
7
|
+
s.version = Cucumber::Core::Version
|
8
|
+
s.authors = ["Aslak Hellesøy", "Matt Wynne", "Steve Tooke", "Oleg Sukhodolsky", "Tom Brand"]
|
9
|
+
s.description = 'Core library for the Cucumber BDD app'
|
10
|
+
s.summary = "cucumber-core-#{s.version}"
|
11
|
+
s.email = 'cukes@googlegroups.com'
|
12
|
+
s.homepage = "http://cukes.info"
|
13
|
+
s.platform = Gem::Platform::RUBY
|
14
|
+
s.license = "MIT"
|
15
|
+
s.required_ruby_version = ">= 1.9.3"
|
16
|
+
|
17
|
+
s.add_dependency 'gherkin', '~> 2.12.0'
|
18
|
+
|
19
|
+
s.add_development_dependency 'bundler', '>= 1.3.5'
|
20
|
+
s.add_development_dependency 'rake', '>= 0.9.2'
|
21
|
+
s.add_development_dependency 'rspec', '>= 2.13'
|
22
|
+
s.add_development_dependency 'unindent', '>= 1.0'
|
23
|
+
|
24
|
+
# For coverage reports
|
25
|
+
s.add_development_dependency 'coveralls', '~> 0.7'
|
26
|
+
|
27
|
+
s.rubygems_version = ">= 1.6.1"
|
28
|
+
s.files = `git ls-files`.split("\n").reject {|path| path =~ /\.gitignore$/ }
|
29
|
+
s.test_files = `git ls-files -- spec/*`.split("\n")
|
30
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
31
|
+
s.require_path = "lib"
|
32
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'cucumber/core/gherkin/parser'
|
2
|
+
require 'cucumber/core/compiler'
|
3
|
+
require 'cucumber/core/test/runner'
|
4
|
+
require 'cucumber/core/test/mapper'
|
5
|
+
require 'cucumber/core/test/hook_compiler'
|
6
|
+
|
7
|
+
module Cucumber
|
8
|
+
module Core
|
9
|
+
|
10
|
+
def parse(gherkin_documents, compiler)
|
11
|
+
parser = Core::Gherkin::Parser.new(compiler)
|
12
|
+
gherkin_documents.each do |document|
|
13
|
+
parser.document document
|
14
|
+
end
|
15
|
+
parser.done
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def compile(gherkin_documents, last_receiver, filters = [])
|
20
|
+
first_receiver = filters.reduce(last_receiver) do |receiver, (filter_type, args)|
|
21
|
+
filter_type.new(*args + [receiver])
|
22
|
+
end
|
23
|
+
compiler = Compiler.new(first_receiver)
|
24
|
+
parse gherkin_documents, compiler
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def execute(gherkin_documents, mappings, report, filters = [], run_options = {})
|
29
|
+
receiver = Test::Runner.new(report, run_options)
|
30
|
+
filters << [Test::HookCompiler, [mappings]]
|
31
|
+
filters << [Test::Mapper, [mappings]]
|
32
|
+
compile gherkin_documents, receiver, filters
|
33
|
+
self
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'cucumber/core/ast/comment'
|
2
|
+
require 'cucumber/core/ast/tag'
|
3
|
+
require 'cucumber/core/ast/feature'
|
4
|
+
require 'cucumber/core/ast/empty_background'
|
5
|
+
require 'cucumber/core/ast/background'
|
6
|
+
require 'cucumber/core/ast/scenario'
|
7
|
+
require 'cucumber/core/ast/step'
|
8
|
+
require 'cucumber/core/ast/multiline_argument'
|
9
|
+
require 'cucumber/core/ast/doc_string'
|
10
|
+
require 'cucumber/core/ast/data_table'
|
11
|
+
require 'cucumber/core/ast/scenario_outline'
|
12
|
+
require 'cucumber/core/ast/outline_step'
|
13
|
+
require 'cucumber/core/ast/examples_table'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'cucumber/initializer'
|
2
|
+
require 'cucumber/core/ast/names'
|
3
|
+
require 'cucumber/core/ast/location'
|
4
|
+
require 'cucumber/core/ast/describes_itself'
|
5
|
+
|
6
|
+
module Cucumber
|
7
|
+
module Core
|
8
|
+
module Ast
|
9
|
+
class Background
|
10
|
+
include Names
|
11
|
+
include HasLocation
|
12
|
+
include DescribesItself
|
13
|
+
|
14
|
+
include Cucumber.initializer(:gherkin_statement, :language, :location, :comments, :keyword, :title, :description, :raw_steps)
|
15
|
+
|
16
|
+
attr_accessor :feature
|
17
|
+
attr_accessor :comments, :keyword, :location
|
18
|
+
attr_reader :gherkin_statement
|
19
|
+
|
20
|
+
def children
|
21
|
+
raw_steps
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def description_for_visitors
|
27
|
+
:background
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'cucumber/initializer'
|
2
|
+
require 'cucumber/core/ast/location'
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
module Core
|
6
|
+
module Ast
|
7
|
+
class Comment
|
8
|
+
include HasLocation
|
9
|
+
include Cucumber.initializer :location, :value
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,326 @@
|
|
1
|
+
require 'gherkin/rubify'
|
2
|
+
require 'gherkin/lexer/i18n_lexer'
|
3
|
+
require 'gherkin/formatter/escaping'
|
4
|
+
require 'cucumber/core/ast/describes_itself'
|
5
|
+
require 'cucumber/core/ast/location'
|
6
|
+
|
7
|
+
module Cucumber
|
8
|
+
module Core
|
9
|
+
module Ast
|
10
|
+
# Step Definitions that match a plain text Step with a multiline argument table
|
11
|
+
# will receive it as an instance of DataTable. A DataTable object holds the data of a
|
12
|
+
# table parsed from a feature file and lets you access and manipulate the data
|
13
|
+
# in different ways.
|
14
|
+
#
|
15
|
+
# For example:
|
16
|
+
#
|
17
|
+
# Given I have:
|
18
|
+
# | a | b |
|
19
|
+
# | c | d |
|
20
|
+
#
|
21
|
+
# And a matching StepDefinition:
|
22
|
+
#
|
23
|
+
# Given /I have:/ do |table|
|
24
|
+
# data = table.raw
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# This will store <tt>[['a', 'b'], ['c', 'd']]</tt> in the <tt>data</tt> variable.
|
28
|
+
#
|
29
|
+
class DataTable
|
30
|
+
include DescribesItself
|
31
|
+
include HasLocation
|
32
|
+
|
33
|
+
class Builder
|
34
|
+
attr_reader :rows
|
35
|
+
|
36
|
+
def initialize
|
37
|
+
@rows = []
|
38
|
+
end
|
39
|
+
|
40
|
+
def row(row, line_number)
|
41
|
+
@rows << row
|
42
|
+
end
|
43
|
+
|
44
|
+
def eof
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
include ::Gherkin::Rubify
|
49
|
+
|
50
|
+
NULL_CONVERSIONS = Hash.new({ :strict => false, :proc => lambda{ |cell_value| cell_value } }).freeze
|
51
|
+
|
52
|
+
attr_accessor :file
|
53
|
+
|
54
|
+
def self.default_arg_name #:nodoc:
|
55
|
+
"table"
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.parse(text, uri, location)
|
59
|
+
builder = Builder.new
|
60
|
+
lexer = ::Gherkin::Lexer::I18nLexer.new(builder)
|
61
|
+
lexer.scan(text)
|
62
|
+
new(builder.rows, location)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Creates a new instance. +raw+ should be an Array of Array of String
|
66
|
+
# or an Array of Hash
|
67
|
+
# You don't typically create your own DataTable objects - Cucumber will do
|
68
|
+
# it internally and pass them to your Step Definitions.
|
69
|
+
#
|
70
|
+
def initialize(raw, location)
|
71
|
+
@cells_class = Cells
|
72
|
+
@cell_class = Cell
|
73
|
+
raw = ensure_array_of_array(rubify(raw))
|
74
|
+
# Verify that it's square
|
75
|
+
raw.transpose
|
76
|
+
create_cell_matrix(raw)
|
77
|
+
@location = location
|
78
|
+
end
|
79
|
+
|
80
|
+
def to_step_definition_arg
|
81
|
+
dup
|
82
|
+
end
|
83
|
+
|
84
|
+
# Creates a copy of this table
|
85
|
+
#
|
86
|
+
def dup
|
87
|
+
self.class.new(raw.dup, location)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Returns a new, transposed table. Example:
|
91
|
+
#
|
92
|
+
# | a | 7 | 4 |
|
93
|
+
# | b | 9 | 2 |
|
94
|
+
#
|
95
|
+
# Gets converted into the following:
|
96
|
+
#
|
97
|
+
# | a | b |
|
98
|
+
# | 7 | 9 |
|
99
|
+
# | 4 | 2 |
|
100
|
+
#
|
101
|
+
def transpose
|
102
|
+
self.class.new(raw.transpose, location)
|
103
|
+
end
|
104
|
+
|
105
|
+
def map(&block)
|
106
|
+
new_raw = raw.map do |row|
|
107
|
+
row.map(&block)
|
108
|
+
end
|
109
|
+
|
110
|
+
self.class.new(new_raw, location)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Converts this table into an Array of Hash where the keys of each
|
114
|
+
# Hash are the headers in the table. For example, a DataTable built from
|
115
|
+
# the following plain text:
|
116
|
+
#
|
117
|
+
# | a | b | sum |
|
118
|
+
# | 2 | 3 | 5 |
|
119
|
+
# | 7 | 9 | 16 |
|
120
|
+
#
|
121
|
+
# Gets converted into the following:
|
122
|
+
#
|
123
|
+
# [{'a' => '2', 'b' => '3', 'sum' => '5'}, {'a' => '7', 'b' => '9', 'sum' => '16'}]
|
124
|
+
#
|
125
|
+
def hashes
|
126
|
+
build_hashes
|
127
|
+
end
|
128
|
+
|
129
|
+
# Converts this table into a Hash where the first column is
|
130
|
+
# used as keys and the second column is used as values
|
131
|
+
#
|
132
|
+
# | a | 2 |
|
133
|
+
# | b | 3 |
|
134
|
+
#
|
135
|
+
# Gets converted into the following:
|
136
|
+
#
|
137
|
+
# {'a' => '2', 'b' => '3'}
|
138
|
+
#
|
139
|
+
# The table must be exactly two columns wide
|
140
|
+
#
|
141
|
+
def rows_hash
|
142
|
+
verify_table_width(2)
|
143
|
+
self.transpose.hashes[0]
|
144
|
+
end
|
145
|
+
|
146
|
+
# Gets the raw data of this table. For example, a DataTable built from
|
147
|
+
# the following plain text:
|
148
|
+
#
|
149
|
+
# | a | b |
|
150
|
+
# | c | d |
|
151
|
+
#
|
152
|
+
# gets converted into the following:
|
153
|
+
#
|
154
|
+
# [['a', 'b'], ['c', 'd']]
|
155
|
+
#
|
156
|
+
def raw
|
157
|
+
cell_matrix.map do |row|
|
158
|
+
row.map do |cell|
|
159
|
+
cell.value
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def column_names #:nodoc:
|
165
|
+
cell_matrix[0].map { |cell| cell.value }
|
166
|
+
end
|
167
|
+
|
168
|
+
def rows
|
169
|
+
hashes.map do |hash|
|
170
|
+
hash.values_at(*headers)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# For testing only
|
175
|
+
def to_sexp #:nodoc:
|
176
|
+
[:table, *cells_rows.map{|row| row.to_sexp}]
|
177
|
+
end
|
178
|
+
|
179
|
+
def to_hash(cells) #:nodoc:
|
180
|
+
hash = Hash.new do |the_hash, key|
|
181
|
+
the_hash[key.to_s] if key.is_a?(Symbol)
|
182
|
+
end
|
183
|
+
column_names.each_with_index do |column_name, column_index|
|
184
|
+
hash[column_name] = cells.value(column_index)
|
185
|
+
end
|
186
|
+
hash
|
187
|
+
end
|
188
|
+
|
189
|
+
def verify_table_width(width) #:nodoc:
|
190
|
+
raise %{The table must have exactly #{width} columns} unless raw[0].size == width
|
191
|
+
end
|
192
|
+
|
193
|
+
def cells_rows #:nodoc:
|
194
|
+
cell_matrix.map do |cell_row|
|
195
|
+
@cells_class.new(self, cell_row)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def headers #:nodoc:
|
200
|
+
raw.first
|
201
|
+
end
|
202
|
+
|
203
|
+
def cell_matrix #:nodoc:
|
204
|
+
@cell_matrix
|
205
|
+
end
|
206
|
+
|
207
|
+
def col_width(col) #:nodoc:
|
208
|
+
columns[col].__send__(:width)
|
209
|
+
end
|
210
|
+
|
211
|
+
def ==(other)
|
212
|
+
other.class == self.class && raw == other.raw
|
213
|
+
end
|
214
|
+
|
215
|
+
def inspect
|
216
|
+
raw.inspect
|
217
|
+
end
|
218
|
+
|
219
|
+
private
|
220
|
+
|
221
|
+
TO_S_PREFIXES = Hash.new(' ')
|
222
|
+
TO_S_PREFIXES[:comment] = '(+) '
|
223
|
+
TO_S_PREFIXES[:undefined] = '(-) '
|
224
|
+
|
225
|
+
def build_hashes
|
226
|
+
cells_rows[1..-1].map do |row|
|
227
|
+
row.to_hash
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def create_cell_matrix(raw) #:nodoc:
|
232
|
+
@cell_matrix = raw.map do |raw_row|
|
233
|
+
line = raw_row.line rescue -1
|
234
|
+
raw_row.map do |raw_cell|
|
235
|
+
new_cell(raw_cell, line)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def columns #:nodoc:
|
241
|
+
cell_matrix.transpose.map do |cell_row|
|
242
|
+
@cells_class.new(self, cell_row)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def new_cell(raw_cell, line) #:nodoc:
|
247
|
+
@cell_class.new(raw_cell, self, line)
|
248
|
+
end
|
249
|
+
|
250
|
+
def ensure_array_of_array(array)
|
251
|
+
Hash === array[0] ? hashes_to_array(array) : array
|
252
|
+
end
|
253
|
+
|
254
|
+
def hashes_to_array(hashes) #:nodoc:
|
255
|
+
header = hashes[0].keys.sort
|
256
|
+
[header] + hashes.map{|hash| header.map{|key| hash[key]}}
|
257
|
+
end
|
258
|
+
|
259
|
+
def description_for_visitors
|
260
|
+
:table
|
261
|
+
end
|
262
|
+
|
263
|
+
# Represents a row of cells or columns of cells
|
264
|
+
class Cells #:nodoc:
|
265
|
+
include Enumerable
|
266
|
+
include Gherkin::Formatter::Escaping
|
267
|
+
|
268
|
+
attr_reader :exception
|
269
|
+
|
270
|
+
def initialize(table, cells)
|
271
|
+
@table, @cells = table, cells
|
272
|
+
end
|
273
|
+
|
274
|
+
# For testing only
|
275
|
+
def to_sexp #:nodoc:
|
276
|
+
[:row, line, *@cells.map{|cell| cell.to_sexp}]
|
277
|
+
end
|
278
|
+
|
279
|
+
def to_hash #:nodoc:
|
280
|
+
@to_hash ||= @table.to_hash(self)
|
281
|
+
end
|
282
|
+
|
283
|
+
def value(n) #:nodoc:
|
284
|
+
self[n].value
|
285
|
+
end
|
286
|
+
|
287
|
+
def [](n)
|
288
|
+
@cells[n]
|
289
|
+
end
|
290
|
+
|
291
|
+
def line
|
292
|
+
@cells[0].line
|
293
|
+
end
|
294
|
+
|
295
|
+
private
|
296
|
+
|
297
|
+
def width
|
298
|
+
map{|cell| cell.value ? escape_cell(cell.value.to_s).unpack('U*').length : 0}.max
|
299
|
+
end
|
300
|
+
|
301
|
+
def each(&proc)
|
302
|
+
@cells.each(&proc)
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
class Cell #:nodoc:
|
307
|
+
attr_reader :line, :table
|
308
|
+
attr_accessor :status, :value
|
309
|
+
|
310
|
+
def initialize(value, table, line)
|
311
|
+
@value, @table, @line = value, table, line
|
312
|
+
end
|
313
|
+
|
314
|
+
def inspect!
|
315
|
+
@value = "(i) #{value.inspect}"
|
316
|
+
end
|
317
|
+
|
318
|
+
# For testing only
|
319
|
+
def to_sexp #:nodoc:
|
320
|
+
[:cell, @value]
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|