cucumber_factory 1.9.2 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,5 @@
1
+ require 'cucumber/factory/build_strategy'
2
+
1
3
  module Cucumber
2
4
  class Factory
3
5
 
@@ -58,7 +60,8 @@ module Cucumber
58
60
  end
59
61
 
60
62
  def parse_creation(world, raw_model, raw_variant, raw_attributes, raw_boolean_attributes)
61
- model_class = model_class_from_prose(raw_model)
63
+ build_strategy = BuildStrategy.from_prose(raw_model, raw_variant)
64
+ model_class = build_strategy.model_class
62
65
  attributes = {}
63
66
  if raw_attributes.try(:strip).present?
64
67
  raw_attributes.scan(/(?:the|and|with|but|,| )+(.*?) ("([^\"]*)"|above)/).each do |fragment|
@@ -75,8 +78,7 @@ module Cucumber
75
78
  attributes[attribute] = flag
76
79
  end
77
80
  end
78
- variant = raw_variant.present? && /\((.*?)\)/.match(raw_variant)[1].downcase.gsub(" ", "_")
79
- record = create_record(model_class, variant, attributes)
81
+ record = build_strategy.create_record(attributes)
80
82
  remember_record_names(world, record, attributes)
81
83
  record
82
84
  end
@@ -99,35 +101,6 @@ module Cucumber
99
101
  prose.downcase.gsub(" ", "_").to_sym
100
102
  end
101
103
 
102
- def model_class_from_prose(prose)
103
- # don't use \w which depends on the system locale
104
- prose.gsub(/[^A-Za-z0-9_\/]+/, "_").camelize.constantize
105
- end
106
-
107
- def factory_girl_factory_name(name)
108
- name.to_s.underscore.gsub('/', '_').to_sym
109
- end
110
-
111
- def create_record(model_class, variant, attributes)
112
- fg_factory_name = factory_girl_factory_name(variant || model_class)
113
- if defined?(::FactoryGirl) && factory = ::FactoryGirl.factories[fg_factory_name]
114
- ::FactoryGirl.create(fg_factory_name, attributes)
115
- elsif model_class.respond_to?(:make) # Machinist blueprint
116
- if variant.present?
117
- model_class.make(variant.to_sym, attributes)
118
- else
119
- model_class.make(attributes)
120
- end
121
- elsif model_class.respond_to?(:create!) # Plain ActiveRecord
122
- model = model_class.new
123
- CucumberFactory::Switcher.assign_attributes(model, attributes)
124
- model.save!
125
- model
126
- else
127
- model_class.new(attributes)
128
- end
129
- end
130
-
131
104
  def remember_record_names(world, record, attributes)
132
105
  string_values = attributes.values.select { |v| v.is_a?(String) }
133
106
  for string_value in string_values
@@ -0,0 +1,90 @@
1
+ module Cucumber
2
+ class Factory
3
+
4
+ # wraps machinist / factory_girl / ruby object logic
5
+
6
+ class BuildStrategy
7
+
8
+ class << self
9
+
10
+ def from_prose(model_prose, variant_prose)
11
+ # don't use \w which depends on the system locale
12
+ underscored_model_name = model_prose.gsub(/[^A-Za-z0-9_\/]+/, "_")
13
+ variant = variant_prose.present? && /\((.*?)\)/.match(variant_prose)[1].downcase.gsub(" ", "_")
14
+
15
+ if factory_girl_strategy = factory_girl_strategy(variant || underscored_model_name)
16
+ factory_girl_strategy
17
+ else
18
+ model_class = underscored_model_name.camelize.constantize
19
+ machinist_strategy(model_class, variant) ||
20
+ active_record_strategy(model_class) ||
21
+ ruby_object_strategy(model_class)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def factory_girl_strategy(factory_name)
28
+ return unless defined?(::FactoryGirl)
29
+
30
+ factory_name = factory_name.to_s.underscore.gsub('/', '_').to_sym
31
+ if factory = ::FactoryGirl.factories[factory_name]
32
+
33
+ new(factory.build_class) do |attributes|
34
+ ::FactoryGirl.create(factory.name, attributes)
35
+ end
36
+
37
+ end
38
+ end
39
+
40
+ def machinist_strategy(model_class, variant)
41
+ if model_class.respond_to?(:make)
42
+
43
+ new(model_class) do |attributes|
44
+ if variant.present?
45
+ model_class.make(variant.to_sym, attributes)
46
+ else
47
+ model_class.make(attributes)
48
+ end
49
+ end
50
+
51
+ end
52
+ end
53
+
54
+ def active_record_strategy(model_class)
55
+ if model_class.respond_to?(:create!)
56
+
57
+ new(model_class) do |attributes|
58
+ model = model_class.new
59
+ CucumberFactory::Switcher.assign_attributes(model, attributes)
60
+ model.save!
61
+ model
62
+ end
63
+
64
+ end
65
+ end
66
+
67
+ def ruby_object_strategy(model_class)
68
+ new(model_class) do |attributes|
69
+ model_class.new(attributes)
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+
76
+ attr_reader :model_class
77
+
78
+ def initialize(model_class, &block)
79
+ @model_class = model_class
80
+ @create_proc = block
81
+ end
82
+
83
+ def create_record(attributes)
84
+ @create_proc.call(attributes)
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+ end
@@ -1,3 +1,3 @@
1
1
  module CucumberFactory
2
- VERSION = '1.9.2'
2
+ VERSION = '1.10.0'
3
3
  end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require_relative '../../support/factory_girl_mock'
3
+
4
+ describe Cucumber::Factory::BuildStrategy do
5
+
6
+ subject { Cucumber::Factory::BuildStrategy }
7
+
8
+ # most of the behaviour is integration tested in steps_spec.rb
9
+
10
+ describe '.from_prose' do
11
+
12
+ context 'when describing a factory girl factory' do
13
+
14
+ it 'returns a strategy corresponding to the factories model' do
15
+ FactoryGirl.stub_factories :job_offer => JobOffer
16
+ strategy = subject.from_prose('job offer', nil)
17
+
18
+ strategy.should be_a(described_class)
19
+ strategy.model_class.should == JobOffer
20
+ end
21
+
22
+ it 'uses the variant for the factory name if present' do
23
+ FactoryGirl.stub_factories :job_offer => JobOffer
24
+ strategy = subject.from_prose('foo', '(job offer)')
25
+
26
+ strategy.should be_a(described_class)
27
+ strategy.model_class.should == JobOffer
28
+ end
29
+
30
+ end
31
+
32
+ context 'when describing a non factory girl model' do
33
+
34
+ it "should return a strategy for the class matching a natural language expression" do
35
+ subject.from_prose("movie", nil).model_class.should == Movie
36
+ subject.from_prose("job offer", nil).model_class.should == JobOffer
37
+ end
38
+
39
+ it "should ignore variants for the class name" do
40
+ subject.from_prose("movie", "(job offer)").model_class.should == Movie
41
+ end
42
+
43
+ it "should allow namespaced models" do
44
+ subject.from_prose("people/actor", nil).model_class.should == People::Actor
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -3,12 +3,7 @@ require 'spec_helper'
3
3
  require_relative 'cucumber_helper'
4
4
  require 'cucumber'
5
5
  require 'cucumber/rb_support/rb_language'
6
-
7
- class FactoryGirl # for factory_girl compatibility spec
8
- def self.factories
9
- {}
10
- end
11
- end
6
+ require_relative '../support/factory_girl_mock'
12
7
 
13
8
  describe 'steps provided by cucumber_factory' do
14
9
 
@@ -39,17 +34,23 @@ describe 'steps provided by cucumber_factory' do
39
34
  end
40
35
 
41
36
  it "should create models that have a factory_girl factory by calling #FactoryGirl.create(:model_name)" do
42
- FactoryGirl.should_receive(:factories).with().and_return({ :job_offer => :job_offer_factory }) # Fake factory look up in factory_girl
37
+ FactoryGirl.stub_factories :job_offer => JobOffer
43
38
  FactoryGirl.should_receive(:create).with(:job_offer, { :title => "Awesome job" })
44
39
  invoke_cucumber_step('there is a job offer with the title "Awesome job"')
45
40
  end
46
41
 
47
- it "should create model variants that have a factory_girl factory by calling #FactoryGirl.create(:variant_name)" do
48
- FactoryGirl.should_receive(:factories).with().and_return({ :tempting_job_offer => :tempting_job_offer_factory }) # Fake factory look up in factory_girl
42
+ it "should create model variants that have a factory_girl factory by calling #FactoryGirl.create(:variant)" do
43
+ FactoryGirl.stub_factories :tempting_job_offer => JobOffer
49
44
  FactoryGirl.should_receive(:create).with(:tempting_job_offer, { :title => "Awesomafiablyfantasmic job" })
50
45
  invoke_cucumber_step('there is a job offer (tempting job offer) with the title "Awesomafiablyfantasmic job"')
51
46
  end
52
47
 
48
+ it "should create model variants that have a factory_girl factory by using the model name as a factory name" do
49
+ FactoryGirl.stub_factories :tempting_job_offer => JobOffer
50
+ FactoryGirl.should_receive(:create).with(:tempting_job_offer, { :title => "Awesomafiablyfantasmic job" })
51
+ invoke_cucumber_step('there is a tempting job offer with the title "Awesomafiablyfantasmic job"')
52
+ end
53
+
53
54
  it "should instantiate plain ruby classes by calling #new" do
54
55
  PlainRubyClass.should_receive(:new).with({})
55
56
  invoke_cucumber_step("there is a plain ruby class")
@@ -0,0 +1,17 @@
1
+ class FactoryGirl # for factory_girl compatibility spec
2
+
3
+ def self.factories
4
+ {}
5
+ end
6
+
7
+ Factory = Struct.new(:name, :build_class)
8
+
9
+ def self.stub_factories(hash)
10
+ factories = {}
11
+ hash.each do |name, build_class|
12
+ factories[name] = Factory.new(name, build_class)
13
+ end
14
+ FactoryGirl.stub :factories => factories
15
+ end
16
+ end
17
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cucumber_factory
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.2
4
+ version: 1.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-14 00:00:00.000000000 Z
12
+ date: 2015-02-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -121,6 +121,7 @@ files:
121
121
  - Rakefile
122
122
  - cucumber_factory.gemspec
123
123
  - lib/cucumber/factory.rb
124
+ - lib/cucumber/factory/build_strategy.rb
124
125
  - lib/cucumber/runtime_ext.rb
125
126
  - lib/cucumber_factory.rb
126
127
  - lib/cucumber_factory/switcher.rb
@@ -207,9 +208,10 @@ files:
207
208
  - spec/shared/app_root/db/migrate/003_create_payments.rb
208
209
  - spec/shared/app_root/db/migrate/004_create_actors.rb
209
210
  - spec/shared/cucumber_factory/cucumber_helper.rb
210
- - spec/shared/cucumber_factory/factory_spec.rb
211
+ - spec/shared/cucumber_factory/factory/build_strategy_spec.rb
211
212
  - spec/shared/cucumber_factory/runtime_ext_spec.rb
212
213
  - spec/shared/cucumber_factory/steps_spec.rb
214
+ - spec/shared/support/factory_girl_mock.rb
213
215
  homepage: http://github.com/makandra/cucumber_factory
214
216
  licenses:
215
217
  - MIT
@@ -231,8 +233,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
231
233
  version: '0'
232
234
  requirements: []
233
235
  rubyforge_project:
234
- rubygems_version: 1.8.23.2
236
+ rubygems_version: 1.8.25
235
237
  signing_key:
236
238
  specification_version: 3
237
239
  summary: Create records from Cucumber features without writing step definitions.
238
240
  test_files: []
241
+ has_rdoc:
@@ -1,29 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Cucumber::Factory do
4
-
5
- subject { Cucumber::Factory }
6
-
7
- describe 'model_class_from_prose' do
8
-
9
- it "should return the class matching a natural language expression" do
10
- subject.send(:model_class_from_prose, "movie").should == Movie
11
- subject.send(:model_class_from_prose, "job offer").should == JobOffer
12
- end
13
-
14
- it "should allow namespaced models" do
15
- subject.send(:model_class_from_prose, "people/actor").should == People::Actor
16
- end
17
-
18
- end
19
-
20
- describe 'factory_girl_factory_name' do
21
-
22
- it "should underscorize everything" do
23
- subject.send(:factory_girl_factory_name, People::Actor).should == :people_actor
24
- subject.send(:factory_girl_factory_name, JobOffer).should == :job_offer
25
- end
26
-
27
- end
28
-
29
- end