active_cucumber 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 31fc83494b273be00aaa3b52b7d3376a31b86e55
4
- data.tar.gz: d1ca0c141ab1195f7e2cd8637dc993e2b57cb08b
3
+ metadata.gz: d79075dcae64e837aac60d1fcd14e2afdbd5e3cd
4
+ data.tar.gz: f44adf57d12377ea1751400a63469af2be5e350c
5
5
  SHA512:
6
- metadata.gz: c3d951e2e1ae6b2f2a401589d9c601bb0de1e470c0ddbbe3f4c516f1caa1d9a398500eac0e29b0dee8c4e0fe17db4b1c1df6c9887cbc5f017a11c6bef48a8d79
7
- data.tar.gz: 59146c0d3fc96562c18e45a16efbf7bfec5a4e4eb07cbf6fbf9e15bbc0b540f8ec8afd1f8504001cceea96f7e613ed8b633a8c1a53a9e3d7e6476c22483a5d41
6
+ metadata.gz: 9b644b362eaae699f43e408e9253bf331d7aad0787455a912af9196e8bd4d70b16f1f8aa0722a48a953639162b10b1fa49859d47bdfeba226170cfac582ef64d
7
+ data.tar.gz: 5a782c450a2166c849c258c64d5174ddae91328d0c8359a13452db7df81e58964bafe8a0819950d49540405d926a97b005aa8bf842504bc0ba55703bb993c6fb
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active_cucumber (0.0.1)
4
+ active_cucumber (0.0.2)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -24,6 +24,7 @@ GEM
24
24
  astrolabe (1.3.1)
25
25
  parser (~> 2.2)
26
26
  builder (3.2.2)
27
+ colorize (0.7.7)
27
28
  cucumber (2.1.0)
28
29
  builder (>= 2.1.2)
29
30
  cucumber-core (~> 1.3.0)
@@ -33,10 +34,21 @@ GEM
33
34
  multi_test (>= 0.1.2)
34
35
  cucumber-core (1.3.0)
35
36
  gherkin3 (~> 3.1.0)
37
+ cucumber_lint (0.1.2)
38
+ colorize (~> 0.7.7)
39
+ gherkin (~> 2.12.2)
40
+ multi_json (~> 1.11.2)
36
41
  diff-lcs (1.2.5)
42
+ factory_girl (4.5.0)
43
+ activesupport (>= 3.0.0)
44
+ faker (1.5.0)
45
+ i18n (~> 0.5)
46
+ gherkin (2.12.2)
47
+ multi_json (~> 1.3)
37
48
  gherkin3 (3.1.2)
38
49
  i18n (0.7.0)
39
50
  json (1.8.3)
51
+ kappamaki (0.0.3)
40
52
  minitest (5.8.1)
41
53
  mortadella (0.2.1)
42
54
  multi_json (1.11.2)
@@ -50,6 +62,8 @@ GEM
50
62
  rspec-core (~> 3.3.0)
51
63
  rspec-expectations (~> 3.3.0)
52
64
  rspec-mocks (~> 3.3.0)
65
+ rspec-collection_matchers (1.1.2)
66
+ rspec-expectations (>= 2.99.0.beta1)
53
67
  rspec-core (3.3.2)
54
68
  rspec-support (~> 3.3.0)
55
69
  rspec-expectations (3.3.1)
@@ -79,9 +93,14 @@ DEPENDENCIES
79
93
  activerecord
80
94
  bundler
81
95
  cucumber
96
+ cucumber_lint
97
+ factory_girl
98
+ faker
99
+ kappamaki
82
100
  mortadella
83
101
  rake
84
102
  rspec
103
+ rspec-collection_matchers
85
104
  rubocop
86
105
  sqlite3
87
106
 
data/README.md CHANGED
@@ -16,6 +16,11 @@ the ones not listed are ignored.
16
16
 
17
17
  ### diff_one!
18
18
 
19
+ <img width="385"
20
+ height="144"
21
+ alt="image of a mismatching vertical Cucumber table"
22
+ src="documentation/vertical_diff.png">
23
+
19
24
  `ActiveCucumber.diff_one!` compares the given ActiveRecord entry with the given
20
25
  _vertical_ Cucumber table.
21
26
  These tables have their headers on the left side, and are used to describe
@@ -41,6 +46,11 @@ end
41
46
 
42
47
  ### diff_all!
43
48
 
49
+ <img width="431"
50
+ height="95"
51
+ alt="image of a mismatching vertical Cucumber table"
52
+ src="documentation/horizontal_diff.png">
53
+
44
54
  `ActiveCucumber.diff_all!` verifies that the given _horizontal_ Cucumber table
45
55
  describes all existing database entries of the given class.
46
56
  Horizontal Cucumber tables have their headers on top, and define several
@@ -80,7 +90,8 @@ for attribute values into the format used in the Cucumber table.
80
90
  ```ruby
81
91
  class EpisodeCucumberator < Cucumberator
82
92
 
83
- # In the SHOW column, print the name of the show of the episode truncated
93
+ # In the SHOW column, print the name of the associated show object,
94
+ # truncated to 10 characters
84
95
  def value_of_show
85
96
  show.name.truncate 10
86
97
  end
data/Rakefile CHANGED
@@ -6,7 +6,19 @@ require 'cucumber/rake/task'
6
6
  Cucumber::Rake::Task.new :features
7
7
  task default: %i(lint features)
8
8
 
9
- desc 'Run linter'
10
- task 'lint' do
9
+ desc 'Run linters'
10
+ task lint: %w(lint:ruby lint:cucumber)
11
+
12
+ desc 'Run Cucumber linter'
13
+ task 'lint:cucumber' do
14
+ sh 'bundle exec cucumber_lint'
15
+ end
16
+
17
+ desc 'Run Ruby linter'
18
+ task 'lint:ruby' do
19
+ # NOTE: cannot use "task 'lint:ruby' => [:rubocop]" here,
20
+ # because the Heroku toolbelt has issues with JRuby.
21
+ # In particular, running "heroku run rake db:migrate"
22
+ # fails when JRuby is the active Ruby at this point.
11
23
  sh 'bundle exec rubocop'
12
24
  end
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'active_cucumber'
6
- s.version = '0.0.1'
6
+ s.version = '0.0.2'
7
7
  s.authors = ['Kevin Goslar']
8
8
  s.email = ['kevin.goslar@gmail.com']
9
9
  s.summary = %s(ActiveRecord tools for Cucumber)
@@ -18,9 +18,14 @@ Gem::Specification.new do |s|
18
18
  s.add_development_dependency 'activerecord'
19
19
  s.add_development_dependency 'bundler'
20
20
  s.add_development_dependency 'cucumber'
21
+ s.add_development_dependency 'cucumber_lint'
22
+ s.add_development_dependency 'factory_girl'
23
+ s.add_development_dependency 'faker'
24
+ s.add_development_dependency 'kappamaki'
21
25
  s.add_development_dependency 'mortadella'
22
26
  s.add_development_dependency 'rake'
23
27
  s.add_development_dependency 'rubocop'
24
28
  s.add_development_dependency 'rspec'
29
+ s.add_development_dependency 'rspec-collection_matchers'
25
30
  s.add_development_dependency 'sqlite3'
26
31
  end
data/cucumber_lint.yml ADDED
@@ -0,0 +1,13 @@
1
+ consistent_empty_lines:
2
+ enabled: true
3
+ between_description_and_element: 2
4
+ between_elements: 2
5
+ between_feature_and_description: 1
6
+ between_feature_and_element: 1
7
+ between_scenario_outline_and_examples: 1
8
+
9
+ consistent_table_whitespace:
10
+ enabled: false
11
+
12
+ consistent_table_headers:
13
+ enabled: false
Binary file
Binary file
@@ -0,0 +1,40 @@
1
+ Feature: ActiveCucumber.create_many
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
+ Scenario: creating string columns
9
+ When running "ActiveCucumber.create_many Episode, table" with this table:
10
+ | NAME |
11
+ | Encounter at Farpoint |
12
+ | All Good Things |
13
+ Then the database contains the given episodes
14
+
15
+
16
+ Scenario: creating integer columns
17
+ When running "ActiveCucumber.create_many Episode, table" with this table:
18
+ | YEAR |
19
+ | 1987 |
20
+ | 1994 |
21
+ Then the database contains the given episodes
22
+
23
+
24
+ Scenario: creating associated objects
25
+ When running "ActiveCucumber.create_many Episode, table" with this table:
26
+ | SHOW | NAME |
27
+ | Star Trek TNG | Encounter at Farpoint |
28
+ | Star Trek TNG | All Good Things |
29
+ Then the database contains the given episodes
30
+ And the database contains the show "Star Trek TNG"
31
+
32
+
33
+ Scenario: complex example
34
+ When running "ActiveCucumber.create_many Episode, table" with this table:
35
+ | SHOW | NAME | YEAR |
36
+ | Star Trek TNG | Encounter at Farpoint | 1987 |
37
+ | Star Trek TOS | The Paradise Syndrome | 1994 |
38
+ Then the database contains the given episodes
39
+ And the database contains the shows "Star Trek TNG" and "Star Trek TOS"
40
+
@@ -0,0 +1,33 @@
1
+ Feature: ActiveCucumber.create_one
2
+
3
+ (see ./create_many.feature)
4
+
5
+
6
+ Scenario: creating string columns
7
+ When running "ActiveCucumber.create_one Episode, table" with this table:
8
+ | NAME | Encounter at Farpoint |
9
+ Then the database contains the given episode
10
+
11
+
12
+ Scenario: creating integer columns
13
+ When running "ActiveCucumber.create_one Episode, table" with this table:
14
+ | YEAR | 1994 |
15
+ Then the database contains the given episode
16
+
17
+
18
+ Scenario: creating associated objects
19
+ When running "ActiveCucumber.create_one Episode, table" with this table:
20
+ | SHOW | Star Trek TNG |
21
+ | NAME | Encounter at Farpoint |
22
+ Then the database contains the given episode
23
+ And the database contains the show "Star Trek TNG"
24
+
25
+
26
+ Scenario: complex example
27
+ When running "ActiveCucumber.create_one Episode, table" with this table:
28
+ | SHOW | Star Trek TNG |
29
+ | NAME | Encounter at Farpoint |
30
+ | YEAR | 1987 |
31
+ Then the database contains the given episode
32
+ And the database contains the show "Star Trek TNG"
33
+
@@ -1,4 +1,4 @@
1
- Feature: Cucumparer.diff_all!
1
+ Feature: ActiveCucumber.diff_all!
2
2
 
3
3
  As a Cucumber user
4
4
  I want to verify all existing records using a Cucumber table
@@ -1,4 +1,4 @@
1
- Feature: Cucumparer.diff_one!
1
+ Feature: ActiveCucumber.diff_one!
2
2
 
3
3
  As a Cucumber user
4
4
  I want to verify a single record using a detailed Cucumber table
@@ -1,41 +1,55 @@
1
1
  Given(/^the TV episode:$/) do |table|
2
- data = table.rows_hash
2
+ data = ActiveCucumber.vertical_table table
3
3
  show = Show.find_or_create_by name: data['SHOW']
4
4
  @episode = show.episodes.create name: data['NAME'], year: data['YEAR']
5
5
  end
6
6
 
7
7
 
8
8
  Given(/^the TV episodes:$/) do |table|
9
- table.map_headers! { |header| header.downcase.to_sym }
10
- table.hashes.each do |row|
11
- show = Show.find_or_create_by name: row[:show]
12
- show.episodes.create name: row[:name], year: row[:year]
9
+ ActiveCucumber.horizontal_table(table).each do |row|
10
+ show = Show.find_or_create_by name: row['SHOW']
11
+ show.episodes.create name: row['NAME'], year: row['YEAR']
13
12
  end
14
13
  end
15
14
 
16
15
 
17
16
 
18
- # rubocop:disable Lint/UnusedBlockArgument
19
17
  Then(/^running "([^"]+)" with this table:$/) do |code, table|
18
+ @previous_table = table
20
19
  begin
21
- @exception = false
20
+ @error_happened = false
22
21
  @result = eval code
23
22
  rescue StandardError => e
24
- @exception = true
23
+ @error_happened = true
25
24
  @error_message = e.message
25
+ @exception = e
26
26
  end
27
27
  end
28
- # rubocop:enable Lint/UnusedBlockArgument
29
28
 
30
29
 
31
- Then(/^the test passes$/) do
32
- p @error_message if @expectation == true
33
- expect(@exception).to be false
30
+ Then(/^the database contains the given episode$/) do
31
+ expect(Episode).to have(1).instance
32
+ ActiveCucumber.diff_one! Episode.first, @previous_table
34
33
  end
35
34
 
36
35
 
37
- Then(/^the test fails$/) do
38
- expect(@exception).to be true
36
+ Then(/^the database contains the given episodes$/) do
37
+ ActiveCucumber.diff_all! Episode, @previous_table
38
+ end
39
+
40
+
41
+ Then(/^the database contains the shows? (.+)$/) do |show_names|
42
+ expect(Show.all.map(&:name)).to match Kappamaki.from_sentence show_names
43
+ end
44
+
45
+
46
+ Then(/^the test (passes|fails)$/) do |expected_result|
47
+ @error_checked = true
48
+ if expected_result == 'passes' && @error_happened
49
+ p @error_message
50
+ p @exception
51
+ end
52
+ expect(@error_happened).to be expected_result != 'passes'
39
53
  end
40
54
 
41
55
 
@@ -2,6 +2,10 @@ require 'active_record'
2
2
  require 'sqlite3'
3
3
  require 'mortadella'
4
4
  require 'active_cucumber'
5
+ require 'factory_girl'
6
+ require 'faker'
7
+ require 'kappamaki'
8
+ require 'rspec/collection_matchers'
5
9
 
6
10
 
7
11
  ActiveRecord::Base.establish_connection(
@@ -9,6 +13,7 @@ ActiveRecord::Base.establish_connection(
9
13
  database: ':memory:'
10
14
  )
11
15
 
16
+
12
17
  ActiveRecord::Schema.define do
13
18
  create_table :shows, force: true do |t|
14
19
  t.string :name
@@ -23,7 +28,26 @@ ActiveRecord::Schema.define do
23
28
  end
24
29
  end
25
30
 
31
+
32
+ FactoryGirl.define do
33
+ factory :show do
34
+ name { Faker::Book.title }
35
+ end
36
+
37
+ factory :episode do
38
+ name { Faker::Book.title }
39
+ year { 1960 + rand(40) }
40
+ show
41
+ end
42
+ end
43
+
44
+
26
45
  Before do
27
46
  Show.delete_all
28
47
  Episode.delete_all
48
+ @error_checked = false
49
+ end
50
+
51
+ After do
52
+ expect(@error_happened).to be false unless @error_checked
29
53
  end
@@ -0,0 +1,7 @@
1
+ class EpisodeCureator < ActiveCucumber::Cureator
2
+
3
+ def value_for_show show_name
4
+ Show.find_by(name: show_name) || FactoryGirl.create(:show, name: show_name)
5
+ end
6
+
7
+ end
@@ -0,0 +1,86 @@
1
+ module ActiveCucumber
2
+
3
+ # Creates ActiveRecord entries
4
+ class Cureator
5
+
6
+ # Returns the Cureator instance for the given ActiveRecord class.
7
+ def self.for activerecord_class
8
+ cureator_class(activerecord_class).new activerecord_class
9
+ end
10
+
11
+
12
+ def initialize activerecord_class
13
+ @clazz = activerecord_class
14
+ end
15
+
16
+
17
+ # Creates all entries in the given Cucumber table
18
+ #
19
+ # Assumes a horizontal Cucumber table.
20
+ def create_records table
21
+ table.each do |row|
22
+ create_record row
23
+ end
24
+ end
25
+
26
+
27
+ # Creates a new record in the database,
28
+ # of the given class, with the given Cucumber-formatted String attributes.
29
+ def create_record attributes
30
+ FactoryGirl.create @clazz, factorygirl_row(symbolized_hash(attributes))
31
+ end
32
+
33
+
34
+ private
35
+
36
+ # Returns the Cucumberator subclass to be used by this Cucumparer instance
37
+ def self.cureator_class activerecord_class
38
+ cureator_class_name(activerecord_class).constantize
39
+ rescue NameError
40
+ Cureator
41
+ end
42
+
43
+
44
+ # Returns the name of the Cucumberator subclass to be used by this Cucumparer instance.
45
+ def self.cureator_class_name activerecord_class
46
+ "#{activerecord_class.name}Cureator"
47
+ end
48
+
49
+
50
+ # Returns the given row, with values converted to FactoryGirl format
51
+ #
52
+ # Assumes the keys of the row are hashes
53
+ def factorygirl_row row
54
+ {}.tap do |result|
55
+ row.each do |key, value|
56
+ method = method_name key
57
+ result[key] = respond_to?(method) ? send(method, value) : value
58
+ end
59
+ end
60
+ end
61
+
62
+
63
+ # Returns the name of the value_for method for the given key
64
+ def method_name key
65
+ "value_for_#{key}"
66
+ end
67
+
68
+
69
+ # Converts the key given in Cucumber format into FactoryGirl format
70
+ def normalized_key key
71
+ key.downcase.parameterize.underscore
72
+ end
73
+
74
+
75
+ # Returns a new hash with the keys normalized to symbols
76
+ def symbolized_hash row
77
+ {}.tap do |result|
78
+ row.each do |key, value|
79
+ result[normalized_key key] = value
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -1,9 +1,23 @@
1
1
  require 'active_cucumber/cucumparer'
2
2
  require 'active_cucumber/cucumberator'
3
+ require 'active_cucumber/cureator'
3
4
 
4
5
  # The main namespace for this gem
5
6
  module ActiveCucumber
6
7
 
8
+ # Creates entries of the given ActiveRecord class
9
+ # specified by the given Cucumber table
10
+ def self.create_many activerecord_class, cucumber_table
11
+ Cureator.for(activerecord_class).create_records ActiveCucumber.horizontal_table(cucumber_table)
12
+ end
13
+
14
+ # Creates an entry of the given ActiveRecord class
15
+ # specified by the given Cucumber table
16
+ def self.create_one activerecord_class, cucumber_table
17
+ Cureator.for(activerecord_class).create_record ActiveCucumber.vertical_table(cucumber_table)
18
+ end
19
+
20
+
7
21
  # Verifies that the database table for the given ActiveRecord class
8
22
  # matches the given horizontal Cucumber table.
9
23
  #
@@ -13,10 +27,24 @@ module ActiveCucumber
13
27
  cucumber_table.diff! cucumparer.to_horizontal_table
14
28
  end
15
29
 
30
+
16
31
  # Verifies that the given object matches the given vertical Cucumber table
17
32
  def self.diff_one! object, cucumber_table
18
33
  cucumparer = Cucumparer.new object.class, cucumber_table
19
34
  cucumber_table.diff! cucumparer.to_vertical_table(object)
20
35
  end
21
36
 
37
+
38
+ # Returns the given horizontal Cucumber table in standardized format
39
+ def self.horizontal_table table
40
+ table.hashes
41
+ end
42
+
43
+
44
+ # Returns the given vertical Cucumber table in standardized format
45
+ def self.vertical_table table
46
+ table.rows_hash
47
+ end
48
+
49
+
22
50
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_cucumber
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Goslar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-19 00:00:00.000000000 Z
11
+ date: 2015-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -52,6 +52,62 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: cucumber_lint
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: factory_girl
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: faker
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: kappamaki
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
55
111
  - !ruby/object:Gem::Dependency
56
112
  name: mortadella
57
113
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +164,20 @@ dependencies:
108
164
  - - ">="
109
165
  - !ruby/object:Gem::Version
110
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rspec-collection_matchers
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
111
181
  - !ruby/object:Gem::Dependency
112
182
  name: sqlite3
113
183
  requirement: !ruby/object:Gem::Requirement
@@ -138,16 +208,23 @@ files:
138
208
  - Rakefile
139
209
  - active_cucumber.gemspec
140
210
  - circle.yml
141
- - features/cucumparer/diff_all.feature
142
- - features/cucumparer/diff_one.feature
211
+ - cucumber_lint.yml
212
+ - documentation/horizontal_diff.png
213
+ - documentation/vertical_diff.png
214
+ - features/active_cucumber/create_many.feature
215
+ - features/active_cucumber/create_one.feature
216
+ - features/active_cucumber/diff_all.feature
217
+ - features/active_cucumber/diff_one.feature
143
218
  - features/step_definitions/steps.rb
144
219
  - features/support/env.rb
145
220
  - features/support/episode.rb
146
221
  - features/support/episode_cucumberator.rb
222
+ - features/support/episode_cureator.rb
147
223
  - features/support/show.rb
148
224
  - lib/active_cucumber.rb
149
225
  - lib/active_cucumber/cucumberator.rb
150
226
  - lib/active_cucumber/cucumparer.rb
227
+ - lib/active_cucumber/cureator.rb
151
228
  homepage: https://github.com/Originate/active_cucumber
152
229
  licenses:
153
230
  - MIT