active_cucumber 1.0.0 → 1.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 +5 -5
- data/.github/workflows/ruby.yml +28 -0
- data/.rubocop.yml +12 -24
- data/.ruby-version +1 -0
- data/CHANGELOG.md +73 -0
- data/DEVELOPMENT.md +14 -0
- data/Gemfile +17 -2
- data/Gemfile.lock +132 -110
- data/LICENSE.txt +1 -1
- data/README.md +63 -76
- data/Rakefile +15 -18
- data/active_cucumber.gemspec +22 -27
- data/cucumber.yml +1 -0
- data/documentation/horizontal_diff.png +0 -0
- data/documentation/vertical_diff.png +0 -0
- data/dprint.json +11 -0
- data/features/active_cucumber/attributes_for.feature +2 -12
- data/features/active_cucumber/create_many.feature +7 -13
- data/features/active_cucumber/create_one.feature +5 -9
- data/features/active_cucumber/diff_all/arrays_of_objects.feature +2 -11
- data/features/active_cucumber/diff_all/context_values.feature +1 -10
- data/features/active_cucumber/diff_all/converting_data.feature +4 -13
- data/features/active_cucumber/diff_all/filtering_columns.feature +2 -11
- data/features/active_cucumber/diff_all/filtering_rows.feature +2 -13
- data/features/active_cucumber/diff_all/mismatching_data.feature +4 -14
- data/features/active_cucumber/diff_one.feature +8 -13
- data/features/step_definitions/steps.rb +16 -15
- data/features/support/director.rb +2 -0
- data/features/support/env.rb +23 -25
- data/features/support/episode.rb +2 -0
- data/features/support/episode_creator.rb +6 -6
- data/features/support/episode_cucumberator.rb +2 -2
- data/features/support/genre.rb +2 -0
- data/features/support/show.rb +2 -0
- data/features/support/show_creator.rb +5 -4
- data/features/support/show_cucumberator.rb +3 -3
- data/features/support/subscription.rb +2 -0
- data/features/support/subscription_creator.rb +6 -6
- data/features/support/subscription_cucumberator.rb +4 -4
- data/lib/active_cucumber/active_record_builder.rb +26 -18
- data/lib/active_cucumber/creator.rb +44 -25
- data/lib/active_cucumber/cucumberator.rb +17 -15
- data/lib/active_cucumber/cucumparer.rb +13 -12
- data/lib/active_cucumber.rb +97 -25
- metadata +26 -166
- data/.coveralls.yml +0 -1
- data/circle.yml +0 -16
- data/cucumber_lint.yml +0 -13
data/README.md
CHANGED
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
[](https://github.com/kevgo/active_cucumber/actions/workflows/ruby.yml)
|
|
2
|
+
[](https://coveralls.io/github/kevgo/active_cucumber?branch=kg-coveralls)
|
|
3
3
|
|
|
4
4
|
High-level Cucumber helpers for performing
|
|
5
5
|
[ActiveRecord](http://guides.rubyonrails.org/active_record_basics.html)-based
|
|
6
6
|
database operations using Cucumber tables in tests.
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
## Installation
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
- add `gem 'active_cucumber'` to your Gemfile
|
|
11
|
+
- run `bundle install`
|
|
12
|
+
- make sure you have your
|
|
13
|
+
[FactoryBot factories](https://github.com/thoughtbot/factory_bot) set up and
|
|
14
|
+
loaded
|
|
15
15
|
|
|
16
16
|
## Creating database records
|
|
17
17
|
|
|
18
|
-
ActiveCucumber allows to create ActiveRecord objects from data in Cucumber
|
|
18
|
+
ActiveCucumber allows to create ActiveRecord objects from data in Cucumber
|
|
19
|
+
tables using [FactoryBot factories](https://github.com/thoughtbot/factory_bot).
|
|
19
20
|
|
|
20
21
|
Let's assume we have an application that stores TV shows and their episodes.
|
|
21
22
|
|
|
22
|
-
|
|
23
23
|
### Creating simple fields
|
|
24
24
|
|
|
25
|
-
Simple fields works out of the box. Let's say our tests contain this Cucumber
|
|
25
|
+
Simple fields works out of the box. Let's say our tests contain this Cucumber
|
|
26
|
+
table:
|
|
26
27
|
|
|
27
28
|
```cucumber
|
|
28
29
|
Given the episodes:
|
|
@@ -35,16 +36,15 @@ ActiveCucumber makes it trivially easy to implement this step:
|
|
|
35
36
|
|
|
36
37
|
```ruby
|
|
37
38
|
Given(/^the episodes:$/) do |table|
|
|
38
|
-
ActiveCucumber.create_many
|
|
39
|
+
ActiveCucumber.create_many(Episode, table)
|
|
39
40
|
end
|
|
40
41
|
```
|
|
41
42
|
|
|
42
|
-
|
|
43
43
|
### Transforming values
|
|
44
44
|
|
|
45
|
-
Let's say our data model also contains a `Series` class
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
Let's say our data model also contains a `Series` class (an episode belongs to a
|
|
46
|
+
series, and a series has many episodes). We want to also define (and if
|
|
47
|
+
necessary create) the series that an episode belongs to:
|
|
48
48
|
|
|
49
49
|
```cucumber
|
|
50
50
|
Given the episodes:
|
|
@@ -53,34 +53,33 @@ Given the episodes:
|
|
|
53
53
|
| Star Trek TNG | All Good Things |
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
ActiveCucumber doesn't require custom step definitions here.
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
ActiveCucumber doesn't require custom step definitions here. To make this work,
|
|
57
|
+
tell ActiveCucumber how to convert particular Cucumber table fields into
|
|
58
|
+
ActiveRecord attributes via a `Creator` class:
|
|
59
59
|
|
|
60
60
|
```ruby
|
|
61
61
|
class EpisodeCreator < ActiveCucumber::Creator
|
|
62
62
|
|
|
63
|
-
def value_for_series
|
|
64
|
-
Series.find_by(name: series_name) ||
|
|
63
|
+
def value_for_series(series_name)
|
|
64
|
+
Series.find_by(name: series_name) || FactoryBot.create(:series, name: series_name)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
end
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
-
ActiveCucumber automatically uses classes named `<class name>Creator`
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
ActiveCucumber automatically uses classes named `<class name>Creator` as creator
|
|
71
|
+
classes for the respective class. This class must have methods named
|
|
72
|
+
`value_for_<attribute name>`. They receive the value of the respective attribute
|
|
73
|
+
in the Cucumber table (a string), and return whatever value should be assigned
|
|
74
|
+
to that attribute on the ActiveRecord instance.
|
|
76
75
|
|
|
77
76
|
### Other columns
|
|
78
77
|
|
|
79
|
-
Cucumber tables can contain columns that provide other test data,
|
|
80
|
-
|
|
78
|
+
Cucumber tables can contain columns that provide other test data, and don't
|
|
79
|
+
correspond to attributes on the created object.
|
|
81
80
|
|
|
82
|
-
For example, let's say series belong to a `Genre` class that specifies
|
|
83
|
-
|
|
81
|
+
For example, let's say series belong to a `Genre` class that specifies the genre
|
|
82
|
+
that the series is in.
|
|
84
83
|
|
|
85
84
|
```cucumber
|
|
86
85
|
Given the episodes:
|
|
@@ -91,37 +90,34 @@ Given the episodes:
|
|
|
91
90
|
|
|
92
91
|
Implementing this with Creators is simple:
|
|
93
92
|
|
|
94
|
-
Creators decorate the data structure that
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
add or remove fields,
|
|
100
|
-
or store instance variables to be used later.
|
|
93
|
+
Creators decorate the data structure that is sent to FactoryBot to create the
|
|
94
|
+
record. This means `self` inside creator methods behaves like a Hash that is
|
|
95
|
+
pre-populated with the Cucumber table data. You can modify this hash, use other
|
|
96
|
+
field values, add or remove fields, or store instance variables to be used
|
|
97
|
+
later.
|
|
101
98
|
|
|
102
99
|
```ruby
|
|
103
100
|
class EpisodeCreator < ActiveCucumber::Creator
|
|
104
101
|
|
|
105
|
-
def value_for_genre
|
|
106
|
-
@genre = Genre.find_by(name: genre_name) ||
|
|
102
|
+
def value_for_genre(genre_name)
|
|
103
|
+
@genre = Genre.find_by(name: genre_name) || FactoryBot.create(:genre, name: genre_name)
|
|
107
104
|
delete :genre
|
|
108
105
|
end
|
|
109
106
|
|
|
110
|
-
def value_for_series
|
|
111
|
-
Series.find_by(name: series_name) ||
|
|
107
|
+
def value_for_series(series_name)
|
|
108
|
+
Series.find_by(name: series_name) || FactoryBot.create(:series, name: series_name, genre: @genre)
|
|
112
109
|
end
|
|
113
110
|
|
|
114
111
|
end
|
|
115
112
|
```
|
|
116
113
|
|
|
117
|
-
|
|
118
114
|
### Context values
|
|
119
115
|
|
|
120
116
|
You can provide extra values to ActiveCucumber that are available as instance
|
|
121
117
|
variables on your creators.
|
|
122
118
|
|
|
123
|
-
Let's say our system has subscriptions for series, and we want to be able to
|
|
124
|
-
|
|
119
|
+
Let's say our system has subscriptions for series, and we want to be able to use
|
|
120
|
+
the currently logged in user in them:
|
|
125
121
|
|
|
126
122
|
```cucumber
|
|
127
123
|
Given the subscriptions:
|
|
@@ -129,11 +125,12 @@ Given the subscriptions:
|
|
|
129
125
|
| me | Star Trek TNG |
|
|
130
126
|
```
|
|
131
127
|
|
|
132
|
-
The currently logged in user can be provided to ActiveCucumber using the
|
|
128
|
+
The currently logged in user can be provided to ActiveCucumber using the
|
|
129
|
+
`context` parameter:
|
|
133
130
|
|
|
134
131
|
```ruby
|
|
135
132
|
Given(/^the subscriptions:$/) do |table|
|
|
136
|
-
ActiveCucumber.create_many
|
|
133
|
+
ActiveCucumber.create_many(Subscription, table, context: { logged_in_user: @current_user })
|
|
137
134
|
end
|
|
138
135
|
```
|
|
139
136
|
|
|
@@ -142,18 +139,17 @@ In the Creator, the context is available as instance variables:
|
|
|
142
139
|
```ruby
|
|
143
140
|
class SubscriptionCreator < ActiveCucumber::Creator
|
|
144
141
|
|
|
145
|
-
def value_for_subscriber
|
|
142
|
+
def value_for_subscriber(subscriber_name)
|
|
146
143
|
subscriber_name == 'me' ? @logged_in_user : subscriber_name
|
|
147
144
|
end
|
|
148
145
|
|
|
149
146
|
end
|
|
150
147
|
```
|
|
151
148
|
|
|
152
|
-
|
|
153
149
|
### Retrieving record attributes
|
|
154
150
|
|
|
155
|
-
If you want to create the database record yourself,
|
|
156
|
-
|
|
151
|
+
If you want to create the database record yourself, you can have ActiveCucumber
|
|
152
|
+
parse a Cucumber table into an attributes hash by calling
|
|
157
153
|
|
|
158
154
|
```ruby
|
|
159
155
|
ActiveCucumber.attributes_for <class>, table
|
|
@@ -161,15 +157,11 @@ ActiveCucumber.attributes_for <class>, table
|
|
|
161
157
|
|
|
162
158
|
with a vertical Cucumber table.
|
|
163
159
|
|
|
164
|
-
|
|
165
160
|
## Verifying database records
|
|
166
161
|
|
|
167
|
-
ActiveCucumber allows to compare ActiveRecord objects
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
Only the attributes provided in the table are compared,
|
|
171
|
-
the ones not listed are ignored.
|
|
172
|
-
|
|
162
|
+
ActiveCucumber allows to compare ActiveRecord objects against Cucumber tables,
|
|
163
|
+
with the differences visualized intuitively as a Cucumber table diff. Only the
|
|
164
|
+
attributes provided in the table are compared, the ones not listed are ignored.
|
|
173
165
|
|
|
174
166
|
### diff_one!
|
|
175
167
|
|
|
@@ -179,9 +171,8 @@ the ones not listed are ignored.
|
|
|
179
171
|
src="documentation/vertical_diff.png">
|
|
180
172
|
|
|
181
173
|
`ActiveCucumber.diff_one!` compares the given ActiveRecord entry with the given
|
|
182
|
-
_vertical_ Cucumber table.
|
|
183
|
-
|
|
184
|
-
a single record in greater detail.
|
|
174
|
+
_vertical_ Cucumber table. These tables have their headers on the left side, and
|
|
175
|
+
are used to describe a single record in greater detail.
|
|
185
176
|
|
|
186
177
|
```cucumber
|
|
187
178
|
When loading the last Star Trek TNG episode
|
|
@@ -196,11 +187,10 @@ The `Then` step is easy to implement with ActiveCucumber:
|
|
|
196
187
|
```ruby
|
|
197
188
|
Then /^it returns this episode:$/ do |table|
|
|
198
189
|
# @episode contains one loaded entry
|
|
199
|
-
ActiveCucumber.diff_one!
|
|
190
|
+
ActiveCucumber.diff_one!(@episode, table)
|
|
200
191
|
end
|
|
201
192
|
```
|
|
202
193
|
|
|
203
|
-
|
|
204
194
|
### diff_all!
|
|
205
195
|
|
|
206
196
|
<img width="431"
|
|
@@ -209,9 +199,8 @@ end
|
|
|
209
199
|
src="documentation/horizontal_diff.png">
|
|
210
200
|
|
|
211
201
|
`ActiveCucumber.diff_all!` verifies that the given _horizontal_ Cucumber table
|
|
212
|
-
describes all existing database entries of the given class.
|
|
213
|
-
|
|
214
|
-
records at once:
|
|
202
|
+
describes all existing database entries of the given class. Horizontal Cucumber
|
|
203
|
+
tables have their headers on top, and define several records at once:
|
|
215
204
|
|
|
216
205
|
```cucumber
|
|
217
206
|
When I run the importer script with parameter "count=3"
|
|
@@ -226,23 +215,21 @@ The last step would be implemented as:
|
|
|
226
215
|
|
|
227
216
|
```ruby
|
|
228
217
|
Then /^Then the database contains these episodes:$/ do |table|
|
|
229
|
-
ActiveCucumber.diff_all!
|
|
218
|
+
ActiveCucumber.diff_all!(Episode, table)
|
|
230
219
|
end
|
|
231
220
|
```
|
|
232
221
|
|
|
233
222
|
The Cucumber table should list the entries sorted by `created_at` timestamp.
|
|
234
223
|
|
|
235
|
-
|
|
236
224
|
### Cucumberators
|
|
237
225
|
|
|
238
|
-
ActiveCucumber converts the database records into a data table
|
|
239
|
-
|
|
226
|
+
ActiveCucumber converts the database records into a data table and matches it
|
|
227
|
+
against the given Cucumber table.
|
|
240
228
|
|
|
241
|
-
By default, all attributes are converted into a String.
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
for attribute values into the format used in the Cucumber table.
|
|
229
|
+
By default, all attributes are converted into a String. It is possible to
|
|
230
|
+
customize this conversion step by creating a _Cucumberator_ (short for Cucumber
|
|
231
|
+
Decorator). This class decorates an ActiveRecord instance, and defines
|
|
232
|
+
converters for attribute values into the format used in the Cucumber table.
|
|
246
233
|
|
|
247
234
|
```ruby
|
|
248
235
|
class EpisodeCucumberator < Cucumberator
|
|
@@ -256,5 +243,5 @@ class EpisodeCucumberator < Cucumberator
|
|
|
256
243
|
end
|
|
257
244
|
```
|
|
258
245
|
|
|
259
|
-
ActiveCucumber automatically finds and uses these Cucumberators if this
|
|
260
|
-
|
|
246
|
+
ActiveCucumber automatically finds and uses these Cucumberators if this naming
|
|
247
|
+
convention is followed.
|
data/Rakefile
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
require 'bundler/gem_tasks'
|
|
3
|
-
require 'cucumber'
|
|
4
|
-
require 'cucumber/rake/task'
|
|
1
|
+
# frozen_string_literal: true
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
require "bundler"
|
|
4
|
+
require "bundler/gem_tasks"
|
|
5
|
+
require "cucumber"
|
|
6
|
+
require "cucumber/rake/task"
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
task
|
|
8
|
+
Cucumber::Rake::Task.new :features
|
|
9
|
+
task default: [:lint, :features]
|
|
11
10
|
|
|
12
|
-
desc
|
|
13
|
-
task
|
|
14
|
-
sh
|
|
11
|
+
desc "Fix all auto-fixable issues"
|
|
12
|
+
task "fix" do
|
|
13
|
+
sh "bundle exec rubocop -A lib/*.rb lib/**/*.rb active_cucumber.gemspec", verbose: false
|
|
14
|
+
sh "dprint fmt", verbose: false
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
desc
|
|
18
|
-
task
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
# In particular, running "heroku run rake db:migrate"
|
|
22
|
-
# fails when JRuby is the active Ruby at this point.
|
|
23
|
-
sh 'bundle exec rubocop'
|
|
17
|
+
desc "Run linters"
|
|
18
|
+
task "lint" do
|
|
19
|
+
sh "bundle exec rubocop lib/*.rb lib/**/*.rb active_cucumber.gemspec", verbose: false
|
|
20
|
+
sh "dprint check", verbose: false
|
|
24
21
|
end
|
data/active_cucumber.gemspec
CHANGED
|
@@ -1,32 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
5
|
|
|
4
|
-
Gem::Specification.new do |
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
Gem::Specification.new do |gem|
|
|
7
|
+
gem.name = "active_cucumber"
|
|
8
|
+
gem.version = "1.1.0"
|
|
9
|
+
gem.authors = ["Kevin Goslar"]
|
|
10
|
+
gem.email = ["kevin.goslar@gmail.com"]
|
|
11
|
+
gem.summary = "ActiveRecord tools for Cucumber"
|
|
12
|
+
gem.description = "Tools to compare ActiveRecord entries with Cucumber tables"
|
|
13
|
+
gem.homepage = "https://github.com/kevgo/active_cucumber"
|
|
14
|
+
gem.license = "MIT"
|
|
15
|
+
|
|
16
|
+
gem.files = `git ls-files -z`.split("\x0")
|
|
17
|
+
gem.require_paths = ["lib"]
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
s.require_paths = ['lib']
|
|
19
|
+
gem.required_ruby_version = ">= 3.2"
|
|
20
|
+
gem.metadata["rubygems_mfa_required"] = "true"
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
s.add_development_dependency 'factory_girl'
|
|
24
|
-
s.add_development_dependency 'faker'
|
|
25
|
-
s.add_development_dependency 'kappamaki'
|
|
26
|
-
s.add_development_dependency 'mortadella'
|
|
27
|
-
s.add_development_dependency 'rake'
|
|
28
|
-
s.add_development_dependency 'rubocop'
|
|
29
|
-
s.add_development_dependency 'rspec'
|
|
30
|
-
s.add_development_dependency 'rspec-collection_matchers'
|
|
31
|
-
s.add_development_dependency 'sqlite3'
|
|
22
|
+
# Runtime dependencies
|
|
23
|
+
gem.add_dependency "activerecord", ">= 6.0"
|
|
24
|
+
gem.add_dependency "cucumber", ">= 7.0"
|
|
25
|
+
gem.add_dependency "factory_bot", ">= 5.0"
|
|
26
|
+
gem.add_dependency "mortadella", ">= 1.0"
|
|
32
27
|
end
|
data/cucumber.yml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
default: --publish-quiet
|
|
Binary file
|
|
Binary file
|
data/dprint.json
ADDED
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
Feature: ActiveCucumber.attributes_for
|
|
2
2
|
|
|
3
|
-
As a developer testing my own record create code
|
|
4
|
-
I want to be able to convert Cucumber tables into attribute hashes
|
|
5
|
-
So that I can use ActiveCucumber to parse Cucumber tables.
|
|
6
|
-
|
|
7
|
-
Rules:
|
|
8
|
-
- ActiveCucumbe.attributes_for(Class, table) returns the attributes of the given table as a hash
|
|
9
|
-
- the creator for this class is used to parse attributes in the Cucumber table
|
|
10
|
-
- related objects are getting created in the database
|
|
11
|
-
|
|
12
|
-
|
|
13
3
|
Scenario: data attributes
|
|
14
|
-
When running "ActiveCucumber.attributes_for
|
|
4
|
+
When running "ActiveCucumber.attributes_for(Episode, table)" with this table:
|
|
15
5
|
| NAME | Encounter at Farpoint |
|
|
16
6
|
Then it returns the hash
|
|
17
7
|
"""
|
|
@@ -24,7 +14,7 @@ Feature: ActiveCucumber.attributes_for
|
|
|
24
14
|
|
|
25
15
|
|
|
26
16
|
Scenario: associated objects are built
|
|
27
|
-
When running "ActiveCucumber.attributes_for
|
|
17
|
+
When running "ActiveCucumber.attributes_for(Episode, table)" with this table:
|
|
28
18
|
| SHOW | Star Trek TNG |
|
|
29
19
|
| NAME | Encounter at Farpoint |
|
|
30
20
|
Then it returns the hash
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
Feature: ActiveCucumber.create_many
|
|
2
2
|
|
|
3
|
-
As a Cucumber user
|
|
4
|
-
I want to create database records using Cucumber tables
|
|
5
|
-
So that I can easily and intuitively set up my test environment.
|
|
6
|
-
|
|
7
|
-
|
|
8
3
|
Scenario: creating string columns
|
|
9
|
-
When running "ActiveCucumber.create_many
|
|
4
|
+
When running "ActiveCucumber.create_many(Episode, table)" with this table:
|
|
10
5
|
| NAME |
|
|
11
6
|
| Encounter at Farpoint |
|
|
12
7
|
| All Good Things |
|
|
@@ -14,7 +9,7 @@ Feature: ActiveCucumber.create_many
|
|
|
14
9
|
|
|
15
10
|
|
|
16
11
|
Scenario: creating integer columns
|
|
17
|
-
When running "ActiveCucumber.create_many
|
|
12
|
+
When running "ActiveCucumber.create_many(Episode, table)" with this table:
|
|
18
13
|
| YEAR |
|
|
19
14
|
| 1987 |
|
|
20
15
|
| 1994 |
|
|
@@ -22,7 +17,7 @@ Feature: ActiveCucumber.create_many
|
|
|
22
17
|
|
|
23
18
|
|
|
24
19
|
Scenario: creating associated objects
|
|
25
|
-
When running "ActiveCucumber.create_many
|
|
20
|
+
When running "ActiveCucumber.create_many(Episode, table)" with this table:
|
|
26
21
|
| SHOW | NAME |
|
|
27
22
|
| Star Trek TNG | Encounter at Farpoint |
|
|
28
23
|
| Star Trek TNG | All Good Things |
|
|
@@ -31,7 +26,7 @@ Feature: ActiveCucumber.create_many
|
|
|
31
26
|
|
|
32
27
|
|
|
33
28
|
Scenario: creating associated objects with a nil value
|
|
34
|
-
When running "ActiveCucumber.create_many
|
|
29
|
+
When running "ActiveCucumber.create_many(Show, table)" with this table:
|
|
35
30
|
| DIRECTOR | NAME |
|
|
36
31
|
| | Directionless |
|
|
37
32
|
| Gene Roddenberry | Star Trek TNG |
|
|
@@ -40,7 +35,7 @@ Feature: ActiveCucumber.create_many
|
|
|
40
35
|
|
|
41
36
|
|
|
42
37
|
Scenario: creating associated objects that depend on other associated objects
|
|
43
|
-
When running "ActiveCucumber.create_many
|
|
38
|
+
When running "ActiveCucumber.create_many(Episode, table)" with this table:
|
|
44
39
|
| GENRE | SHOW | NAME |
|
|
45
40
|
| Science Fiction | Star Trek TNG | Encounter at Farpoint |
|
|
46
41
|
| Science Fiction | Star Trek TNG | All Good Things |
|
|
@@ -54,7 +49,7 @@ Feature: ActiveCucumber.create_many
|
|
|
54
49
|
|
|
55
50
|
|
|
56
51
|
Scenario: using context values
|
|
57
|
-
When running "ActiveCucumber.create_many
|
|
52
|
+
When running "ActiveCucumber.create_many(Subscription, table, context: { current_user: 'Q' })" with this table:
|
|
58
53
|
| SUBSCRIBER | SHOW |
|
|
59
54
|
| me | Star Trek TNG |
|
|
60
55
|
Then the database contains the subscriptions:
|
|
@@ -63,10 +58,9 @@ Feature: ActiveCucumber.create_many
|
|
|
63
58
|
|
|
64
59
|
|
|
65
60
|
Scenario: complex example
|
|
66
|
-
When running "ActiveCucumber.create_many
|
|
61
|
+
When running "ActiveCucumber.create_many(Episode, table)" with this table:
|
|
67
62
|
| SHOW | NAME | YEAR |
|
|
68
63
|
| Star Trek TNG | Encounter at Farpoint | 1987 |
|
|
69
64
|
| Star Trek TOS | The Paradise Syndrome | 1968 |
|
|
70
65
|
Then the database contains the given episodes
|
|
71
66
|
And the database contains the shows "Star Trek TNG" and "Star Trek TOS"
|
|
72
|
-
|
|
@@ -1,22 +1,19 @@
|
|
|
1
1
|
Feature: ActiveCucumber.create_one
|
|
2
2
|
|
|
3
|
-
(see ./create_many.feature)
|
|
4
|
-
|
|
5
|
-
|
|
6
3
|
Scenario: creating string columns
|
|
7
|
-
When running "ActiveCucumber.create_one
|
|
4
|
+
When running "ActiveCucumber.create_one(Episode, table)" with this table:
|
|
8
5
|
| NAME | Encounter at Farpoint |
|
|
9
6
|
Then the database contains the given episode
|
|
10
7
|
|
|
11
8
|
|
|
12
9
|
Scenario: creating integer columns
|
|
13
|
-
When running "ActiveCucumber.create_one
|
|
10
|
+
When running "ActiveCucumber.create_one(Episode, table)" with this table:
|
|
14
11
|
| YEAR | 1994 |
|
|
15
12
|
Then the database contains the given episode
|
|
16
13
|
|
|
17
14
|
|
|
18
15
|
Scenario: creating associated objects
|
|
19
|
-
When running "ActiveCucumber.create_one
|
|
16
|
+
When running "ActiveCucumber.create_one(Episode, table)" with this table:
|
|
20
17
|
| SHOW | Star Trek TNG |
|
|
21
18
|
| NAME | Encounter at Farpoint |
|
|
22
19
|
Then the database contains the given episode
|
|
@@ -24,7 +21,7 @@ Feature: ActiveCucumber.create_one
|
|
|
24
21
|
|
|
25
22
|
|
|
26
23
|
Scenario: using context values
|
|
27
|
-
When running "ActiveCucumber.create_one
|
|
24
|
+
When running "ActiveCucumber.create_one(Subscription, table, context: { current_user: 'Q' })" with this table:
|
|
28
25
|
| SUBSCRIBER | me |
|
|
29
26
|
| SHOW | Star Trek TNG |
|
|
30
27
|
Then the database contains the subscriptions:
|
|
@@ -33,10 +30,9 @@ Feature: ActiveCucumber.create_one
|
|
|
33
30
|
|
|
34
31
|
|
|
35
32
|
Scenario: complex example
|
|
36
|
-
When running "ActiveCucumber.create_one
|
|
33
|
+
When running "ActiveCucumber.create_one(Episode, table)" with this table:
|
|
37
34
|
| SHOW | Star Trek TNG |
|
|
38
35
|
| NAME | Encounter at Farpoint |
|
|
39
36
|
| YEAR | 1987 |
|
|
40
37
|
Then the database contains the given episode
|
|
41
38
|
And the database contains the show "Star Trek TNG"
|
|
42
|
-
|
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
Feature: Comparing arrays of ActiveRecord instances
|
|
2
2
|
|
|
3
|
-
As a developer having complex database query logic
|
|
4
|
-
I want to be able to compare against a manually created array of ActiveRecord objects
|
|
5
|
-
So that I can use ActiveCucumber for a large variety of data sources.
|
|
6
|
-
|
|
7
|
-
Rules:
|
|
8
|
-
- one can give an ActiveRecord class or an array of ActiveRecord instances to ActiveCucumber
|
|
9
|
-
- ActiveCucumber choses the Cucumperer based on the class of each record
|
|
10
|
-
|
|
11
|
-
|
|
12
3
|
Background:
|
|
13
4
|
Given the episodes:
|
|
14
5
|
| NAME | YEAR |
|
|
@@ -17,7 +8,7 @@ Feature: Comparing arrays of ActiveRecord instances
|
|
|
17
8
|
|
|
18
9
|
|
|
19
10
|
Scenario: comparing all instances of an ActiveRecord class
|
|
20
|
-
When running "ActiveCucumber.diff_all!
|
|
11
|
+
When running "ActiveCucumber.diff_all!(Episode, table)" with this table:
|
|
21
12
|
| NAME | YEAR |
|
|
22
13
|
| Encounter at Farpoint | 1987 |
|
|
23
14
|
| All Good Things | 1994 |
|
|
@@ -25,7 +16,7 @@ Feature: Comparing arrays of ActiveRecord instances
|
|
|
25
16
|
|
|
26
17
|
|
|
27
18
|
Scenario: comparing an array of ActiveRecord instances
|
|
28
|
-
When running "ActiveCucumber.diff_all!
|
|
19
|
+
When running "ActiveCucumber.diff_all!([Episode.first, Episode.last], table)" with this table:
|
|
29
20
|
| NAME | YEAR |
|
|
30
21
|
| Encounter at Farpoint | 1987 |
|
|
31
22
|
| All Good Things | 1994 |
|
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
Feature: Using contextual data
|
|
2
2
|
|
|
3
|
-
As a developer wanting to use non-database data in my database specs
|
|
4
|
-
I want to be able to provide contextual data to ActiveCucumber
|
|
5
|
-
So that I can use it in my specs.
|
|
6
|
-
|
|
7
|
-
Rules:
|
|
8
|
-
- contextual data is provided as an additional parameter containing key-value pairs in calls to ActiveCucumber
|
|
9
|
-
- all contextual data is made available to Cucumberators as instance variables whose name is the key and value is the value
|
|
10
|
-
|
|
11
|
-
|
|
12
3
|
Scenario: using contextual data
|
|
13
4
|
Given the subscriptions:
|
|
14
5
|
| SUBSCRIBER | SHOW |
|
|
15
6
|
| Q | Star Trek TNG |
|
|
16
|
-
When running "ActiveCucumber.diff_all!
|
|
7
|
+
When running "ActiveCucumber.diff_all!(Subscription, table, context: { current_user: 'Q' })" with this table:
|
|
17
8
|
| SUBSCRIBER | SHOW |
|
|
18
9
|
| me | Star Trek TNG |
|
|
19
10
|
Then the test passes
|
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
Feature: Comparing different field types
|
|
2
2
|
|
|
3
|
-
As a developer testing a relational database
|
|
4
|
-
I want to verify my database content and associations the same way
|
|
5
|
-
So that database verifications are intuitive.
|
|
6
|
-
|
|
7
|
-
Rules:
|
|
8
|
-
- the user can define a Cucumberator to define custom Cucumber representations of fields or associated records
|
|
9
|
-
- if the Cucumberator doesn't define a conversion or is missing altogether, the content is compared as-is
|
|
10
|
-
|
|
11
|
-
|
|
12
3
|
Background:
|
|
13
4
|
Given the episodes:
|
|
14
5
|
| SHOW | NAME | YEAR |
|
|
@@ -20,14 +11,14 @@ Feature: Comparing different field types
|
|
|
20
11
|
Given the genres:
|
|
21
12
|
| NAME |
|
|
22
13
|
| Science Fiction |
|
|
23
|
-
When running "ActiveCucumber.diff_all!
|
|
14
|
+
When running "ActiveCucumber.diff_all!(Genre, table)" with this table:
|
|
24
15
|
| NAME |
|
|
25
16
|
| Science Fiction |
|
|
26
17
|
Then the test passes
|
|
27
18
|
|
|
28
19
|
|
|
29
20
|
Scenario: verifying fields not defined in the Cucumberator
|
|
30
|
-
When running "ActiveCucumber.diff_all!
|
|
21
|
+
When running "ActiveCucumber.diff_all!(Episode, table)" with this table:
|
|
31
22
|
| NAME |
|
|
32
23
|
| Encounter at Farpoint |
|
|
33
24
|
| All Good Things |
|
|
@@ -35,7 +26,7 @@ Feature: Comparing different field types
|
|
|
35
26
|
|
|
36
27
|
|
|
37
28
|
Scenario: verifying numeric fields
|
|
38
|
-
When running "ActiveCucumber.diff_all!
|
|
29
|
+
When running "ActiveCucumber.diff_all!(Episode, table)" with this table:
|
|
39
30
|
| YEAR |
|
|
40
31
|
| 1987 |
|
|
41
32
|
| 1994 |
|
|
@@ -43,7 +34,7 @@ Feature: Comparing different field types
|
|
|
43
34
|
|
|
44
35
|
|
|
45
36
|
Scenario: verifying associated fields through a Cucumberator
|
|
46
|
-
When running "ActiveCucumber.diff_all!
|
|
37
|
+
When running "ActiveCucumber.diff_all!(Episode, table)" with this table:
|
|
47
38
|
| SHOW | NAME |
|
|
48
39
|
| Star Trek TNG | Encounter at Farpoint |
|
|
49
40
|
| Star Trek TNG | All Good Things |
|