cucumber_factory 2.0.1 → 2.3.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.
@@ -1,3 +1,3 @@
1
1
  module CucumberFactory
2
- VERSION = '2.0.1'
2
+ VERSION = '2.3.0'
3
3
  end
@@ -0,0 +1 @@
1
+ This is a test file.
@@ -0,0 +1 @@
1
+ This is the second test file.
@@ -0,0 +1 @@
1
+ spec/assets/file.txt
@@ -2,47 +2,45 @@ require 'spec_helper'
2
2
 
3
3
  describe CucumberFactory::BuildStrategy do
4
4
 
5
- subject { CucumberFactory::BuildStrategy }
6
-
7
5
  # most of the behaviour is integration tested in steps_spec.rb
8
6
 
9
7
  describe '.from_prose' do
10
8
 
11
9
  context 'when describing a factory_bot factory' do
12
-
13
- it 'returns a strategy corresponding to the factories model' do
14
- FactoryBot.stub_factories :job_offer => JobOffer
15
- strategy = subject.from_prose('job offer', nil)
10
+ it 'returns a strategy and transient attributes corresponding to the factories model' do
11
+ strategy, transient_attributes = described_class.from_prose('job offer', nil)
16
12
 
17
13
  strategy.should be_a(described_class)
18
14
  strategy.model_class.should == JobOffer
15
+ transient_attributes.should == [:my_transient_attribute]
19
16
  end
20
17
 
21
18
  it 'uses the variant for the factory name if present' do
22
- FactoryBot.stub_factories :job_offer => JobOffer
23
- strategy = subject.from_prose('foo', '(job offer)')
19
+ strategy, transient_attributes = described_class.from_prose('job offer', '(tempting_job_offer)')
24
20
 
25
21
  strategy.should be_a(described_class)
26
22
  strategy.model_class.should == JobOffer
23
+ transient_attributes.should == [:my_transient_attribute, :other_transient_attribute]
27
24
  end
28
-
29
25
  end
30
26
 
31
27
  context 'when describing a non factory_bot model' do
28
+ before do
29
+ hide_const("FactoryBot")
30
+ end
32
31
 
33
32
  it "should return a strategy for the class matching a natural language expression" do
34
- subject.from_prose("movie", nil).model_class.should == Movie
35
- subject.from_prose("job offer", nil).model_class.should == JobOffer
33
+ described_class.from_prose("movie", nil).first.model_class.should == Movie
34
+ described_class.from_prose("job offer", nil).first.model_class.should == JobOffer
36
35
  end
37
36
 
38
37
  it "should ignore variants for the class name" do
39
- subject.from_prose("movie", "(job offer)").model_class.should == Movie
38
+ described_class.from_prose("movie", "(job offer)").first.model_class.should == Movie
40
39
  end
41
40
 
42
41
  it "should allow namespaced models" do
43
- subject.from_prose("people/actor", nil).model_class.should == People::Actor
42
+ described_class.from_prose("people/actor", nil).first.model_class.should == People::Actor
44
43
  end
45
-
46
44
  end
47
45
 
48
46
  end
@@ -1,490 +1,659 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'steps provided by cucumber_factory' do
3
+ TRANSFORMS_SUPPORTED = Cucumber::VERSION < '3'
4
4
 
5
+ describe 'steps provided by cucumber_factory' do
5
6
  before(:each) do
6
7
  prepare_cucumber_example
7
8
  end
8
9
 
9
- TRANSFORMS_SUPPORTED = Cucumber::VERSION < '3'
10
+ context 'FactoryBot' do
11
+ it "should create ActiveRecord models by calling #new and #save!" do
12
+ movie = Movie.new
13
+ Movie.should_receive(:new).with(no_args).and_return(movie)
14
+ movie.should_receive(:save!)
15
+ invoke_cucumber_step("there is a movie")
16
+ end
10
17
 
11
- it "should create ActiveRecord models by calling #new and #save!" do
12
- movie = Movie.new
13
- Movie.should_receive(:new).with(no_args).and_return(movie)
14
- movie.should_receive(:save!)
15
- invoke_cucumber_step("there is a movie")
16
- end
18
+ it "should create models that have a factory_bot factory by calling #FactoryBot.create(:model_name)" do
19
+ FactoryBot.should_receive(:create).with(:job_offer, { :title => "Awesome job" })
20
+ invoke_cucumber_step('there is a job offer with the title "Awesome job"')
21
+ end
17
22
 
18
- it "should create models that have a machinist blueprint by calling #make" do
19
- MachinistModel.should_receive(:make).with({ :attribute => "foo"})
20
- invoke_cucumber_step('there is a machinist model with the attribute "foo"')
21
- end
23
+ it "should create model variants that have a factory_bot factory by calling #FactoryBot.create(:variant)" do
24
+ FactoryBot.should_receive(:create).with(:job_offer, :tempting_job_offer, { :title => "Awesomafiablyfantasmic job" })
25
+ invoke_cucumber_step('there is a job offer (tempting job offer) with the title "Awesomafiablyfantasmic job"')
26
+ end
22
27
 
23
- it "should be able to step_match machinist blueprint variants" do
24
- MachinistModel.should_receive(:make).with(:variant, { :attribute => "foo"})
25
- invoke_cucumber_step('there is a machinist model (variant) with the attribute "foo"')
26
- end
28
+ it "should create model variants that have a factory_bot trait by calling #FactoryBot.create(:factory, :trait1, :trait2)" do
29
+ FactoryBot.should_receive(:create).with(:job_offer, :risky, :lucrative, { :title => "Awesomafiablyfantasmic job" })
30
+ invoke_cucumber_step('there is a job offer (risky, lucrative) with the title "Awesomafiablyfantasmic job"')
31
+ end
27
32
 
28
- it "should be able to step_match machinist blueprint variants containing spaces or uppercase characters in prose" do
29
- MachinistModel.should_receive(:make).with(:variant_mark_two, { :attribute => "foo"})
30
- invoke_cucumber_step('there is a machinist model (Variant Mark Two) with the attribute "foo"')
31
- end
33
+ it "should create model variants that have a factory_bot factory by using the model name as a factory name" do
34
+ FactoryBot.should_receive(:create).with(:job_offer, { :title => "Awesomafiablyfantasmic job" })
35
+ invoke_cucumber_step('there is a job offer with the title "Awesomafiablyfantasmic job"')
36
+ end
32
37
 
33
- it "should create models that have a factory_bot factory by calling #FactoryBot.create(:model_name)" do
34
- FactoryBot.stub_factories :job_offer => JobOffer
35
- FactoryBot.should_receive(:create).with(:job_offer, { :title => "Awesome job" })
36
- invoke_cucumber_step('there is a job offer with the title "Awesome job"')
37
- end
38
+ it "should instantiate classes with multiple words in their name" do
39
+ job_offer = JobOffer.new
40
+ JobOffer.should_receive(:new).with(no_args).and_return(job_offer)
41
+ invoke_cucumber_step("there is a job offer")
42
+ end
38
43
 
39
- it "should create model variants that have a factory_bot factory by calling #FactoryBot.create(:variant)" do
40
- FactoryBot.stub_factories :tempting_job_offer => JobOffer
41
- FactoryBot.should_receive(:create).with(:tempting_job_offer, { :title => "Awesomafiablyfantasmic job" })
42
- invoke_cucumber_step('there is a job offer (tempting job offer) with the title "Awesomafiablyfantasmic job"')
43
- end
44
+ it "should instantiate classes with uppercase characters in their name" do
45
+ user = User.new
46
+ User.should_receive(:new).and_return(user)
47
+ invoke_cucumber_step("there is a User")
48
+ end
44
49
 
45
- it "should create model variants that have a factory_bot trait by calling #FactoryBot.create(:factory, :trait1, :trait2)" do
46
- FactoryBot.stub_factories :tempting_job_offer => JobOffer
47
- FactoryBot.should_receive(:create).with(:tempting_job_offer, :risky, :lucrative, { :title => "Awesomafiablyfantasmic job" })
48
- invoke_cucumber_step('there is a tempting job offer (risky, lucrative) with the title "Awesomafiablyfantasmic job"')
49
- end
50
+ it "should allow either 'a' or 'an' for the article" do
51
+ opera = Opera.new
52
+ Opera.should_receive(:new).with(no_args).and_return(opera)
53
+ invoke_cucumber_step("there is an opera")
54
+ end
50
55
 
51
- it "should create model variants that have a factory_bot factory by using the model name as a factory name" do
52
- FactoryBot.stub_factories :tempting_job_offer => JobOffer
53
- FactoryBot.should_receive(:create).with(:tempting_job_offer, { :title => "Awesomafiablyfantasmic job" })
54
- invoke_cucumber_step('there is a tempting job offer with the title "Awesomafiablyfantasmic job"')
55
- end
56
+ it "should create records with attributes" do
57
+ movie = Movie.new
58
+ Movie.stub(:new => movie)
59
+ invoke_cucumber_step('there is a movie with the title "Sunshine" and the year "2007"')
60
+ movie.title.should == "Sunshine"
61
+ movie.year.should == 2007
62
+ end
56
63
 
57
- it "should instantiate plain ruby classes by calling #new" do
58
- PlainRubyClass.should_receive(:new).with({})
59
- invoke_cucumber_step("there is a plain ruby class")
60
- end
64
+ it "should allow to join attribute lists with 'and's, commas and 'but's" do
65
+ movie = Movie.new
66
+ Movie.stub(:new => movie)
67
+ invoke_cucumber_step('there is a movie with the title "Sunshine", the year "2007" but with the box office result "32000000"')
68
+ movie.title.should == "Sunshine"
69
+ movie.year.should == 2007
70
+ movie.box_office_result.should == 32000000
71
+ end
61
72
 
62
- it "should instantiate classes with multiple words in their name" do
63
- JobOffer.should_receive(:new).with({})
64
- invoke_cucumber_step("there is a job offer")
65
- end
73
+ if TRANSFORMS_SUPPORTED
74
+ it "should apply Cucumber transforms to attribute values" do
75
+ movie = Movie.new
76
+ Movie.stub(:new => movie)
77
+ @main.instance_eval do
78
+ Transform /^(value)$/ do |value|
79
+ 'transformed value'
80
+ end
81
+ end
82
+ invoke_cucumber_step('there is a movie with the title "value"')
83
+ movie.title.should == "transformed value"
84
+ end
85
+ end
66
86
 
67
- it "should instantiate classes with uppercase characters in their name" do
68
- user = User.new
69
- User.should_receive(:new).and_return(user)
70
- invoke_cucumber_step("there is a User")
71
- end
87
+ it "should create records with attributes containing spaces" do
88
+ movie = Movie.new
89
+ Movie.stub(:new => movie)
90
+ invoke_cucumber_step('there is a movie with the box office result "99999999"')
91
+ movie.box_office_result.should == 99999999
92
+ end
72
93
 
73
- it "should instantiate namespaced classes" do
74
- actor = People::Actor.new
75
- People::Actor.should_receive(:new).and_return(actor)
76
- invoke_cucumber_step("there is a people/actor")
77
- end
94
+ it "should create records with attributes containing uppercase characters" do
95
+ user = User.new
96
+ User.stub(:new => user)
97
+ invoke_cucumber_step('there is a User with the Name "Susanne"')
98
+ user.name.should == "Susanne"
99
+ end
78
100
 
79
- it "should allow either 'a' or 'an' for the article" do
80
- Opera.should_receive(:new).with({})
81
- invoke_cucumber_step("there is an opera")
82
- end
101
+ it "should override attr_accessible protection" do
102
+ invoke_cucumber_step('there is a payment with the amount "120" and the comment "Thanks for lending"')
103
+ payment = Payment.last
104
+ payment.amount.should == 120
105
+ payment.comment.should == 'Thanks for lending'
106
+ end
83
107
 
84
- it "should create records with attributes" do
85
- movie = Movie.new
86
- Movie.stub(:new => movie)
87
- invoke_cucumber_step('there is a movie with the title "Sunshine" and the year "2007"')
88
- movie.title.should == "Sunshine"
89
- movie.year.should == 2007
90
- end
108
+ it "should allow to set an explicit primary key" do
109
+ invoke_cucumber_step('there is a payment with the ID 2')
110
+ payment = Payment.last
111
+ payment.id.should == 2
112
+ end
91
113
 
92
- it "should allow to join attribute lists with 'and's, commas and 'but's" do
93
- movie = Movie.new
94
- Movie.stub(:new => movie)
95
- invoke_cucumber_step('there is a movie with the title "Sunshine", the year "2007" but with the box office result "32000000"')
96
- movie.title.should == "Sunshine"
97
- movie.year.should == 2007
98
- movie.box_office_result.should == 32000000
99
- end
114
+ it "should allow to name records and set a belongs_to association to that record by referring to that name" do
115
+ invoke_cucumber_step('"Some Prequel" is a movie with the title "Before Sunrise"')
116
+ invoke_cucumber_step('there is a movie with the title "Limitless"')
117
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel "Some Prequel"')
118
+ movie = Movie.find_by_title!('Before Sunset')
119
+ prequel = Movie.find_by_title!('Before Sunrise')
120
+ movie.prequel.should == prequel
121
+ end
100
122
 
101
- if TRANSFORMS_SUPPORTED
102
- it "should apply Cucumber transforms to attribute values" do
103
- movie = Movie.new
104
- Movie.stub(:new => movie)
105
- @main.instance_eval do
106
- Transform /^(value)$/ do |value|
107
- 'transformed value'
123
+ it "should allow to set a belongs_to association to a previously created record by referring to any string attribute of that record" do
124
+ invoke_cucumber_step('there is a movie with the title "Before Sunrise"')
125
+ invoke_cucumber_step('there is a movie with the title "Limitless"')
126
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel "Before Sunrise"')
127
+ movie = Movie.find_by_title!('Before Sunset')
128
+ prequel = Movie.find_by_title!('Before Sunrise')
129
+ movie.prequel.should == prequel
130
+ end
131
+
132
+ it "should allow to set a belongs_to association to a previously updated record by referring to any string attribute used when updating" do
133
+ invoke_cucumber_step('there is a movie')
134
+ invoke_cucumber_step('the movie above has the title "Before Sunrise"')
135
+ invoke_cucumber_step('there is a movie with the title "Limitless"')
136
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel "Before Sunrise"')
137
+ movie = Movie.find_by_title!('Before Sunset')
138
+ prequel = Movie.find_by_title!('Before Sunrise')
139
+ movie.prequel.should == prequel
140
+ end
141
+
142
+ it "should allow to set a belongs_to association to a previously created record by referring to their explicitely set primary keys" do
143
+ invoke_cucumber_step('there is a movie with the ID 123')
144
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel 123')
145
+ movie = Movie.find_by_title!('Before Sunset')
146
+ prequel = Movie.find(123)
147
+ movie.prequel.should == prequel
148
+ end
149
+
150
+ it "should allow to set a belongs_to association to a previously created record by saying 'above'" do
151
+ invoke_cucumber_step('there is a user with the name "Jane"')
152
+ invoke_cucumber_step('there is a user with the name "John"')
153
+ invoke_cucumber_step('there is a movie with the title "Limitless"')
154
+ invoke_cucumber_step('there is a movie with the title "Before Sunrise"')
155
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the reviewer above and the prequel above')
156
+ before_sunset = Movie.find_by_title!("Before Sunset")
157
+ before_sunset.prequel.title.should == "Before Sunrise"
158
+ before_sunset.reviewer.name.should == "John"
159
+ end
160
+
161
+ if TRANSFORMS_SUPPORTED
162
+ it "should fallback to using transforms when no named record is found" do
163
+ user = User.create!(:name => 'Me')
164
+ @main.instance_eval do
165
+ Transform(/^(me)$/) do |value|
166
+ user
167
+ end
108
168
  end
169
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the reviewer "me"')
170
+ before_sunset = Movie.find_by_title!("Before Sunset")
171
+ before_sunset.reviewer.should == user
109
172
  end
110
- invoke_cucumber_step('there is a movie with the title "value"')
111
- movie.title.should == "transformed value"
112
173
  end
113
- end
114
174
 
115
- it "should create records with attributes containing spaces" do
116
- movie = Movie.new
117
- Movie.stub(:new => movie)
118
- invoke_cucumber_step('there is a movie with the box office result "99999999"')
119
- movie.box_office_result.should == 99999999
120
- end
175
+ it "should give created_at precedence over id when saying 'above' if the primary key is not numeric" do
176
+ invoke_cucumber_step('there is a uuid user with the name "Jane" and the id "jane"')
177
+ invoke_cucumber_step('there is a uuid user with the name "John" and the id "john"')
178
+ UuidUser.find_by_name("John").update_attributes!(:created_at => 1.day.ago)
179
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the uuid reviewer above')
180
+ before_sunset = Movie.find_by_title!("Before Sunset")
181
+ before_sunset.uuid_reviewer.name.should == "Jane"
182
+ end
121
183
 
122
- it "should create records with attributes containing uppercase characters" do
123
- user = User.new
124
- User.stub(:new => user)
125
- invoke_cucumber_step('there is a User with the Name "Susanne"')
126
- user.name.should == "Susanne"
127
- end
184
+ it "should ignore created_at if the primary key is numeric" do
185
+ invoke_cucumber_step('there is a user with the name "Jane"')
186
+ invoke_cucumber_step('there is a user with the name "John"')
187
+ User.find_by_name("John").update_attributes!(:created_at => 1.day.ago)
188
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the reviewer above')
189
+ before_sunset = Movie.find_by_title!("Before Sunset")
190
+ before_sunset.reviewer.name.should == "John"
191
+ end
128
192
 
129
- it "should override attr_accessible protection" do
130
- invoke_cucumber_step('there is a payment with the amount "120" and the comment "Thanks for lending"')
131
- payment = Payment.last
132
- payment.amount.should == 120
133
- payment.comment.should == 'Thanks for lending'
134
- end
193
+ it "should raise a proper error if there is no previous record when saying 'above'" do
194
+ lambda do
195
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the reviewer above and the prequel above')
196
+ end.should raise_error(/There is no last reviewer/i)
197
+ end
135
198
 
136
- it "should allow to set an explicit primary key" do
137
- invoke_cucumber_step('there is a payment with the ID 2')
138
- payment = Payment.last
139
- payment.id.should == 2
140
- end
199
+ it "should reload an object assigned to a belongs_to before assigning" do
200
+ invoke_cucumber_step('"Jane" is a user who is deleted')
201
+ User.last.update_attributes(:deleted => false)
202
+ proc { invoke_cucumber_step('there is a movie with the title "Before Sunset" and the reviewer "Jane"') }.should_not raise_error
203
+ end
141
204
 
142
- it "should allow to name records and set a belongs_to association to that record by refering to that name" do
143
- invoke_cucumber_step('"Some Prequel" is a movie with the title "Before Sunrise"')
144
- invoke_cucumber_step('there is a movie with the title "Limitless"')
145
- invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel "Some Prequel"')
146
- movie = Movie.find_by_title!('Before Sunset')
147
- prequel = Movie.find_by_title!('Before Sunrise')
148
- movie.prequel.should == prequel
149
- end
205
+ it "should allow to set positive boolean attributes with 'who' after the attribute list" do
206
+ user = User.new
207
+ User.stub(:new => user)
208
+ invoke_cucumber_step('there is a user with the name "Jane" who is deleted')
209
+ user.name.should == "Jane"
210
+ user.deleted.should == true
211
+ end
150
212
 
151
- it "should allow to set a belongs_to association to a previously created record by refering to any string attribute of that record" do
152
- invoke_cucumber_step('there is a movie with the title "Before Sunrise"')
153
- invoke_cucumber_step('there is a movie with the title "Limitless"')
154
- invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel "Before Sunrise"')
155
- movie = Movie.find_by_title!('Before Sunset')
156
- prequel = Movie.find_by_title!('Before Sunrise')
157
- movie.prequel.should == prequel
158
- end
213
+ it "should allow to name records and set a belongs_to association to that record by referring to that name" do
214
+ invoke_cucumber_step('"Some Prequel" is a movie with the title "Before Sunrise"')
215
+ invoke_cucumber_step('there is a movie with the title "Limitless"')
216
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel "Some Prequel"')
217
+ movie = Movie.find_by_title!('Before Sunset')
218
+ prequel = Movie.find_by_title!('Before Sunrise')
219
+ movie.prequel.should == prequel
220
+ end
159
221
 
160
- it "should allow to set a belongs_to association to a previously created record by refering to their explicitely set primary keys" do
161
- invoke_cucumber_step('there is a movie with the ID 123')
162
- invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel 123')
163
- movie = Movie.find_by_title!('Before Sunset')
164
- prequel = Movie.find(123)
165
- movie.prequel.should == prequel
166
- end
222
+ it "should allow to set positive boolean attributes with 'which' after the attribute list" do
223
+ user = User.new
224
+ User.stub(:new => user)
225
+ invoke_cucumber_step('there is a user with the name "Jane" which is deleted')
226
+ user.name.should == "Jane"
227
+ user.deleted.should == true
228
+ end
167
229
 
168
- it "should allow to set a belongs_to association to a previously created record by saying 'above'" do
169
- invoke_cucumber_step('there is a user with the name "Jane"')
170
- invoke_cucumber_step('there is a user with the name "John"')
171
- invoke_cucumber_step('there is a movie with the title "Limitless"')
172
- invoke_cucumber_step('there is a movie with the title "Before Sunrise"')
173
- invoke_cucumber_step('there is a movie with the title "Before Sunset" and the reviewer above and the prequel above')
174
- before_sunset = Movie.find_by_title!("Before Sunset")
175
- before_sunset.prequel.title.should == "Before Sunrise"
176
- before_sunset.reviewer.name.should == "John"
177
- end
230
+ it "should allow to set positive boolean attributes with 'that' after the attribute list" do
231
+ user = User.new
232
+ User.stub(:new => user)
233
+ invoke_cucumber_step('there is a user with the name "Jane" that is deleted')
234
+ user.name.should == "Jane"
235
+ user.deleted.should == true
236
+ end
178
237
 
179
- if TRANSFORMS_SUPPORTED
180
- it "should fallback to using transforms when no named record is found" do
181
- user = User.create!(:name => 'Me')
182
- @main.instance_eval do
183
- Transform(/^(me)$/) do |value|
184
- user
185
- end
186
- end
187
- invoke_cucumber_step('there is a movie with the title "Before Sunset" and the reviewer "me"')
188
- before_sunset = Movie.find_by_title!("Before Sunset")
189
- before_sunset.reviewer.should == user
238
+ it "should allow to set boolean attributes without regular attributes preceding them" do
239
+ user = User.new
240
+ User.stub(:new => user)
241
+ invoke_cucumber_step('there is a user who is deleted')
242
+ user.deleted.should == true
190
243
  end
191
- end
192
244
 
193
- it "should give created_at precedence over id when saying 'above' if the primary key is not numeric" do
194
- invoke_cucumber_step('there is a uuid user with the name "Jane" and the id "jane"')
195
- invoke_cucumber_step('there is a uuid user with the name "John" and the id "john"')
196
- UuidUser.find_by_name("John").update_attributes!(:created_at => 1.day.ago)
197
- invoke_cucumber_step('there is a movie with the title "Before Sunset" and the uuid reviewer above')
198
- before_sunset = Movie.find_by_title!("Before Sunset")
199
- before_sunset.uuid_reviewer.name.should == "Jane"
200
- end
245
+ it "should allow to set negative boolean attribute" do
246
+ user = User.new
247
+ User.stub(:new => user)
248
+ invoke_cucumber_step('there is a user who is not deleted')
249
+ user.deleted.should == false
250
+ end
201
251
 
202
- it "should ignore created_at if the primary key is numeric" do
203
- invoke_cucumber_step('there is a user with the name "Jane"')
204
- invoke_cucumber_step('there is a user with the name "John"')
205
- User.find_by_name("John").update_attributes!(:created_at => 1.day.ago)
206
- invoke_cucumber_step('there is a movie with the title "Before Sunset" and the reviewer above')
207
- before_sunset = Movie.find_by_title!("Before Sunset")
208
- before_sunset.reviewer.name.should == "John"
209
- end
252
+ it "should allow to set multiple boolean attributes" do
253
+ user = User.new
254
+ User.stub(:new => user)
255
+ invoke_cucumber_step('there is a user who is locked and not deleted and subscribed')
256
+ user.locked.should == true
257
+ user.deleted.should == false
258
+ user.subscribed.should == true
259
+ end
210
260
 
211
- it "should raise a proper error if there is no previous record when saying 'above'" do
212
- lambda do
213
- invoke_cucumber_step('there is a movie with the title "Before Sunset" and the reviewer above and the prequel above')
214
- end.should raise_error(/There is no last reviewer/i)
215
- end
261
+ it "should allow to set boolean attributes that are named from multiple words" do
262
+ user = User.new
263
+ User.stub(:new => user)
264
+ invoke_cucumber_step('there is a user who is locked and not scared and scared by spiders and deleted')
265
+ user.locked.should == true
266
+ user.scared.should == false
267
+ user.scared_by_spiders.should == true
268
+ user.deleted.should == true
269
+ end
216
270
 
217
- it "should reload an object assigned to a belongs_to before assigning" do
218
- invoke_cucumber_step('"Jane" is a user who is deleted')
219
- User.last.update_attributes(:deleted => false)
220
- proc { invoke_cucumber_step('there is a movie with the title "Before Sunset" and the reviewer "Jane"') }.should_not raise_error
221
- end
271
+ it "should allow to join boolean attribute lists with 'and's, commas and 'but's" do
272
+ user = User.new
273
+ User.stub(:new => user)
274
+ invoke_cucumber_step('there is a user who is locked, scared, but scared by spiders and deleted')
275
+ user.locked.should == true
276
+ user.scared.should == true
277
+ user.scared_by_spiders.should == true
278
+ user.deleted.should == true
279
+ end
222
280
 
223
- it "should allow to set positive boolean attributes with 'who' after the attribute list" do
224
- user = User.new
225
- User.stub(:new => user)
226
- invoke_cucumber_step('there is a user with the name "Jane" who is deleted')
227
- user.name.should == "Jane"
228
- user.deleted.should == true
229
- end
281
+ it "should allow to set a has_many association by referring to multiple named records in square brackets" do
282
+ invoke_cucumber_step('there is a movie with the title "Sunshine"')
283
+ invoke_cucumber_step('there is a movie with the title "Limitless"')
284
+ invoke_cucumber_step('there is a user with the reviewed movies ["Sunshine" and "Limitless"]')
285
+ user = User.last
286
+ reviewed_movie_titles = user.reviewed_movies.map(&:title)
287
+ reviewed_movie_titles.should =~ ['Sunshine', 'Limitless']
288
+ end
230
289
 
231
- it "should allow to set positive boolean attributes with 'which' after the attribute list" do
232
- user = User.new
233
- User.stub(:new => user)
234
- invoke_cucumber_step('there is a user with the name "Jane" which is deleted')
235
- user.name.should == "Jane"
236
- user.deleted.should == true
237
- end
290
+ it 'allow associations for transient attributes if they are named after the associated model' do
291
+ invoke_cucumber_step('there is a movie with the title "Sunshine"')
292
+ invoke_cucumber_step('there is a user with the movie "Sunshine"')
293
+ user = User.last
294
+ user.reviewed_movies.count.should == 1
295
+ user.reviewed_movies.first.title.should == 'Sunshine'
296
+ end
238
297
 
239
- it "should allow to set positive boolean attributes with 'that' after the attribute list" do
240
- user = User.new
241
- User.stub(:new => user)
242
- invoke_cucumber_step('there is a user with the name "Jane" that is deleted')
243
- user.name.should == "Jane"
244
- user.deleted.should == true
245
- end
298
+ it "should allow to set attributes via doc string" do
299
+ user = User.new
300
+ User.stub(:new => user)
246
301
 
247
- it "should allow to set boolean attributes without regular attributes preceding them" do
248
- user = User.new
249
- User.stub(:new => user)
250
- invoke_cucumber_step('there is a user who is deleted')
251
- user.deleted.should == true
252
- end
302
+ invoke_cucumber_step('there is a user with these attributes:', <<-DOC_STRING)
303
+ name: Jane
304
+ locked: true
305
+ DOC_STRING
253
306
 
254
- it "should allow to set negative boolean attribute" do
255
- user = User.new
256
- User.stub(:new => user)
257
- invoke_cucumber_step('there is a user who is not deleted')
258
- user.deleted.should == false
259
- end
307
+ user.name.should == "Jane"
308
+ user.locked.should == true
309
+ end
260
310
 
261
- it "should allow to set multiple boolean attributes" do
262
- user = User.new
263
- User.stub(:new => user)
264
- invoke_cucumber_step('there is a user who is locked and not deleted and subscribed')
265
- user.locked.should == true
266
- user.deleted.should == false
267
- user.subscribed.should == true
268
- end
311
+ it "should allow to set attributes via additional doc string" do
312
+ user = User.new
313
+ User.stub(:new => user)
269
314
 
270
- it "should allow to set boolean attributes that are named from multiple words" do
271
- user = User.new
272
- User.stub(:new => user)
273
- invoke_cucumber_step('there is a user who is locked and not scared and scared by spiders and deleted')
274
- user.locked.should == true
275
- user.scared.should == false
276
- user.scared_by_spiders.should == true
277
- user.deleted.should == true
278
- end
315
+ invoke_cucumber_step('there is a user with the email "test@invalid.com" and these attributes:', <<-DOC_STRING)
316
+ name: Jane
317
+ DOC_STRING
279
318
 
280
- it "should allow to join boolean attribute lists with 'and's, commas and 'but's" do
281
- user = User.new
282
- User.stub(:new => user)
283
- invoke_cucumber_step('there is a user who is locked, scared, but scared by spiders and deleted')
284
- user.locked.should == true
285
- user.scared.should == true
286
- user.scared_by_spiders.should == true
287
- user.deleted.should == true
288
- end
319
+ user.name.should == "Jane"
320
+ user.email.should == "test@invalid.com"
321
+ end
289
322
 
290
- it "should allow to set integer attributes without surrounding quotes" do
291
- invoke_cucumber_step('there is a plain Ruby class with the amount 123 and the total 456')
292
- obj = PlainRubyClass.last
293
- obj.attributes[:amount].should == 123
294
- obj.attributes[:total].should == 456
295
- end
323
+ it 'should allow named records when setting attributes via doc string' do
324
+ invoke_cucumber_step('"Some Prequel" is a movie with these attributes:', <<-DOC_STRING)
325
+ title: Before Sunrise
326
+ DOC_STRING
327
+ invoke_cucumber_step('there is a movie with the title "Limitless"')
328
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel "Some Prequel"')
329
+ movie = Movie.find_by_title!('Before Sunset')
330
+ prequel = Movie.find_by_title!('Before Sunrise')
331
+ movie.prequel.should == prequel
332
+ end
296
333
 
297
- it "should allow to set decimal attributes without surrounding quotes" do
298
- invoke_cucumber_step('there is a plain Ruby class with the amount 1.23 and the total 45.6')
299
- obj = PlainRubyClass.last
300
- obj.attributes[:amount].should be_a(BigDecimal)
301
- obj.attributes[:amount].to_s.should == "1.23"
302
- obj.attributes[:total].should be_a(BigDecimal)
303
- obj.attributes[:total].to_s.should == "45.6"
304
- end
334
+ it "should allow to set attributes via data table" do
335
+ user = User.new
336
+ User.stub(:new => user)
305
337
 
306
- it "should allow set an array of strings with square brackets" do
307
- invoke_cucumber_step('there is a plain Ruby class with the tags ["foo", "bar"] and the list ["bam", "baz"]')
308
- obj = PlainRubyClass.last
309
- obj.attributes[:tags].should == ['foo', 'bar']
310
- obj.attributes[:list].should == ['bam', 'baz']
311
- end
338
+ invoke_cucumber_step('there is a user with these attributes:', nil, <<-DATA_TABLE)
339
+ | name | Jane |
340
+ | locked | true |
341
+ DATA_TABLE
312
342
 
313
- it "should allow set an array of numbers with square brackets" do
314
- invoke_cucumber_step('there is a plain Ruby class with the integers [1, 2] and the decimals [3.4, 4.5]')
315
- obj = PlainRubyClass.last
316
- obj.attributes[:integers].should == [1, 2]
317
- obj.attributes[:decimals].should == [BigDecimal('3.4'), BigDecimal('4.5')]
318
- end
343
+ user.name.should == "Jane"
344
+ user.locked.should == true
345
+ end
319
346
 
320
- it 'should allow to set an empty array' do
321
- invoke_cucumber_step('there is a plain Ruby class with the tags []')
322
- obj = PlainRubyClass.last
323
- obj.attributes[:tags].should == []
324
- end
347
+ it "should allow to set attributes via additional data table" do
348
+ user = User.new
349
+ User.stub(:new => user)
325
350
 
326
- it 'should allow to separate array values with either a comma or "and"' do
327
- invoke_cucumber_step('there is a plain Ruby class with the tags ["foo", "bar" and "baz"] and the list ["bam", "baz" and "qux"]')
328
- obj = PlainRubyClass.last
329
- obj.attributes[:tags].should == ['foo', 'bar', 'baz']
330
- obj.attributes[:list].should == ['bam', 'baz', 'qux']
331
- end
351
+ invoke_cucumber_step('there is a user with the email "test@invalid.com" and these attributes:', nil, <<-DATA_TABLE)
352
+ | name | Jane |
353
+ DATA_TABLE
332
354
 
333
- it 'should allow to separate array values with an Oxford comma' do
334
- invoke_cucumber_step('there is a plain Ruby class with the tags ["foo", "bar", and "baz"] and the list ["bam", "baz", and "qux"]')
335
- obj = PlainRubyClass.last
336
- obj.attributes[:tags].should == ['foo', 'bar', 'baz']
337
- obj.attributes[:list].should == ['bam', 'baz', 'qux']
338
- end
355
+ user.name.should == "Jane"
356
+ user.email.should == "test@invalid.com"
357
+ end
339
358
 
340
- it "should allow to set a has_many association by refering to multiple named records in square brackets" do
341
- invoke_cucumber_step('there is a movie with the title "Sunshine"')
342
- invoke_cucumber_step('there is a movie with the title "Limitless"')
343
- invoke_cucumber_step('there is a user with the reviewed movies ["Sunshine" and "Limitless"]')
344
- user = User.last
345
- reviewed_movie_titles = user.reviewed_movies.map(&:title)
346
- reviewed_movie_titles.should =~ ['Sunshine', 'Limitless']
347
- end
359
+ it 'should allow named records when setting attributes via data table' do
360
+ invoke_cucumber_step('"Some Prequel" is a movie with these attributes:', nil, <<-DATA_TABLE)
361
+ | title | Before Sunrise |
362
+ DATA_TABLE
363
+ invoke_cucumber_step('there is a movie with the title "Limitless"')
364
+ invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel "Some Prequel"')
365
+ movie = Movie.find_by_title!('Before Sunset')
366
+ prequel = Movie.find_by_title!('Before Sunrise')
367
+ movie.prequel.should == prequel
368
+ end
348
369
 
349
- it "should allow attribute names starting with 'the'" do
350
- PlainRubyClass.should_receive(:new).with({:theme => 'Sci-fi'})
351
- invoke_cucumber_step('there is a plain ruby class with the theme "Sci-fi"')
352
- end
370
+ it "should allow mixed single quotes for model names" do
371
+ invoke_cucumber_step("'Some Prequel' is a movie with the title \"Before Sunrise\"")
372
+ invoke_cucumber_step('there is a movie with the title "Limitless"')
373
+ invoke_cucumber_step('there is a movie with the title \'Before Sunset\' and the prequel "Some Prequel"')
374
+ movie = Movie.find_by_title!('Before Sunset')
375
+ prequel = Movie.find_by_title!('Before Sunrise')
376
+ movie.prequel.should == prequel
377
+ end
353
378
 
354
- it "should allow attribute names starting with 'and'" do
355
- PlainRubyClass.should_receive(:new).with({:android => 'Paranoid'})
356
- invoke_cucumber_step('there is a plain ruby class with the android "Paranoid"')
357
- end
379
+ it 'supports named associations with polymorphic associations' do
380
+ invoke_cucumber_step('"my opera" is an opera')
381
+ invoke_cucumber_step('there is a movie with the premiere site "my opera"')
382
+ end
358
383
 
359
- it "should allow attribute names starting with 'with'" do
360
- PlainRubyClass.should_receive(:new).with({:withdrawal => 'bank_account'})
361
- invoke_cucumber_step('there is a plain ruby class with the withdrawal "bank_account"')
362
- end
384
+ it 'does not support last record references with polymorphic associations as the target class cannot be guessed' do
385
+ invoke_cucumber_step('there is an opera')
386
+ expect {
387
+ invoke_cucumber_step('there is a movie with the premiere site above')
388
+ }.to raise_error(CucumberFactory::Factory::Error, 'Cannot set last Movie#premiere_site for polymorphic associations')
389
+ end
363
390
 
364
- it "should allow attribute names starting with 'but'" do
365
- PlainRubyClass.should_receive(:new).with({:butt => 'pear-shaped'})
366
- invoke_cucumber_step('there is a plain ruby class with the butt "pear-shaped"')
367
- end
391
+ it 'supports carrierwave uploaders' do
392
+ invoke_cucumber_step('there is a payment with the attachment file:"spec/assets/file.txt"')
393
+ payment = Payment.last
394
+ expect(payment.attachment.file.read).to eq "This is a test file.\n"
395
+ end
368
396
 
369
- it "should allow to set attributes via doc string" do
370
- user = User.new
371
- User.stub(:new => user)
397
+ it 'supports single quote for carrierwave uploaders' do
398
+ invoke_cucumber_step("there is a payment with the attachment file:'spec/assets/file.txt'")
399
+ payment = Payment.last
400
+ expect(payment.attachment.file.read).to eq "This is a test file.\n"
401
+ end
372
402
 
373
- invoke_cucumber_step('there is a user with these attributes:', <<-DOC_STRING)
374
- name: Jane
375
- locked: true
376
- DOC_STRING
403
+ it 'is able to read symlinked files' do
404
+ invoke_cucumber_step("there is a payment with the attachment file:'spec/assets/symlink.txt'")
405
+ payment = Payment.last
406
+ expect(payment.attachment.file.read).to eq "This is a test file.\n"
407
+ end
377
408
 
378
- user.name.should == "Jane"
379
- user.locked.should == true
380
- end
409
+ it 'supports table syntax for carrierwave uploaders' do
410
+ invoke_cucumber_step('there is a payment with these attributes:', nil, <<-DATA_TABLE)
411
+ | attachment | file:"spec/assets/file.txt" |
412
+ DATA_TABLE
413
+ payment = Payment.last
414
+ expect(payment.attachment.file.read).to eq "This is a test file.\n"
415
+ end
381
416
 
382
- it "should allow to set attributes via additional doc string" do
383
- user = User.new
384
- User.stub(:new => user)
417
+ it 'supports doc string syntax for carrierwave uploaders' do
418
+ invoke_cucumber_step('there is a payment with these attributes:', <<-DOC_STRING)
419
+ attachment: file:"spec/assets/file.txt"
420
+ DOC_STRING
421
+ payment = Payment.last
422
+ payment.save!
423
+ expect(payment.attachment.file.read).to eq "This is a test file.\n"
424
+ end
385
425
 
386
- invoke_cucumber_step('there is a user with the email "test@invalid.com" and these attributes:', <<-DOC_STRING)
387
- name: Jane
388
- DOC_STRING
426
+ it 'allows updating a carrierwave attribute' do
427
+ invoke_cucumber_step('there is a payment with the attachment file:"spec/assets/file.txt"')
428
+ payment = Payment.last
429
+ expect(payment.attachment.file.read).to eq "This is a test file.\n"
430
+ invoke_cucumber_step('the payment above has the attachment file:"spec/assets/file2.txt"')
431
+ payment.reload
432
+ expect(payment.attachment.file.read).to eq "This is the second test file.\n"
433
+ end
389
434
 
390
- user.name.should == "Jane"
391
- user.email.should == "test@invalid.com"
392
- end
435
+ it 'works with nested factories (BUGFIX)' do
436
+ invoke_cucumber_step('there is a subgenre movie')
437
+ end
393
438
 
394
- it "should allow to set array attributes via doc string" do
395
- invoke_cucumber_step('there is a plain Ruby class with these attributes:', <<-DOC_STRING)
396
- tags: ["foo", "bar"]
397
- DOC_STRING
439
+ describe 'references to named records are tracked correctly' do
440
+ # CucumberFactory keeps track of all created records by their attributes.
441
+ # For example, if you create a user with the name "Peter" you can reference him later on as "Peter".
398
442
 
399
- obj = PlainRubyClass.last
400
- obj.attributes[:tags].should == ['foo', 'bar']
401
- end
443
+ it 'does not overwrite existing references when associating new records with another reference (BUGFIX)' do
444
+ invoke_cucumber_step('"reviewer" is a user with the id "1"')
445
+ movie1 = invoke_cucumber_step('there is a movie with the reviewer "reviewer" and the id "2"') # <- should not overwrite the 'reviewer' reference
446
+ movie2 = invoke_cucumber_step('there is a movie with the reviewer "reviewer" and the id "3"')
402
447
 
403
- it 'should allow named records when setting attributes via doc string' do
404
- invoke_cucumber_step('"Some Prequel" is a movie with these attributes:', <<-DOC_STRING)
405
- title: Before Sunrise
406
- DOC_STRING
407
- invoke_cucumber_step('there is a movie with the title "Limitless"')
408
- invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel "Some Prequel"')
409
- movie = Movie.find_by_title!('Before Sunset')
410
- prequel = Movie.find_by_title!('Before Sunrise')
411
- movie.prequel.should == prequel
448
+ expect(movie1.reviewer_id).to eq(1)
449
+ expect(movie2.reviewer_id).to eq(1)
450
+ end
451
+
452
+ it 'does not set new references when setting primary keys of an association (BUGFIX)' do
453
+ movie1 = invoke_cucumber_step('there is a movie with the id "123" and the user id "456"') # <- should not set a '456' reference
454
+ movie2 = invoke_cucumber_step('there is a movie with the user id "456"')
455
+
456
+ expect(movie1.reviewer_id).to eq(456)
457
+ expect(movie2.reviewer_id).to eq(456)
458
+ end
459
+ end
412
460
  end
413
461
 
414
- it "should allow to set attributes via data table" do
415
- user = User.new
416
- User.stub(:new => user)
462
+ context 'without FactoryBot' do
463
+ before do
464
+ hide_const("FactoryBot")
465
+ end
417
466
 
418
- invoke_cucumber_step('there is a user with these attributes:', nil, <<-DATA_TABLE)
419
- | name | Jane |
420
- | locked | true |
421
- DATA_TABLE
467
+ it "should instantiate plain ruby classes by calling #new" do
468
+ PlainRubyClass.should_receive(:new).with({})
469
+ invoke_cucumber_step("there is a plain ruby class")
470
+ end
422
471
 
423
- user.name.should == "Jane"
424
- user.locked.should == true
425
- end
472
+ it "should instantiate namespaced classes" do
473
+ actor = People::Actor.new
474
+ People::Actor.should_receive(:new).and_return(actor)
475
+ invoke_cucumber_step("there is a people/actor")
476
+ end
426
477
 
427
- it "should allow to set attributes via additional data table" do
428
- user = User.new
429
- User.stub(:new => user)
478
+ it "should allow to set integer attributes without surrounding quotes" do
479
+ invoke_cucumber_step('there is a plain Ruby class with the amount 123 and the total 456')
480
+ obj = PlainRubyClass.last
481
+ obj.attributes[:amount].should == 123
482
+ obj.attributes[:total].should == 456
483
+ end
430
484
 
431
- invoke_cucumber_step('there is a user with the email "test@invalid.com" and these attributes:', nil, <<-DATA_TABLE)
432
- | name | Jane |
433
- DATA_TABLE
485
+ it "should allow to set decimal attributes without surrounding quotes" do
486
+ invoke_cucumber_step('there is a plain Ruby class with the amount 1.23 and the total 45.6')
487
+ obj = PlainRubyClass.last
488
+ obj.attributes[:amount].should be_a(BigDecimal)
489
+ obj.attributes[:amount].to_s.should == "1.23"
490
+ obj.attributes[:total].should be_a(BigDecimal)
491
+ obj.attributes[:total].to_s.should == "45.6"
492
+ end
434
493
 
435
- user.name.should == "Jane"
436
- user.email.should == "test@invalid.com"
437
- end
494
+ it "should allow to set file attributes with the file:'path' syntax" do
495
+ invoke_cucumber_step('there is a plain Ruby class with the file file:"spec/assets/file.txt"')
496
+ obj = PlainRubyClass.last
497
+ obj.attributes[:file].should be_a(File)
498
+ obj.attributes[:file].read.should == "This is a test file.\n"
499
+ end
438
500
 
439
- it "should allow to set array attributes via data table" do
440
- invoke_cucumber_step('there is a plain Ruby class with these attributes:', nil, <<-DATA_TABLE)
501
+ it "should allow set an array of strings with square brackets" do
502
+ invoke_cucumber_step('there is a plain Ruby class with the tags ["foo", "bar"] and the list ["bam", "baz"]')
503
+ obj = PlainRubyClass.last
504
+ obj.attributes[:tags].should == ['foo', 'bar']
505
+ obj.attributes[:list].should == ['bam', 'baz']
506
+ end
507
+
508
+ it "should allow set an array of numbers with square brackets" do
509
+ invoke_cucumber_step('there is a plain Ruby class with the integers [1, 2] and the decimals [3.4, 4.5]')
510
+ obj = PlainRubyClass.last
511
+ obj.attributes[:integers].should == [1, 2]
512
+ obj.attributes[:decimals].should == [BigDecimal('3.4'), BigDecimal('4.5')]
513
+ end
514
+
515
+ it 'should allow to set an empty array' do
516
+ invoke_cucumber_step('there is a plain Ruby class with the tags []')
517
+ obj = PlainRubyClass.last
518
+ obj.attributes[:tags].should == []
519
+ end
520
+
521
+ it 'should allow to separate array values with either a comma or "and"' do
522
+ invoke_cucumber_step('there is a plain Ruby class with the tags ["foo", "bar" and "baz"] and the list ["bam", "baz" and "qux"]')
523
+ obj = PlainRubyClass.last
524
+ obj.attributes[:tags].should == ['foo', 'bar', 'baz']
525
+ obj.attributes[:list].should == ['bam', 'baz', 'qux']
526
+ end
527
+
528
+ it 'should allow to separate array values with an Oxford comma' do
529
+ invoke_cucumber_step('there is a plain Ruby class with the tags ["foo", "bar", and "baz"] and the list ["bam", "baz", and "qux"]')
530
+ obj = PlainRubyClass.last
531
+ obj.attributes[:tags].should == ['foo', 'bar', 'baz']
532
+ obj.attributes[:list].should == ['bam', 'baz', 'qux']
533
+ end
534
+
535
+ it "should allow attribute names starting with 'the'" do
536
+ PlainRubyClass.should_receive(:new).with({:theme => 'Sci-fi'})
537
+ invoke_cucumber_step('there is a plain ruby class with the theme "Sci-fi"')
538
+ end
539
+
540
+ it "should allow attribute names starting with 'and'" do
541
+ PlainRubyClass.should_receive(:new).with({:android => 'Paranoid'})
542
+ invoke_cucumber_step('there is a plain ruby class with the android "Paranoid"')
543
+ end
544
+
545
+ it "should allow attribute names starting with 'with'" do
546
+ PlainRubyClass.should_receive(:new).with({:withdrawal => 'bank_account'})
547
+ invoke_cucumber_step('there is a plain ruby class with the withdrawal "bank_account"')
548
+ end
549
+
550
+ it "should allow attribute names starting with 'but'" do
551
+ PlainRubyClass.should_receive(:new).with({:butt => 'pear-shaped'})
552
+ invoke_cucumber_step('there is a plain ruby class with the butt "pear-shaped"')
553
+ end
554
+
555
+ it "should allow to set array attributes via doc string" do
556
+ invoke_cucumber_step('there is a plain Ruby class with these attributes:', <<-DOC_STRING)
557
+ tags: ["foo", "bar"]
558
+ DOC_STRING
559
+
560
+ obj = PlainRubyClass.last
561
+ obj.attributes[:tags].should == ['foo', 'bar']
562
+ end
563
+
564
+ it "should allow to set array attributes via data table" do
565
+ invoke_cucumber_step('there is a plain Ruby class with these attributes:', nil, <<-DATA_TABLE)
441
566
  | tags | ["foo", "bar"] |
442
- DATA_TABLE
567
+ DATA_TABLE
443
568
 
444
- obj = PlainRubyClass.last
445
- obj.attributes[:tags].should == ['foo', 'bar']
446
- end
569
+ obj = PlainRubyClass.last
570
+ obj.attributes[:tags].should == ['foo', 'bar']
571
+ end
447
572
 
448
- it 'should allow named records when setting attributes via data table' do
449
- invoke_cucumber_step('"Some Prequel" is a movie with these attributes:', nil, <<-DATA_TABLE)
450
- | title | Before Sunrise |
451
- DATA_TABLE
452
- invoke_cucumber_step('there is a movie with the title "Limitless"')
453
- invoke_cucumber_step('there is a movie with the title "Before Sunset" and the prequel "Some Prequel"')
454
- movie = Movie.find_by_title!('Before Sunset')
455
- prequel = Movie.find_by_title!('Before Sunrise')
456
- movie.prequel.should == prequel
457
- end
573
+ it "should create models that have a machinist blueprint by calling #make" do
574
+ MachinistModel.should_receive(:make).with({ :attribute => "foo"})
575
+ invoke_cucumber_step('there is a machinist model with the attribute "foo"')
576
+ end
458
577
 
459
- it "should allow single quote for attribute values" do
460
- MachinistModel.should_receive(:make).with({ :attribute => "foo"})
461
- invoke_cucumber_step("there is a machinist model with the attribute 'foo'")
462
- end
578
+ it "should be able to step_match machinist blueprint variants" do
579
+ MachinistModel.should_receive(:make).with(:variant, { :attribute => "foo"})
580
+ invoke_cucumber_step('there is a machinist model (variant) with the attribute "foo"')
581
+ end
463
582
 
464
- it "should allow mixed single and double quotes for different attribute values" do
465
- MachinistModel.should_receive(:make).with({ :attribute => "foo", :other_attribute => "bar" })
466
- invoke_cucumber_step("there is a machinist model with the attribute 'foo' and the other attribute \"bar\"")
467
- end
583
+ it "should be able to step_match machinist blueprint variants containing spaces or uppercase characters in prose" do
584
+ MachinistModel.should_receive(:make).with(:variant_mark_two, { :attribute => "foo"})
585
+ invoke_cucumber_step('there is a machinist model (Variant Mark Two) with the attribute "foo"')
586
+ end
468
587
 
469
- it "should allow mixed single quotes for model names" do
470
- invoke_cucumber_step("'Some Prequel' is a movie with the title \"Before Sunrise\"")
471
- invoke_cucumber_step('there is a movie with the title "Limitless"')
472
- invoke_cucumber_step('there is a movie with the title \'Before Sunset\' and the prequel "Some Prequel"')
473
- movie = Movie.find_by_title!('Before Sunset')
474
- prequel = Movie.find_by_title!('Before Sunrise')
475
- movie.prequel.should == prequel
476
- end
588
+ it "should allow single quote for attribute values" do
589
+ MachinistModel.should_receive(:make).with({ :attribute => "foo"})
590
+ invoke_cucumber_step("there is a machinist model with the attribute 'foo'")
591
+ end
477
592
 
478
- it 'should not raise an error for a blank instance name' do
479
- MachinistModel.should_receive(:make).with({ :attribute => 'foo' })
480
- invoke_cucumber_step("'' is a machinist model with the attribute 'foo'")
481
- end
593
+ it "should allow mixed single and double quotes for different attribute values" do
594
+ MachinistModel.should_receive(:make).with({ :attribute => "foo", :other_attribute => "bar" })
595
+ invoke_cucumber_step("there is a machinist model with the attribute 'foo' and the other attribute \"bar\"")
596
+ end
482
597
 
483
- it 'should warn if there are unused fragments' do
484
- MachinistModel.should_not_receive(:make)
485
- lambda { invoke_cucumber_step("there is a machinist model with the attribute NOQUOTES") }.should raise_error(ArgumentError, 'Unable to parse attributes " with the attribute NOQUOTES".')
486
- lambda { invoke_cucumber_step("there is a machinist model with the attribute 'foo' and the ") }.should raise_error(ArgumentError, 'Unable to parse attributes " and the ".')
487
- lambda { invoke_cucumber_step("there is a machinist model with the attribute 'foo'. the other_attribute 'bar' and the third attribute 'baz'") }.should raise_error(ArgumentError, 'Unable to parse attributes ".".')
488
- end
598
+ it 'should not raise an error for a blank instance name' do
599
+ MachinistModel.should_receive(:make).with({ :attribute => 'foo' })
600
+ invoke_cucumber_step("'' is a machinist model with the attribute 'foo'")
601
+ end
602
+
603
+ it 'should warn if there are unused fragments' do
604
+ MachinistModel.should_not_receive(:make)
605
+ lambda { invoke_cucumber_step("there is a machinist model with the attribute NOQUOTES") }.should raise_error(ArgumentError, 'Unable to parse attributes " with the attribute NOQUOTES".')
606
+ lambda { invoke_cucumber_step("there is a machinist model with the attribute 'foo' and the ") }.should raise_error(ArgumentError, 'Unable to parse attributes " and the ".')
607
+ lambda { invoke_cucumber_step("there is a machinist model with the attribute 'foo'. the other_attribute 'bar' and the third attribute 'baz'") }.should raise_error(ArgumentError, 'Unable to parse attributes ".".')
608
+ end
489
609
 
610
+ it "should allow to update the last record of a type" do
611
+ invoke_cucumber_step('there is a user with the name "Bar" and the email "foo@example.com" who is not subscribed')
612
+ invoke_cucumber_step('the user above has the name "Baz", the email "foobar@example.com", and is subscribed')
613
+ user = User.last
614
+ user.name.should == 'Baz'
615
+ user.email.should == 'foobar@example.com'
616
+ user.subscribed.should == true
617
+ end
618
+
619
+ it "should be able to update a record with a given name" do
620
+ invoke_cucumber_step('"Foo" is a user with the name "Bar"')
621
+ invoke_cucumber_step('the user "Foo" has the email "foo@example.com"')
622
+ invoke_cucumber_step("the user 'Foo' is subscribed")
623
+ user = User.last
624
+ user.name.should == 'Bar'
625
+ user.email.should == 'foo@example.com'
626
+ user.subscribed.should == true
627
+ end
628
+
629
+ it "should be able to update a record with a Cucumber table expression" do
630
+ invoke_cucumber_step('"Foo" is a user with the name "Bar"')
631
+ invoke_cucumber_step('the user above has these attributes:', nil, <<-DATA_TABLE)
632
+ | name | Jane |
633
+ | locked | true |
634
+ DATA_TABLE
635
+ user = User.last
636
+ user.name.should == "Jane"
637
+ user.locked.should == true
638
+ end
639
+
640
+ it "should allow to update a record via additional data table" do
641
+ invoke_cucumber_step('"Foo" is a user with the name "Bar"')
642
+ invoke_cucumber_step('the user above has the email "test@invalid.com", is subscribed, and has these attributes:', nil, <<-DATA_TABLE)
643
+ | name | Jane |
644
+ DATA_TABLE
645
+ user = User.last
646
+ user.name.should == "Jane"
647
+ user.email.should == "test@invalid.com"
648
+ user.subscribed.should == true
649
+ end
650
+
651
+ it "should allow to update an association" do
652
+ invoke_cucumber_step('there is a movie with the title "Before Sunrise"')
653
+ invoke_cucumber_step('there is a user with the name "John"')
654
+ invoke_cucumber_step('the movie above has the reviewer above')
655
+ movie = Movie.last
656
+ movie.reviewer.name.should == "John"
657
+ end
658
+ end
490
659
  end