cucumber_factory 1.9.2 → 1.10.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,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