cucumber_factory 2.0.0 → 2.2.0

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
  SHA256:
3
- metadata.gz: 856fe1922e3b069b305e514911da87b4432acc34c89105b46cbf06d6cdd997be
4
- data.tar.gz: a0f9631996850758343f66f79d96d88a1cf0216c4df464a8132677d462766525
3
+ metadata.gz: 95567d71e09afa59f6db5bb2722ce78eb234b473987025ca3f66b6e181cdac1e
4
+ data.tar.gz: 7b1e046852657282cb2d5b65b714d12bb65c848196c0d6c70c13f3ce231fc684
5
5
  SHA512:
6
- metadata.gz: 31d7825ded3ed0ed9e9c29a490ecbff0028b710cb4f33bddbf1e3846a744444c9ae53a852b37db72284a57f4ef40515e166f8043dbf4d96db5412205a7f3b3c0
7
- data.tar.gz: 71ede7f9b7ae86335fb3eb1cd27ff9c72bd9ec9fbd958585fe4293443c7b6608b3cd0c21ea994971946ac69091722eb2a27714492d34a5e792583068c412b666
6
+ metadata.gz: '083f2675e4b6592ab9ee117b5080fefdeaa06f27abba833f3145b176834f37baf3e40f4ef74e90b9d91558f1034b50c7c6250d2675caeda98d52b8a794d27142'
7
+ data.tar.gz: 392e4121dc98584c1928f2e028964780f079a4a0f74d437fb6595dc6d2b9ecbbb090e9eb97f0361f9fa1059c633fb8a9de8f357d986ad0a3bd5e193e79c20bae
@@ -1,5 +1,4 @@
1
1
  rvm:
2
- - 1.8.7
3
2
  - 2.1.10
4
3
  - 2.5.3
5
4
 
@@ -13,20 +12,10 @@ dist: trusty
13
12
 
14
13
  matrix:
15
14
  exclude:
16
- - gemfile: Gemfile.cucumber-3.1
17
- rvm: 1.8.7
18
15
  - gemfile: Gemfile.cucumber-3.1
19
16
  rvm: 2.1.10 # cucumber 3 wants ruby >= 2.2
20
- - gemfile: Gemfile.cucumber-3.0
21
- rvm: 1.8.7
22
17
  - gemfile: Gemfile.cucumber-3.0
23
18
  rvm: 2.1.10 # cucumber 3 wants ruby >= 2.2
24
- - gemfile: Gemfile.cucumber-2.4
25
- rvm: 1.8.7
26
- - gemfile: Gemfile.cucumber-1.3
27
- rvm: 2.5.3 # doesn't work with old RSpec
28
- - gemfile: Gemfile.cucumber-1.3
29
- rvm: 2.1.10 # doesn't work with old RSpec
30
19
 
31
20
  install:
32
21
  # Replace default Travis CI bundler script with a version that doesn't
@@ -15,6 +15,57 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
15
15
 
16
16
  -
17
17
 
18
+ ## 2.2.0 - 2020-09-23
19
+
20
+ ### Compatible changes
21
+
22
+ - A step was added that allows modifying existing records with a similar syntax to creating new records:
23
+ ```cucumber
24
+ (Given "Bob" is a user)
25
+ And "Bob" has the email "foo@bar.com" and is subscribed
26
+ ```
27
+ - This step will also work with doc strings or tables:
28
+ ```cucumber
29
+ (Given "Bob" is a user)
30
+ And the user above has these attributes:
31
+ | name | Bob |
32
+ | email | foo@bar.com |
33
+ ```
34
+
35
+ ## 2.1.1 - 2020-05-20
36
+
37
+ ### Compatible changes
38
+
39
+ - Cucumber 2.1.0 introduced some regressions which are being addressed with this patch:
40
+ - Fix the assignment of polymorphic associations.
41
+ - Restore the support for inherited traits within nested factories.
42
+
43
+ ## 2.1.0 - 2020-03-09
44
+
45
+ ### Compatible changes
46
+
47
+ - Allow associations to be set for [transient attributes](https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#transient-attributes) if they are named after the model. For example, when there is a `Role` model and the`user` factory has a transient attribute `role`, the following steps are now valid:
48
+ ```
49
+ Given there is a role
50
+ And there is a user with the role above
51
+ ```
52
+
53
+ ## 2.0.2 - 2020-03-26
54
+
55
+ ### Compatible changes
56
+
57
+ - Removed development and test support for Ruby 1.8. Closes #32.
58
+
59
+ ## 2.0.1 - 2020-02-27
60
+
61
+ ### Compatible changes
62
+
63
+ - Fix a bug that prevented created records to be named when using multiline attribute assignments
64
+ ```
65
+ Given "Bob" is a user with these attributes:
66
+ | email | foo@bar.com |
67
+ ```
68
+
18
69
  ## 2.0.0 - 2020-02-10
19
70
 
20
71
  ### Breaking changes
@@ -2,16 +2,18 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Runtime dependencies
4
4
  gem 'cucumber', '~> 1.3.20'
5
- gem 'activesupport', '~> 2.3.0'
6
- gem 'activerecord', '~> 2.3.0'
7
- gem 'mysql2', '= 0.2.20'
8
- gem 'i18n', '=0.6.11' # 0.7 no longer builds for Ruby 1.8.7
5
+ gem 'activesupport', '~> 4.2.0'
6
+ gem 'activerecord', '~> 4.2.0'
7
+ gem 'mysql2'
9
8
 
10
9
  # Development dependencies
11
- gem 'rspec', '~> 1.0'
12
- gem 'rake', '=10.0.4'
10
+ gem 'rspec', '> 3.0'
11
+ gem 'rake', '>=10.0.4'
13
12
  gem 'database_cleaner', '~>1.0.0'
14
13
  gem 'gemika'
15
14
 
15
+ # Test dependencies
16
+ gem 'factory_bot', '< 5'
17
+
16
18
  # Gem under test
17
19
  gem 'cucumber_factory', :path => '.'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cucumber_factory (1.15.0)
4
+ cucumber_factory (2.2.0)
5
5
  activerecord
6
6
  activesupport
7
7
  cucumber
@@ -10,10 +10,21 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
- activerecord (2.3.18)
14
- activesupport (= 2.3.18)
15
- activesupport (2.3.18)
16
- builder (3.2.2)
13
+ activemodel (4.2.11.1)
14
+ activesupport (= 4.2.11.1)
15
+ builder (~> 3.1)
16
+ activerecord (4.2.11.1)
17
+ activemodel (= 4.2.11.1)
18
+ activesupport (= 4.2.11.1)
19
+ arel (~> 6.0)
20
+ activesupport (4.2.11.1)
21
+ i18n (~> 0.7)
22
+ minitest (~> 5.1)
23
+ thread_safe (~> 0.3, >= 0.3.4)
24
+ tzinfo (~> 1.1)
25
+ arel (6.0.4)
26
+ builder (3.2.4)
27
+ concurrent-ruby (1.1.6)
17
28
  cucumber (1.3.20)
18
29
  builder (>= 2.1.2)
19
30
  diff-lcs (>= 1.1.3)
@@ -23,31 +34,50 @@ GEM
23
34
  cucumber_priority (0.3.2)
24
35
  cucumber
25
36
  database_cleaner (1.0.1)
26
- diff-lcs (1.2.5)
27
- gemika (0.3.2)
37
+ diff-lcs (1.3)
38
+ factory_bot (4.11.1)
39
+ activesupport (>= 3.0.0)
40
+ gemika (0.4.0)
28
41
  gherkin (2.12.2)
29
42
  multi_json (~> 1.3)
30
- i18n (0.6.11)
31
- multi_json (1.11.2)
43
+ i18n (0.9.5)
44
+ concurrent-ruby (~> 1.0)
45
+ minitest (5.12.0)
46
+ multi_json (1.14.1)
32
47
  multi_test (0.1.2)
33
- mysql2 (0.2.20)
34
- rake (10.0.4)
35
- rspec (1.3.2)
48
+ mysql2 (0.5.3)
49
+ rake (12.3.3)
50
+ rspec (3.9.0)
51
+ rspec-core (~> 3.9.0)
52
+ rspec-expectations (~> 3.9.0)
53
+ rspec-mocks (~> 3.9.0)
54
+ rspec-core (3.9.1)
55
+ rspec-support (~> 3.9.1)
56
+ rspec-expectations (3.9.0)
57
+ diff-lcs (>= 1.2.0, < 2.0)
58
+ rspec-support (~> 3.9.0)
59
+ rspec-mocks (3.9.1)
60
+ diff-lcs (>= 1.2.0, < 2.0)
61
+ rspec-support (~> 3.9.0)
62
+ rspec-support (3.9.2)
63
+ thread_safe (0.3.6)
64
+ tzinfo (1.2.6)
65
+ thread_safe (~> 0.1)
36
66
 
37
67
  PLATFORMS
38
68
  ruby
39
69
 
40
70
  DEPENDENCIES
41
- activerecord (~> 2.3.0)
42
- activesupport (~> 2.3.0)
71
+ activerecord (~> 4.2.0)
72
+ activesupport (~> 4.2.0)
43
73
  cucumber (~> 1.3.20)
44
74
  cucumber_factory!
45
75
  database_cleaner (~> 1.0.0)
76
+ factory_bot (< 5)
46
77
  gemika
47
- i18n (= 0.6.11)
48
- mysql2 (= 0.2.20)
49
- rake (= 10.0.4)
50
- rspec (~> 1.0)
78
+ mysql2
79
+ rake (>= 10.0.4)
80
+ rspec (> 3.0)
51
81
 
52
82
  BUNDLED WITH
53
- 1.17.1
83
+ 1.17.3
@@ -12,5 +12,8 @@ gem 'rake'
12
12
  gem 'database_cleaner'
13
13
  gem 'gemika'
14
14
 
15
+ # Test dependencies
16
+ gem 'factory_bot', '< 5' # 5.0 requires Ruby >= 2.3
17
+
15
18
  # Gem under test
16
19
  gem 'cucumber_factory', :path => '.'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cucumber_factory (2.0.0)
4
+ cucumber_factory (2.2.0)
5
5
  activerecord
6
6
  activesupport
7
7
  cucumber
@@ -40,6 +40,8 @@ GEM
40
40
  cucumber
41
41
  database_cleaner (1.6.2)
42
42
  diff-lcs (1.3)
43
+ factory_bot (4.11.1)
44
+ activesupport (>= 3.0.0)
43
45
  gemika (0.3.2)
44
46
  gherkin (4.1.3)
45
47
  i18n (0.9.5)
@@ -75,6 +77,7 @@ DEPENDENCIES
75
77
  cucumber (~> 2.4.0)
76
78
  cucumber_factory!
77
79
  database_cleaner
80
+ factory_bot (< 5)
78
81
  gemika
79
82
  mysql2
80
83
  rake
@@ -12,5 +12,8 @@ gem 'rake'
12
12
  gem 'database_cleaner'
13
13
  gem 'gemika'
14
14
 
15
+ # Test dependencies
16
+ gem 'factory_bot'
17
+
15
18
  # Gem under test
16
19
  gem 'cucumber_factory', :path => '.'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cucumber_factory (2.0.0)
4
+ cucumber_factory (2.2.0)
5
5
  activerecord
6
6
  activesupport
7
7
  cucumber
@@ -45,6 +45,8 @@ GEM
45
45
  cucumber
46
46
  database_cleaner (1.6.2)
47
47
  diff-lcs (1.3)
48
+ factory_bot (5.1.1)
49
+ activesupport (>= 4.2.0)
48
50
  gemika (0.3.2)
49
51
  gherkin (4.1.3)
50
52
  i18n (0.9.5)
@@ -80,6 +82,7 @@ DEPENDENCIES
80
82
  cucumber (~> 3.0.0)
81
83
  cucumber_factory!
82
84
  database_cleaner
85
+ factory_bot
83
86
  gemika
84
87
  mysql2
85
88
  rake
@@ -12,5 +12,8 @@ gem 'rake'
12
12
  gem 'database_cleaner'
13
13
  gem 'gemika'
14
14
 
15
+ # Test dependencies
16
+ gem 'factory_bot'
17
+
15
18
  # Gem under test
16
19
  gem 'cucumber_factory', :path => '.'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cucumber_factory (2.0.0)
4
+ cucumber_factory (2.2.0)
5
5
  activerecord
6
6
  activesupport
7
7
  cucumber
@@ -45,6 +45,8 @@ GEM
45
45
  cucumber
46
46
  database_cleaner (1.6.2)
47
47
  diff-lcs (1.3)
48
+ factory_bot (5.1.1)
49
+ activesupport (>= 4.2.0)
48
50
  gemika (0.3.2)
49
51
  gherkin (5.0.0)
50
52
  i18n (0.9.5)
@@ -80,6 +82,7 @@ DEPENDENCIES
80
82
  cucumber (~> 3.1.0)
81
83
  cucumber_factory!
82
84
  database_cleaner
85
+ factory_bot
83
86
  gemika
84
87
  mysql2
85
88
  rake
data/README.md CHANGED
@@ -24,6 +24,13 @@ Quoted strings and numbers denote attribute values:
24
24
  Given there is a movie with the title "Sunshine" and the year 2007
25
25
  ```
26
26
 
27
+ To update an existing record, specify the record and the changes:
28
+ ```
29
+ Given the movie above has the title "Sunset" and the year 2008
30
+ Given the movie "Sunrise" has the year 2009
31
+ ```
32
+ A record can be specified by the `above` keyword, which uses the last created record of this class, or by any string that was used during its creation.
33
+
27
34
  Setting boolean attributes
28
35
  --------------------------
29
36
 
@@ -42,6 +49,13 @@ Given there is a movie which is awesome, popular and successful but not science
42
49
  And there is a director with the income "500000" but with the account balance "-30000"
43
50
  ```
44
51
 
52
+ To update boolean attributes use the keyword `is`:
53
+
54
+ ```cucumber
55
+ Given the movie above is awesome but not popular
56
+ Given the movie above has the year 1979 but is not science fiction
57
+ ```
58
+
45
59
 
46
60
  Setting many attributes with a table
47
61
  ------------------------------------
@@ -62,10 +76,18 @@ Given there is a movie with these attributes:
62
76
  | comedy | false |
63
77
  ```
64
78
 
79
+ ```cucumber
80
+ Given the movie above has these attributes:
81
+ """
82
+ name: Sunshine
83
+ comedy: false
84
+ """
85
+ ```
86
+
65
87
  Setting associations
66
88
  --------------------
67
89
 
68
- You can set `belongs_to` associations by referring to the last created record of as `above`:
90
+ You can set `belongs_to` and `transient` associations by referring to the last created record of as `above`:
69
91
 
70
92
  ```cucumber
71
93
  Given there is a movie with the title "Before Sunrise"
@@ -13,6 +13,7 @@ require 'cucumber_priority'
13
13
 
14
14
  # Gem
15
15
  require 'cucumber_factory/build_strategy'
16
+ require 'cucumber_factory/update_strategy'
16
17
  require 'cucumber_factory/factory'
17
18
  require 'cucumber_factory/switcher'
18
19
 
@@ -7,79 +7,115 @@ module CucumberFactory
7
7
  class << self
8
8
 
9
9
  def from_prose(model_prose, variant_prose)
10
- # don't use \w which depends on the system locale
11
- underscored_model_name = model_prose.gsub(/[^A-Za-z0-9_\/]+/, "_")
12
- if variant_prose.present?
13
- variants = /\((.*?)\)/.match(variant_prose)[1].split(/\s*,\s*/)
14
- variants = variants.collect { |variant| variant.downcase.gsub(" ", "_") }
10
+ variants = variants_from_prose(variant_prose)
11
+ factory = factory_bot_factory(model_prose, variants)
12
+
13
+ if factory
14
+ factory.compile # Required to load inherited traits!
15
+ strategy = factory_bot_strategy(factory, model_prose, variants)
16
+ transient_attributes = factory_bot_transient_attributes(factory, variants)
15
17
  else
16
- variants = []
18
+ strategy = alternative_strategy(model_prose, variants)
19
+ transient_attributes = []
17
20
  end
18
21
 
19
- if factory_bot_strategy = factory_bot_strategy(underscored_model_name, variants)
20
- factory_bot_strategy
22
+ [strategy, transient_attributes]
23
+ end
24
+
25
+ def parse_model_class(model_prose)
26
+ underscored_model_name(model_prose).camelize.constantize
27
+ end
28
+
29
+ private
30
+
31
+ def variants_from_prose(variant_prose)
32
+ if variant_prose.present?
33
+ variants = /\((.*?)\)/.match(variant_prose)[1].split(/\s*,\s*/)
34
+ variants.collect { |variant| variant.downcase.gsub(" ", "_").to_sym }
21
35
  else
22
- model_class = underscored_model_name.camelize.constantize
23
- machinist_strategy(model_class, variants) ||
24
- active_record_strategy(model_class) ||
25
- ruby_object_strategy(model_class)
36
+ []
26
37
  end
27
38
  end
28
39
 
29
- private
40
+ def factory_bot_factory(model_prose, variants)
41
+ return unless factory_bot_class
30
42
 
31
- def factory_bot_strategy(factory_name, variants)
32
- factory_class = ::FactoryBot if defined?(FactoryBot)
33
- factory_class ||= ::FactoryGirl if defined?(FactoryGirl)
34
- return unless factory_class
43
+ factory_name = factory_name_from_prose(model_prose)
44
+ factory = factory_bot_class.factories[factory_name]
35
45
 
36
- variants = variants.map(&:to_sym)
37
- factory_name = factory_name.to_s.underscore.gsub('/', '_').to_sym
46
+ if factory.nil? && variants.present?
47
+ factory = factory_bot_class.factories[variants[0]]
48
+ end
38
49
 
39
- factory = factory_class.factories[factory_name]
50
+ factory
51
+ end
40
52
 
41
- if factory.nil? && variants.present? && factory = factory_class.factories[variants[0]]
53
+ def factory_bot_strategy(factory, model_prose, variants)
54
+ return unless factory
55
+
56
+ factory_name = factory_name_from_prose(model_prose)
57
+ if factory_bot_class.factories[factory_name].nil? && variants.present?
42
58
  factory_name, *variants = variants
43
59
  end
44
60
 
45
- if factory
46
- new(factory.build_class) do |attributes|
47
- # Cannot have additional scalar args after a varargs
48
- # argument in Ruby 1.8 and 1.9
49
- args = []
50
- args += variants
51
- args << attributes
52
- factory_class.create(factory_name, *args)
53
- end
61
+ new(factory.build_class) do |attributes|
62
+ # Cannot have additional scalar args after a varargs
63
+ # argument in Ruby 1.8 and 1.9
64
+ args = []
65
+ args += variants
66
+ args << attributes
67
+ factory_bot_class.create(factory_name, *args)
68
+ end
69
+ end
70
+
71
+ def factory_bot_transient_attributes(factory, variants)
72
+ return [] unless factory
73
+
74
+ factory_attributes = factory_bot_attributes(factory, variants)
75
+ class_attributes = factory.build_class.attribute_names.map(&:to_sym)
76
+
77
+ factory_attributes - class_attributes
78
+ end
79
+
80
+ def factory_bot_attributes(factory, variants)
81
+ traits = factory_bot_traits(factory, variants)
82
+ factory.with_traits(traits.map(&:name)).definition.attributes.names
83
+ end
84
+
85
+ def factory_bot_traits(factory, variants)
86
+ factory.definition.defined_traits.select do |trait|
87
+ variants.include?(trait.name.to_sym)
54
88
  end
89
+ end
55
90
 
91
+ def alternative_strategy(model_prose, variants)
92
+ model_class = parse_model_class(model_prose)
93
+ machinist_strategy(model_class, variants) ||
94
+ active_record_strategy(model_class) ||
95
+ ruby_object_strategy(model_class)
56
96
  end
57
97
 
58
98
  def machinist_strategy(model_class, variants)
59
- if model_class.respond_to?(:make)
60
-
61
- new(model_class) do |attributes|
62
- if variants.present?
63
- variants.size == 1 or raise 'Machinist only supports a single variant per blueprint'
64
- model_class.make(variants.first.to_sym, attributes)
65
- else
66
- model_class.make(attributes)
67
- end
68
- end
99
+ return unless model_class.respond_to?(:make)
69
100
 
101
+ new(model_class) do |attributes|
102
+ if variants.present?
103
+ variants.size == 1 or raise 'Machinist only supports a single variant per blueprint'
104
+ model_class.make(variants.first, attributes)
105
+ else
106
+ model_class.make(attributes)
107
+ end
70
108
  end
71
109
  end
72
110
 
73
111
  def active_record_strategy(model_class)
74
- if model_class.respond_to?(:create!)
75
-
76
- new(model_class) do |attributes|
77
- model = model_class.new
78
- CucumberFactory::Switcher.assign_attributes(model, attributes)
79
- model.save!
80
- model
81
- end
112
+ return unless model_class.respond_to?(:create!)
82
113
 
114
+ new(model_class) do |attributes|
115
+ model = model_class.new
116
+ CucumberFactory::Switcher.assign_attributes(model, attributes)
117
+ model.save!
118
+ model
83
119
  end
84
120
  end
85
121
 
@@ -89,6 +125,21 @@ module CucumberFactory
89
125
  end
90
126
  end
91
127
 
128
+ def factory_bot_class
129
+ factory_class = ::FactoryBot if defined?(FactoryBot)
130
+ factory_class ||= ::FactoryGirl if defined?(FactoryGirl)
131
+ factory_class
132
+ end
133
+
134
+ def factory_name_from_prose(model_prose)
135
+ underscored_model_name(model_prose).to_s.underscore.gsub('/', '_').to_sym
136
+ end
137
+
138
+ def underscored_model_name(model_prose)
139
+ # don't use \w which depends on the system locale
140
+ model_prose.gsub(/[^A-Za-z0-9_\/]+/, "_")
141
+ end
142
+
92
143
  end
93
144
 
94
145