pickle 0.3.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,29 @@
1
+ == 0.4.0
2
+ Mongoid adapter, fallback ORM adapter for those not using machinist or active_record, bugfixes
3
+
4
+ * 2 major improvements
5
+ * adapter for Mongoid [Sebastian Zuchmanski]
6
+ * replace ActiveRecord 'factory' adapter with Orm adapter.
7
+
8
+ If you don't have machinist or factory_girl, the Orm factory adapter will fallback to your Orm to create classes.
9
+
10
+ BC: if you have a line like this:
11
+ Pickle.configure do |config|
12
+ config.adapters = [:active_record]
13
+ end
14
+
15
+ You need to replace it with :orm
16
+ Pickle.configure do |config|
17
+ config.adapters = [:orm]
18
+ end
19
+
20
+ * 1 minor improvement
21
+ * Pickle::Session::ModelNotKnownError is raised instead of a generic RuntimeError
22
+
23
+ * 1 bugfix
24
+ * references to unknown models in fields now raise ModelNotKnownError instead of silently assigning nil
25
+
26
+
1
27
  == 0.3.5
2
28
 
3
29
  * 3 improvements
data/README.rdoc CHANGED
@@ -3,7 +3,7 @@
3
3
  Pickle gives you cucumber steps that create your models easily from factory-girl or
4
4
  machinist factories/blueprints. You can also just use ActiveRecord as a factory but it's not as cool.
5
5
 
6
- Pickle can make use of different ORMs for finding records. Currently ActiveRecord and DataMapper adapters are
6
+ Pickle can make use of different ORMs for finding records. Currently ActiveRecord, DataMapper, MongoID adapters are
7
7
  provided. More adapters welcome!
8
8
 
9
9
  References to the models are stored in the current world, not necessarily for the purpose of checking the db
@@ -72,11 +72,11 @@ If you want path steps and email steps then just add the 'paths' and/or 'email'
72
72
  The code/steps will be written to <tt>features/env/paths.rb</tt> and
73
73
  <tt>features/step_definitions/email_steps.rb</tt> respectively.
74
74
 
75
- === Using with plain ole Active Record or DataMapper
75
+ === Using with plain ole Active Record, DataMapper or Mongoid
76
76
 
77
- Pickle comes with adapters for Active Record and DataMapper.
77
+ Pickle comes with adapters for Active Record, DataMapper and Mongoid.
78
78
 
79
- If you have an AR/DM called 'Post', with required fields 'title', and 'body', then you can now write
79
+ If you have a model called 'Post', with required fields 'title', and 'body', then you can now write
80
80
  steps like this
81
81
 
82
82
  Given a post exists with title: "My Post", body: "My body"
@@ -118,7 +118,7 @@ Adapters are very simple and exist a module or class with the name "PickleAdapte
118
118
  User.const_get(:PickleAdapter) #=> should return a pickle adapter
119
119
 
120
120
  The Active Record and DataMapper ones can be found at
121
- ActiveRecord::Base::PickleAdapter and DataMapper::Resource::PickleAdapter respectively.
121
+ ActiveRecord::Base::PickleAdapter, DataMapper::Resource::PickleAdapter, Mongoid::Document::PickleAdapter respectively.
122
122
 
123
123
  See how to implement one by looking at the ones provided in the pickle source in lib/pickle/adapters/*
124
124
 
@@ -133,13 +133,11 @@ In: <tt>features/support/pickle.rb</tt>
133
133
  require 'pickle/world'
134
134
 
135
135
  Pickle.configure do |config|
136
- config.adapters = [:machinist, YourOwnAdapterClass]
136
+ config.adapters = [:machinist, :active_record, YourOwnAdapterClass]
137
137
  config.map 'me', 'myself', 'my', 'I', :to => 'user: "me"'
138
138
  end
139
139
 
140
- Out of the box pickle looks for machinist, then factory-girl, then finally active-record 'factories'.
141
- If you find that your steps aren't working with your factories, it's probably the case that your factory
142
- setup is not being included in your cucumber environment (see comments above regarding machinist and factory-girl).
140
+ Out of the box pickle looks for machinist, then factory-girl. If you want to use active-record 'factories' you should add ":active_record" to adapters. If you find that your steps aren't working with your factories, it's probably the case that your factory setup is not being included in your cucumber environment (see comments above regarding machinist and factory-girl).
143
141
 
144
142
  == API
145
143
 
@@ -332,6 +330,7 @@ To run the features (rails 2.3 only ATM):
332
330
 
333
331
  The following people have made Pickle better:
334
332
 
333
+ * {Sebastian Zuchmanski}[http://github.com/sebcioz]
335
334
  * {Paul Gideon Dann}[http://github.com/giddie]
336
335
  * {Tom Meier}[http://github.com/tommeier]
337
336
  * {Sean Hussey}[http://github.com/seanhussey]
@@ -347,4 +346,4 @@ The following people have made Pickle better:
347
346
  * {Michael Moen}[http://github.com/UnderpantsGnome]
348
347
  * {Myron Marston}[http://github.com/myronmarston]
349
348
  * {Stephan Hagemann}[http://github.com/xing]
350
- * {Chris Flipse}[http://github.com/cflipse]
349
+ * {Chris Flipse}[http://github.com/cflipse]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.5
1
+ 0.4.0
@@ -4,7 +4,7 @@ Feature: I can easily create models from my blueprints
4
4
  I want to be able to create models with fields
5
5
  So that I can create models quickly and easily in my features
6
6
 
7
- @wip
7
+
8
8
  Scenario: I create a user, and see if it looks right
9
9
  Given a user exists with name: "Fred", has_stale_password: true
10
10
  Then the user should not have a status
@@ -56,4 +56,8 @@ Feature: I can easily create models from my factories
56
56
  Scenario: I create fork via a mapping
57
57
  Given killah fork exists
58
58
  Then the fork should be fancy
59
- And the fancy fork: "of cornwood" should be fancy
59
+ And the fancy fork: "of cornwood" should be fancy
60
+
61
+ Scenario: create a tine with a missing fork
62
+ Then the following should raise Pickle::Session::ModelNotKnownError: "Given a tine exists with fork: the fork"
63
+
@@ -0,0 +1,3 @@
1
+ Then /^the following should raise Pickle::Session::ModelNotKnownError: "([^"]*)"$/ do |step|
2
+ lambda { steps step }.should raise_error(Pickle::Session::ModelNotKnownError)
3
+ end
@@ -25,7 +25,7 @@ module Pickle
25
25
 
26
26
  self.model_classes = nil
27
27
 
28
- # Include this module into your adapter
28
+ # Include this module into your ORM adapter
29
29
  # this will register the adapter with pickle and it will be picked up for you
30
30
  # To create an adapter you should create an inner constant "PickleAdapter"
31
31
  #
@@ -33,6 +33,7 @@ module Pickle
33
33
  #
34
34
  # @see pickle/adapters/active_record
35
35
  # @see pickle/adapters/datamapper
36
+ # @see pickle/adapters/mongoid
36
37
  module Base
37
38
  def self.included(base)
38
39
  adapters << base
@@ -69,6 +70,10 @@ module Pickle
69
70
  def find_all_models(klass, conditions)
70
71
  klass.const_get(:PickleAdapter).find_all_models(klass, conditions)
71
72
  end
73
+
74
+ def create_model(klass, attributes)
75
+ klass.const_get(:PickleAdapter).create_model(klass, attributes)
76
+ end
72
77
  end
73
78
 
74
79
  # machinist adapter
@@ -113,10 +118,11 @@ module Pickle
113
118
  end
114
119
  end
115
120
 
116
- # fallback active record adapter
117
- class ActiveRecord < Adapter
121
+ # ORM adapter. If you have no factory adapter, you can use this adapter to
122
+ # use your orm as 'factory' - ie create objects
123
+ class Orm < Adapter
118
124
  def self.factories
119
- ::ActiveRecord::Base::PickleAdapter.model_classes.map{|k| new(k)}
125
+ model_classes.map{|k| new(k)}
120
126
  end
121
127
 
122
128
  def initialize(klass)
@@ -124,7 +130,7 @@ module Pickle
124
130
  end
125
131
 
126
132
  def create(attrs = {})
127
- @klass.send(:create!, attrs)
133
+ Pickle::Adapter.create_model(@klass, attrs)
128
134
  end
129
135
  end
130
136
  end
@@ -48,5 +48,10 @@ class ActiveRecord::Base
48
48
  def self.find_all_models(klass, conditions)
49
49
  klass.find(:all, :conditions => conditions)
50
50
  end
51
+
52
+ # Create a model using attributes
53
+ def self.create_model(klass, attributes)
54
+ klass.create!(attributes)
55
+ end
51
56
  end
52
57
  end
@@ -33,5 +33,10 @@ module DataMapper::Resource
33
33
  def self.find_all_models(klass, conditions)
34
34
  klass.all(conditions)
35
35
  end
36
+
37
+ # Create a model using attributes
38
+ def self.create_model(klass, attributes)
39
+ klass.create(attributes)
40
+ end
36
41
  end
37
42
  end
@@ -0,0 +1,44 @@
1
+ require 'mongoid'
2
+
3
+ module Mongoid
4
+ module Document
5
+ module PickleAdapter
6
+ include Pickle::Adapter::Base
7
+
8
+ # Do not consider these to be part of the class list
9
+ def self.except_classes
10
+ @@except_classes ||= []
11
+ end
12
+
13
+ # Gets a list of the available models for this adapter
14
+ def self.model_classes
15
+ ObjectSpace.each_object(Class).to_a.select {|klass| klass.ancestors.include? Mongoid::Document}
16
+ end
17
+
18
+ # get a list of column names for a given class
19
+ def self.column_names(klass)
20
+ klass.fields.keys
21
+ end
22
+
23
+ # Get an instance by id of the model
24
+ def self.get_model(klass, id)
25
+ klass.find(id)
26
+ end
27
+
28
+ # Find the first instance matching conditions
29
+ def self.find_first_model(klass, conditions)
30
+ klass.first(conditions)
31
+ end
32
+
33
+ # Find all models matching conditions
34
+ def self.find_all_models(klass, conditions)
35
+ klass.all(conditions)
36
+ end
37
+
38
+ # Create a model with given attributes
39
+ def self.create_model(klass, attributes)
40
+ klass.create!(attributes)
41
+ end
42
+ end
43
+ end
44
+ end
data/lib/pickle/config.rb CHANGED
@@ -11,7 +11,7 @@ module Pickle
11
11
  end
12
12
 
13
13
  def adapters
14
- @adapters ||= [:machinist, :factory_girl, :active_record]
14
+ @adapters ||= [:machinist, :factory_girl, :orm]
15
15
  end
16
16
 
17
17
  def adapter_classes
@@ -1,5 +1,18 @@
1
1
  module Pickle
2
2
  module Session
3
+ class ModelNotKnownError < RuntimeError
4
+ attr_reader :name
5
+
6
+ def initialize(name, message = nil)
7
+ @name = name
8
+ @message = message || "The model: '#{name}' is not known in this scenario. Use #create_model to create, or #find_model to find, and store a reference in this scenario."
9
+ end
10
+
11
+ def to_s
12
+ @message
13
+ end
14
+ end
15
+
3
16
  class << self
4
17
  def included(world_class)
5
18
  proxy_to_pickle_parser(world_class)
@@ -53,8 +66,8 @@ module Pickle
53
66
  record
54
67
  end
55
68
 
56
- def find_model!(a_model_name, fields = nil)
57
- find_model(a_model_name, fields) or raise "Can't find pickle model: '#{a_model_name}' in this scenario"
69
+ def find_model!(name, fields = nil)
70
+ find_model(name, fields) or raise ModelNotKnownError, name
58
71
  end
59
72
 
60
73
  def find_models(factory, fields = nil)
@@ -87,7 +100,7 @@ module Pickle
87
100
  elsif name_or_index.is_a?(Integer)
88
101
  models_by_index(factory)[name_or_index]
89
102
  else
90
- models_by_name(factory)[name_or_index] or raise "Can't find pickle model: '#{name}' in this scenario"
103
+ models_by_name(factory)[name_or_index] or raise ModelNotKnownError, name
91
104
  end
92
105
  end
93
106
 
@@ -110,12 +123,12 @@ module Pickle
110
123
 
111
124
  # like model, but raise an error if it can't be found
112
125
  def model!(name)
113
- model(name) or raise "Can't find pickle model: '#{name}' in this scenario"
126
+ model(name) or raise ModelNotKnownError, name
114
127
  end
115
128
 
116
129
  # like created_model, but raise an error if it can't be found
117
130
  def created_model!(name)
118
- created_model(name) or raise "Can't find pickle model: '#{name}' in this scenario"
131
+ created_model(name) or raise ModelNotKnownError, name
119
132
  end
120
133
 
121
134
  # return all original models of specified type
@@ -14,7 +14,7 @@ module Pickle
14
14
 
15
15
  def parse_field_with_model(field)
16
16
  if session && field =~ /^(\w+): #{capture_model}$/
17
- {$1 => session.model($2)}
17
+ {$1 => session.model!($2)}
18
18
  else
19
19
  parse_field_without_model(field)
20
20
  end
data/lib/pickle/world.rb CHANGED
@@ -1,8 +1,9 @@
1
1
  require 'pickle'
2
2
 
3
- # auto require for active record and datamapper
3
+ # auto require for active record, datamapper and mongoid
4
4
  require 'pickle/adapters/active_record' if defined?(ActiveRecord::Base)
5
5
  require 'pickle/adapters/data_mapper' if defined?(DataMapper::Resource)
6
+ require 'pickle/adapters/mongoid' if defined?(Mongoid::Document)
6
7
 
7
8
  # make cucumber world pickle aware
8
9
  World(Pickle::Session)
data/pickle.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{pickle}
8
- s.version = "0.3.5"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ian White"]
12
- s.date = %q{2010-08-12}
12
+ s.date = %q{2010-08-19}
13
13
  s.description = %q{Easy model creation and reference in your cucumber features}
14
14
  s.email = %q{ian.w.white@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -48,6 +48,7 @@ Gem::Specification.new do |s|
48
48
  "features/step_definitions/generator_steps.rb",
49
49
  "features/step_definitions/path_steps.rb",
50
50
  "features/step_definitions/pickle_steps.rb",
51
+ "features/step_definitions/raise_error_steps.rb",
51
52
  "features/support/email.rb",
52
53
  "features/support/env.rb",
53
54
  "features/support/paths.rb",
@@ -59,6 +60,7 @@ Gem::Specification.new do |s|
59
60
  "lib/pickle/adapter.rb",
60
61
  "lib/pickle/adapters/active_record.rb",
61
62
  "lib/pickle/adapters/data_mapper.rb",
63
+ "lib/pickle/adapters/mongoid.rb",
62
64
  "lib/pickle/config.rb",
63
65
  "lib/pickle/email.rb",
64
66
  "lib/pickle/email/parser.rb",
@@ -66,19 +66,19 @@ describe Pickle::Adapter do
66
66
 
67
67
  describe 'with class stubs' do
68
68
  before do
69
- ActiveRecord::Base::PickleAdapter.stub!(:model_classes).and_return([@klass1, @klass2, @klass3])
69
+ Pickle::Adapter::Orm.stub!(:model_classes).and_return([@klass1, @klass2, @klass3])
70
70
  end
71
71
 
72
72
  it ".factories should create one for each active record class" do
73
- Pickle::Adapter::ActiveRecord.should_receive(:new).with(@klass1).once
74
- Pickle::Adapter::ActiveRecord.should_receive(:new).with(@klass2).once
75
- Pickle::Adapter::ActiveRecord.should_receive(:new).with(@klass3).once
76
- Pickle::Adapter::ActiveRecord.factories
73
+ Pickle::Adapter::Orm.should_receive(:new).with(@klass1).once
74
+ Pickle::Adapter::Orm.should_receive(:new).with(@klass2).once
75
+ Pickle::Adapter::Orm.should_receive(:new).with(@klass3).once
76
+ Pickle::Adapter::Orm.factories.length.should == 3
77
77
  end
78
78
 
79
79
  describe ".new(Class)" do
80
80
  before do
81
- @factory = Pickle::Adapter::ActiveRecord.new(@klass2)
81
+ @factory = Pickle::Adapter::Orm.new(@klass2)
82
82
  end
83
83
 
84
84
  it "should have underscored (s/_) name of Class as #name" do
@@ -5,12 +5,12 @@ describe Pickle::Config do
5
5
  @config = Pickle::Config.new
6
6
  end
7
7
 
8
- it "#adapters should default to :machinist, :factory_girl, :active_record" do
9
- @config.adapters.should == [:machinist, :factory_girl, :active_record]
8
+ it "#adapters should default to :machinist, :factory_girl, :orm" do
9
+ @config.adapters.should == [:machinist, :factory_girl, :orm]
10
10
  end
11
11
 
12
- it "#adapter_classes should default to Adapter::Machinist, Adapter::FactoryGirl, Adapter::ActiveRecord" do
13
- @config.adapter_classes.should == [Pickle::Adapter::Machinist, Pickle::Adapter::FactoryGirl, Pickle::Adapter::ActiveRecord]
12
+ it "#adapter_classes should default to Adapter::Machinist, Adapter::FactoryGirl, Adapter::Orm" do
13
+ @config.adapter_classes.should == [Pickle::Adapter::Machinist, Pickle::Adapter::FactoryGirl, Pickle::Adapter::Orm]
14
14
  end
15
15
 
16
16
  describe "setting adapters to [:machinist, SomeAdapter]" do
@@ -29,22 +29,22 @@ describe Pickle::Config do
29
29
  it "should call adaptor.factories for each adaptor" do
30
30
  Pickle::Adapter::Machinist.should_receive(:factories).and_return([])
31
31
  Pickle::Adapter::FactoryGirl.should_receive(:factories).and_return([])
32
- Pickle::Adapter::ActiveRecord.should_receive(:factories).and_return([])
32
+ Pickle::Adapter::Orm.should_receive(:factories).and_return([])
33
33
  @config.factories
34
34
  end
35
35
 
36
36
  it "should aggregate factories into a hash using factory name as key" do
37
37
  Pickle::Adapter::Machinist.should_receive(:factories).and_return([@machinist = mock('machinist', :name => 'machinist')])
38
38
  Pickle::Adapter::FactoryGirl.should_receive(:factories).and_return([@factory_girl = mock('factory_girl', :name => 'factory_girl')])
39
- Pickle::Adapter::ActiveRecord.should_receive(:factories).and_return([@active_record = mock('active_record', :name => 'active_record')])
40
- @config.factories.should == {'machinist' => @machinist, 'factory_girl' => @factory_girl, 'active_record' => @active_record}
39
+ Pickle::Adapter::Orm.should_receive(:factories).and_return([@orm = mock('orm', :name => 'orm')])
40
+ @config.factories.should == {'machinist' => @machinist, 'factory_girl' => @factory_girl, 'orm' => @orm}
41
41
  end
42
42
 
43
43
  it "should give preference to adaptors first in the list" do
44
44
  Pickle::Adapter::Machinist.should_receive(:factories).and_return([@machinist_one = mock('one', :name => 'one')])
45
45
  Pickle::Adapter::FactoryGirl.should_receive(:factories).and_return([@factory_girl_one = mock('one', :name => 'one'), @factory_girl_two = mock('two', :name => 'two')])
46
- Pickle::Adapter::ActiveRecord.should_receive(:factories).and_return([@active_record_two = mock('two', :name => 'two'), @active_record_three = mock('three', :name => 'three')])
47
- @config.factories.should == {'one' => @machinist_one, 'two' => @factory_girl_two, 'three' => @active_record_three}
46
+ Pickle::Adapter::Orm.should_receive(:factories).and_return([@orm_two = mock('two', :name => 'two'), @orm_three = mock('three', :name => 'three')])
47
+ @config.factories.should == {'one' => @machinist_one, 'two' => @factory_girl_two, 'three' => @orm_three}
48
48
  end
49
49
  end
50
50
 
@@ -23,7 +23,7 @@ describe Pickle::Session do
23
23
  end
24
24
 
25
25
  let :user_factory do
26
- Pickle::Adapter::ActiveRecord.new(user_class)
26
+ Pickle::Adapter::Orm.new(user_class)
27
27
  end
28
28
 
29
29
  before do
@@ -257,7 +257,7 @@ describe Pickle::Session do
257
257
 
258
258
  it "should call raise error if find_model returns nil" do
259
259
  should_receive(:find_model).with('name', 'fields').and_return(nil)
260
- lambda { find_model!('name', 'fields') }.should raise_error(RuntimeError, "Can't find pickle model: 'name' in this scenario")
260
+ lambda { find_model!('name', 'fields') }.should raise_error(Pickle::Session::ModelNotKnownError)
261
261
  end
262
262
  end
263
263
 
@@ -425,10 +425,10 @@ describe Pickle::Session do
425
425
  end
426
426
 
427
427
  it "#model!('unknown') should raise informative error message" do
428
- lambda { model!('unknown') }.should raise_error("Can't find pickle model: 'unknown' in this scenario")
428
+ lambda { model!('unknown') }.should raise_error(Pickle::Session::ModelNotKnownError, "The model: 'unknown' is not known in this scenario. Use #create_model to create, or #find_model to find, and store a reference in this scenario.")
429
429
  end
430
430
 
431
431
  it "#created_model!('unknown') should raise informative error message" do
432
- lambda { created_model!('unknown') }.should raise_error("Can't find pickle model: 'unknown' in this scenario")
432
+ lambda { created_model!('unknown') }.should raise_error(Pickle::Session::ModelNotKnownError)
433
433
  end
434
434
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pickle
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
9
- - 5
10
- version: 0.3.5
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ian White
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-12 00:00:00 +01:00
18
+ date: 2010-08-19 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -117,6 +117,7 @@ files:
117
117
  - features/step_definitions/generator_steps.rb
118
118
  - features/step_definitions/path_steps.rb
119
119
  - features/step_definitions/pickle_steps.rb
120
+ - features/step_definitions/raise_error_steps.rb
120
121
  - features/support/email.rb
121
122
  - features/support/env.rb
122
123
  - features/support/paths.rb
@@ -128,6 +129,7 @@ files:
128
129
  - lib/pickle/adapter.rb
129
130
  - lib/pickle/adapters/active_record.rb
130
131
  - lib/pickle/adapters/data_mapper.rb
132
+ - lib/pickle/adapters/mongoid.rb
131
133
  - lib/pickle/config.rb
132
134
  - lib/pickle/email.rb
133
135
  - lib/pickle/email/parser.rb