sham 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,6 +2,7 @@ bin/
2
2
  pkg/*
3
3
  *.gem
4
4
  *.swp
5
+ *.rbc
5
6
  .bundle
6
7
  .rvmrc
7
8
  Gemfile.lock
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - jruby-18mode
7
+ - jruby-19mode
8
+ - rbx-18mode
9
+ - rbx-19mode
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gemspec
4
+
5
+ gem 'rake'
@@ -8,66 +8,66 @@ Lightweight flexible factories for Ruby and Rails testing.
8
8
 
9
9
  ## Getting Started
10
10
 
11
- Create a sham file for each of your models:
11
+ Create a configuration file for any of your models or classes.
12
12
 
13
- # in sham/user.rb
13
+ # sham/user.rb
14
14
  Sham.config(User) do |c|
15
15
  c.attributes do
16
16
  { :name => "Sample User" }
17
17
  end
18
18
  end
19
19
 
20
- To load your shams you can either include the files individually, or define
21
- your shams directly in your test file. Sham also provides a helper function to
22
- load shams under the sham directory. To load all your shams add the following to
23
- your application.rb or test.rb file:
20
+ To load a shams you can either include the configuration file directly, or
21
+ define the sham inline in a test file. Sham provides a helper function to
22
+ load all files under the sham directory. If you are using Rails you can load
23
+ all your shams by adding the following to `config/environments/test.rb`.
24
24
 
25
25
  config.after_initialize do
26
26
  Sham::Config.activate!
27
27
  end
28
28
 
29
- If you are not using Rails you can activate all of your shams by specifying a
30
- path under which your shams are defined. For instance, this command will load
31
- all Ruby files under the `/my/project/path/sham` directory and and all
32
- subdirectories.
29
+ If you aren't using Rails you can activate all of your shams by specifying a
30
+ configuration path. The following command will load all Ruby files under the
31
+ `/my/project/path/sham` directory.
33
32
 
34
33
  Sham::Config.activate!('/my/project/path')
35
34
 
36
- To enable all Shams in cucumber, add the following to your
37
- features/support/env.rb file:
35
+ To load all your shams in Cucumber, modify your `features/support/env.rb` file.
38
36
 
39
37
  require 'sham'
40
38
  Sham::Config.activate!
41
39
 
42
- You can now "sham" your models and pass additional attributes at creation:
40
+ You can now "sham" your models! When you sham a model it is created with the
41
+ default options you specified in the config file. But you can also overwrite
42
+ any number of them and add additional attributes on a case-by-case basis.
43
43
 
44
44
  User.sham!
45
45
  User.sham!(:name => "New Name")
46
46
  User.sham!(:age => 23)
47
47
 
48
- You can use sham to build models without automatically saving them as well:
48
+ Sham can also create objects without automatically saving using the `:build`
49
+ option.
49
50
 
50
51
  user = User.sham!(:build, :name => "I have not been saved")
51
52
  user.save
52
53
 
53
54
  ## RSpec Example
54
55
 
55
- Here is an example of testing validations on an ActiveRecord::Base class using
56
- Sham and RSpec.
56
+ The following is an example of an RSpec test for `ActiveRecord` validations.
57
57
 
58
- # in app/models/item.rb
58
+ # app/models/item.rb
59
59
  class Item < ActiveRecord::Base
60
60
  validates_numericality_of :quantity, :greater_than => 0
61
61
  end
62
62
 
63
- # in sham/item.rb
63
+ # sham/item.rb
64
64
  Sham.config(Item) do |c|
65
65
  c.attributes do
66
66
  { :quantity => 1 }
67
67
  end
68
68
  end
69
69
 
70
- # in spec/models/item_spec.rb
70
+ # spec/models/item_spec.rb
71
71
  require 'spec_helper'
72
72
  require './sham/item'
73
73
 
@@ -83,11 +83,45 @@ Sham and RSpec.
83
83
  end
84
84
  end
85
85
 
86
- ## Alternative Shams
86
+ ## Parameter/Argument Shams
87
87
 
88
- You can easily define alternative sham configurations:
88
+ You can also define shams for initializers that take a list of arguments
89
+ instead of an attribute hash. For example, if you had a `User` class.
89
90
 
90
- # in sham/item.rb
91
+ # lib/user.rb
92
+ class User
93
+ attr_accessor :first, :last
94
+
95
+ def initialize(first, last)
96
+ self.first = first
97
+ self.last = last
98
+ end
99
+ end
100
+
101
+ You could create a parameter sham like this:
102
+
103
+ # sham/user.rb
104
+ Sham.config(User) do |c|
105
+ c.parameters do
106
+ ['John', 'Doe']
107
+ end
108
+ end
109
+
110
+ And invoke it like this:
111
+
112
+ User.sham!
113
+ User.sham!('Jane', 'Doe')
114
+
115
+ Unlike attribute shams, if arguments are passed to a parameter sham, those
116
+ arguments are the only ones passed to the constructor and the parameters are
117
+ not merged with the defaults.
118
+
119
+ ## Multiple Sham Configurations
120
+
121
+ Sometimes you want to be able to configure more than one sham per class. Sham
122
+ makes it easy to define alternative configurations by specifying a config name.
123
+
124
+ # sham/item.rb
91
125
  Sham.config(Item, :small) do |c|
92
126
  c.attributes do
93
127
  { :weight => 10.0 }
@@ -100,46 +134,56 @@ You can easily define alternative sham configurations:
100
134
  end
101
135
  end
102
136
 
103
- These can be invoked using:
137
+ Alternative sham configurations can be invoked by passing their name into the
138
+ `sham!` command.
104
139
 
105
140
  Item.sham!(:small, :quantity => 100)
106
141
  Item.sham!(:large, :build, :quantity => 0)
107
142
 
108
143
  ## Empty Shams
109
144
 
110
- You can easily define empty shams using the empty function:
145
+ Sometimes you simply want to be able to sham an object without passing any
146
+ default options. Sham makes this easy by providing an `empty` configuration.
111
147
 
112
- # in sham/user.rb
113
- Sham.config(User) do |c|
114
- c.empty
115
- end
148
+ # sham/user.rb
149
+ Sham.config(User){ |c| c.empty }
116
150
 
117
- This can be invoked using:
151
+ Empty configurations behave just like empty hashes. That means you can simply
152
+ pass your own attributes in when shamming the class.
118
153
 
119
154
  User.sham!
155
+ User.sham!(:name => 'John Doe')
156
+
157
+ For parameter based shams you can create empty configurations using the
158
+ `no_args` option.
159
+
160
+ Sham.config(User){ |c| c.no_args }
120
161
 
121
- ## Nested Shamming
162
+ ## Nested Shams
122
163
 
123
- You can nest shammed models inside others:
164
+ Sometimes you want one sham to be responsible for creating additional shams when
165
+ it is initialized. For instance, a `LineItem` might require an `Item` to be
166
+ considered a valid object. Sham makes this kind of nested sham very easy to
167
+ configure, and allows you to overwrite the 'sub-object' during initialization.
124
168
 
125
- # in sham/line_item_sham.rb
169
+ # sham/line_item_sham.rb
126
170
  Sham.config(LineItem) do |c|
127
171
  c.attributes do
128
- { :item => Sham::Base.new(Item) }
172
+ { :item => Sham::Nested.new(Item) }
129
173
  end
130
174
  end
131
175
 
132
- The nested shams will automatically be invoked and can be overridden during a
133
- sham call:
176
+ The nested shams will automatically be created and can also be overwritten
177
+ during initialization:
134
178
 
135
179
  LineItem.sham!
136
180
  LineItem.sham!(:item => Item.sham!(:weight => 100))
137
181
 
138
182
 
139
- ## Subclass Shams
183
+ ## Sham Inheritance
140
184
 
141
- Sham plays well with subclassing. That means shams defined on parent classes
142
- will be available to child classes as well:
185
+ Sham plays well with inheritance. That means shams defined on parent classes
186
+ will be available to child classes as well.
143
187
 
144
188
  Sham.config(Person) do |c|
145
189
  c.empty
@@ -150,6 +194,9 @@ will be available to child classes as well:
150
194
 
151
195
  Employee.sham!
152
196
 
197
+ You can also define different shams for your subclasses instead of relying on
198
+ the parent object.
199
+
153
200
  ## Reloading Shams with Spork
154
201
 
155
202
  [Spork](https://rubygems.org/gems/spork) is a great gem that creates a
@@ -158,14 +205,16 @@ against. If you are using Rails it is often necessary to re-load your models and
158
205
  controllers between Spork test runs so that the Spork DRB picks up your latest
159
206
  model changes. This is usually accomplished using a Spork 'each run' block. This
160
207
  block of code gets executed before each test run. If you want to be able to
161
- reload your shams with Spork all you need to do is add a Sham::Config.activate!
162
- line to this block after you have re-loaded your models and controllers.
208
+ reload your shams with Spork all you need to do is add a
209
+ `Sham::Config.activate!` line to this block after you have re-loaded your models
210
+ and controllers.
163
211
 
164
212
  Spork.each_run do
165
- ActiveSupport::Dependencies.clear
166
- ActiveRecord::Base.instantiate_observers
167
213
  Sham::Config.activate!
168
214
  end if Spork.using_spork?
169
215
 
170
216
  This change will cause sham to be re-loaded so that you can continue to use it
171
- with Spork.
217
+ with Spork. If you take this approach it's important to remove the call to
218
+ `Sham::Config.activate!` from your `test.rb` file.
219
+
220
+ ## Build Status [![Build Status](https://secure.travis-ci.org/panthomakos/sham.png)](http://travis-ci.org/panthomakos/sham)
data/Rakefile CHANGED
@@ -1,2 +1,8 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task :default => :spec
@@ -3,6 +3,7 @@ module Sham; end
3
3
  require 'sham/data'
4
4
  require 'sham/util'
5
5
  require 'sham/base'
6
+ require 'sham/nested'
6
7
  require 'sham/config'
7
8
  require 'sham/shammable'
8
9
 
@@ -1,14 +1,12 @@
1
1
  module Sham
2
2
  class Base
3
- attr_accessor :klass, :options
4
-
5
- def initialize klass, options = {}
3
+ def initialize klass, *args
6
4
  @klass = klass
7
- @options = options
5
+ @args = args
8
6
  end
9
7
 
10
8
  def sham!
11
- @klass.sham!(@options)
9
+ @klass.sham!(*@args)
12
10
  end
13
11
  end
14
12
  end
@@ -1,10 +1,16 @@
1
+ require 'sham/shammable'
2
+ require 'sham/config/attributes'
3
+ require 'sham/config/parameters'
4
+ require 'sham/config/empty'
5
+ require 'sham/config/no_args'
6
+
1
7
  module Sham
2
8
  class << self
3
9
  def config klass, name = :default
4
- unless klass.include?(Sham::Shammable)
5
- klass.send(:include, Sham::Shammable)
10
+ unless (class << klass; self; end).include?(Sham::Shammable)
11
+ klass.extend(Sham::Shammable)
6
12
  end
7
- yield(Sham::Config.new(klass, name))
13
+ yield(Sham::Config.new(klass, name)) if block_given?
8
14
  end
9
15
  end
10
16
 
@@ -15,19 +21,25 @@ module Sham
15
21
  Dir[root].each{ |f| load(f) }
16
22
  end
17
23
 
18
- attr_accessor :klass, :name
19
-
20
24
  def initialize klass, name
21
- self.klass = klass
22
- self.name = name
25
+ @klass = klass
26
+ @name = name
27
+ end
28
+
29
+ def attributes(&config)
30
+ @klass.add_sham_config(@name, Sham::Config::Attributes.new(config))
23
31
  end
24
32
 
25
- def attributes &config
26
- klass.add_sham_config(name, config)
33
+ def parameters(&config)
34
+ @klass.add_sham_config(@name, Sham::Config::Parameters.new(config))
27
35
  end
28
36
 
29
37
  def empty
30
- klass.add_sham_config(name, Proc.new{ Hash.new() })
38
+ @klass.add_sham_config(@name, Sham::Config::Empty.new)
39
+ end
40
+
41
+ def no_args
42
+ @klass.add_sham_config(@name, Sham::Config::NoArgs.new)
31
43
  end
32
44
  end
33
45
  end
@@ -0,0 +1,26 @@
1
+ require 'sham/config/base'
2
+ require 'sham/util'
3
+
4
+ module Sham
5
+ class Config
6
+ class Attributes < Base
7
+ def initialize(config)
8
+ @config = config
9
+ end
10
+
11
+ def options(*args)
12
+ @options = ::Sham::Util.extract_options!(args)
13
+
14
+ @config.call.each do |key, value|
15
+ @options[key] = parse!(value) unless @options.has_key?(key)
16
+ end
17
+
18
+ self
19
+ end
20
+
21
+ def args
22
+ [@options]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,35 @@
1
+ require 'sham/nested'
2
+
3
+ module Sham
4
+ class Config
5
+ class Base
6
+ def object(klass)
7
+ @klass = klass
8
+
9
+ self
10
+ end
11
+
12
+ def sham(build = false)
13
+ if build || !@klass.respond_to?(:create)
14
+ @klass.new(*args)
15
+ else
16
+ @klass.create(*args)
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def parse! value
23
+ if value.is_a?(Array)
24
+ value.map{ |k| parse!(k) }
25
+ elsif value.is_a?(Hash)
26
+ Hash.new value.map{ |k,v| [k, parse!(v)] }
27
+ elsif value.is_a?(Sham::Nested)
28
+ value.sham!
29
+ else
30
+ value
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ require 'sham/config/base'
2
+ require 'sham/util'
3
+
4
+ module Sham
5
+ class Config
6
+ class Empty < Base
7
+ def options(*args)
8
+ @options = ::Sham::Util.extract_options!(args)
9
+
10
+ self
11
+ end
12
+
13
+ def args
14
+ [@options]
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'sham/config/base'
2
+ require 'sham/util'
3
+
4
+ module Sham
5
+ class Config
6
+ class NoArgs < Base
7
+ def options(*args)
8
+ @args = args
9
+
10
+ self
11
+ end
12
+
13
+ def args
14
+ @args
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ require 'sham/config/base'
2
+
3
+ module Sham
4
+ class Config
5
+ class Parameters < Base
6
+ def initialize(config)
7
+ @config = config
8
+ end
9
+
10
+ def options(*args)
11
+ @args = args
12
+
13
+ if @args.empty?
14
+ @config.call.each do |arg|
15
+ @args << parse!(arg)
16
+ end
17
+ end
18
+
19
+ self
20
+ end
21
+
22
+ def args
23
+ @args
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ require 'sham/base'
2
+
3
+ module Sham
4
+ Nested = Sham::Base
5
+ end
@@ -1,63 +1,38 @@
1
+ require 'sham/util'
2
+
1
3
  module Sham
2
- class << self
3
- def parse! value
4
- if value.is_a?(Array)
5
- value.map{ |k| parse!(k) }
6
- elsif value.is_a?(Hash)
7
- Hash.new value.map{ |k,v| [k, parse!(v)] }
8
- elsif value.is_a?(Sham::Base)
9
- value.sham!
10
- else
11
- value
12
- end
4
+ module Shammable
5
+ def add_sham_config(name, config)
6
+ @sham_configs ||= {}
7
+ @sham_configs[name] = config
13
8
  end
14
9
 
15
- def add_options! klass, options, attributes
16
- options ||= {}
17
- attributes.call.each do |key, value|
18
- options[key] = parse!(value) unless options.has_key?(key)
10
+ def sham_config(name)
11
+ if @sham_configs && @sham_configs.has_key?(name)
12
+ @sham_configs[name]
13
+ elsif superclass.respond_to?(:sham_config)
14
+ superclass.sham_config(name)
19
15
  end
20
16
  end
21
- end
22
17
 
23
- module Shammable
24
- def self.included(klass)
25
- klass.extend(ClassMethods)
26
-
27
- (class << klass; self; end).instance_eval do
28
- attr_accessor :sham_configs
29
-
30
- define_method(:add_sham_config) do |name, config|
31
- self.sham_configs ||= {}
32
- self.sham_configs[name] = config
33
- end
34
-
35
- define_method(:sham_config) do |name|
36
- if sham_configs && sham_configs.has_key?(name)
37
- sham_configs[name]
38
- else
39
- superclass.sham_config(name)
40
- end
41
- end
42
- end
18
+ def sham!(*args)
19
+ build = extract_build!(args)
20
+ type = extract_type!(args) || :default
21
+ build ||= extract_build!(args)
22
+
23
+ sham_config(type).object(self).options(*args).sham(build == :build)
43
24
  end
44
25
 
45
- module ClassMethods
46
- def sham! *args
47
- options = Sham::Util.extract_options!(args)
48
- type = (args[0] == :build ? args[1] : args[0]) || :default
49
- build = args[0] == :build || args[1] == :build
50
-
51
- ::Sham.add_options!(name, options, sham_config(type))
52
- klass = Sham::Util.constantize(options.delete(:type) || self.name)
53
- if build || !klass.respond_to?(:create)
54
- klass.new(options)
55
- else
56
- klass.create(options)
57
- end
58
- end
26
+ alias :sham_alternate! :sham!
27
+
28
+ private
29
+
30
+ def extract_build!(args)
31
+ args.shift if args.first == :build
32
+ end
59
33
 
60
- alias :sham_alternate! :sham!
34
+ def extract_type!(args)
35
+ args.shift if sham_config(args.first)
61
36
  end
62
37
  end
63
38
  end
@@ -1,3 +1,3 @@
1
1
  module Sham
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
@@ -0,0 +1,16 @@
1
+ require 'sham/base'
2
+
3
+ describe Sham::Base do
4
+ let(:klass){ stub }
5
+
6
+ it 'should call sham! on the class' do
7
+ klass.should_receive(:sham!)
8
+ described_class.new(klass).sham!
9
+ end
10
+
11
+ it 'should pass sham options' do
12
+ options = stub
13
+ klass.should_receive(:sham!).with(options)
14
+ described_class.new(klass, options).sham!
15
+ end
16
+ end
@@ -0,0 +1,44 @@
1
+ require 'sham/config/attributes'
2
+
3
+ describe Sham::Config::Attributes do
4
+ before(:all) do
5
+ Object.send(:remove_const, :AttributesTester) if defined?(AttributesTester)
6
+ class AttributesTester
7
+ attr_accessor :id
8
+
9
+ def initialize(options)
10
+ self.id = options[:id]
11
+ end
12
+ end
13
+ end
14
+
15
+ let(:id){ stub }
16
+ let(:options){ { :id => id } }
17
+ let(:subject){ described_class.new(lambda{ options }) }
18
+ let(:config){ subject.object(AttributesTester) }
19
+
20
+ it 'passes default options' do
21
+ AttributesTester.should_receive(:new).with(options)
22
+ config.options.sham
23
+ end
24
+
25
+ it 'prioritizes passed options' do
26
+ AttributesTester.should_receive(:new).with({ :id => 2 })
27
+ config.options(:id => 2).sham
28
+ end
29
+
30
+ it 'merges passed options' do
31
+ AttributesTester.should_receive(:new).with({ :id => id, :name => 'A' })
32
+ config.options(:name => 'A').sham
33
+ end
34
+
35
+ it 'parses default options' do
36
+ subject.should_receive(:parse!).with(id)
37
+ config.options.sham
38
+ end
39
+
40
+ it 'does not parse passed options' do
41
+ subject.should_receive(:parse!).with(2).never
42
+ config.options(:id => 2).sham
43
+ end
44
+ end
@@ -0,0 +1,26 @@
1
+ require 'sham/config/empty'
2
+
3
+ describe Sham::Config::Empty do
4
+ before(:all) do
5
+ Object.send(:remove_const, :EmptyTester) if defined?(EmptyTester)
6
+ class EmptyTester
7
+ attr_accessor :id
8
+
9
+ def initialize(options)
10
+ self.id = options[:id]
11
+ end
12
+ end
13
+ end
14
+
15
+ let(:config){ subject.object(EmptyTester) }
16
+
17
+ it 'passes an empty hash by default' do
18
+ EmptyTester.should_receive(:new).with({})
19
+ config.options.sham
20
+ end
21
+
22
+ it 'allows passed options' do
23
+ EmptyTester.should_receive(:new).with(:id => 1)
24
+ config.options(:id => 1).sham
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ require 'sham/config/no_args'
2
+
3
+ describe Sham::Config::NoArgs do
4
+ before(:all) do
5
+ Object.send(:remove_const, :NoArgsTester) if defined?(NoArgsTester)
6
+ class NoArgsTester
7
+ attr_accessor :name
8
+
9
+ def initialize(name = nil)
10
+ self.name = name
11
+ end
12
+ end
13
+ end
14
+
15
+ let(:config){ subject.object(NoArgsTester) }
16
+
17
+ it 'does not pass parameters by default' do
18
+ NoArgsTester.should_receive(:new).with()
19
+ config.options.sham
20
+ end
21
+
22
+ it 'allows passed parameters' do
23
+ NoArgsTester.should_receive(:new).with(1)
24
+ config.options(1).sham
25
+ end
26
+ end
@@ -0,0 +1,43 @@
1
+ require 'sham/config/parameters'
2
+
3
+ describe Sham::Config::Parameters do
4
+ before(:all) do
5
+ Object.send(:remove_const, :ParamTester) if defined?(ParamTester)
6
+ class ParamTester
7
+ attr_accessor :first, :last
8
+
9
+ def initialize(first, last)
10
+ self.first = first
11
+ self.last = last
12
+ end
13
+ end
14
+ end
15
+
16
+ let(:first){ stub }
17
+ let(:last){ stub }
18
+ let(:params){ [first, last] }
19
+ let(:subject){ described_class.new(lambda{ params }) }
20
+ let(:config){ subject.object(ParamTester) }
21
+
22
+ it 'passes default options' do
23
+ ParamTester.should_receive(:new).with(*params)
24
+ config.options.sham
25
+ end
26
+
27
+ it 'prioritizes passed options' do
28
+ ParamTester.should_receive(:new).with('A', 'B')
29
+ config.options('A', 'B').sham
30
+ end
31
+
32
+ it 'parses default options' do
33
+ subject.should_receive(:parse!).with(first)
34
+ subject.should_receive(:parse!).with(last)
35
+ config.options.sham
36
+ end
37
+
38
+ it 'does not parse passed options' do
39
+ subject.should_receive(:parse!).with(1).never
40
+ subject.should_receive(:parse!).with(2).never
41
+ config.options(1, 2).sham
42
+ end
43
+ end
@@ -0,0 +1,185 @@
1
+ require 'sham/config'
2
+
3
+ describe Sham::Config do
4
+ let(:parent) do
5
+ Object.send(:remove_const, :Parent) if defined?(Parent)
6
+ class Parent; end
7
+ Parent
8
+ end
9
+ let(:child) do
10
+ Object.send(:remove_const, :Child) if defined?(Child)
11
+ class Child < parent; end
12
+ Child
13
+ end
14
+
15
+ context '#activate!' do
16
+ it 'activates shams in the root directory' do
17
+ begin
18
+ expect {
19
+ described_class.activate!('spec/root')
20
+ }.to change{ defined?(Employee) }.from(nil).to('constant')
21
+ ensure
22
+ Object.send(:remove_const, :Employee) rescue nil
23
+ end
24
+ end
25
+ end
26
+
27
+ context '#config' do
28
+ it 'extends the class with Sham::Shammable' do
29
+ expect { Sham.config(parent) } \
30
+ .to change{ (class << parent; self; end).include?(Sham::Shammable) } \
31
+ .from(false).to(true)
32
+ end
33
+
34
+ it 'only extends with Sham::Shammable once' do
35
+ Sham.config(parent)
36
+ parent.should_receive(:extend).never
37
+
38
+ Sham.config(parent, :alternate)
39
+ end
40
+
41
+ it 'defines sham! on the class' do
42
+ expect { Sham.config(parent) } \
43
+ .to change{ parent.respond_to?(:sham!) }.from(false).to(true)
44
+ end
45
+
46
+ it 'defines sham_alternate! on the class' do
47
+ expect { Sham.config(parent) } \
48
+ .to change{ parent.respond_to?(:sham_alternate!) } \
49
+ .from(false).to(true)
50
+ end
51
+ end
52
+
53
+ context 'configured sham' do
54
+ it 'should be individual to every class' do
55
+ class A; end
56
+ class B; end
57
+
58
+ a = { :attribute => 'a' }
59
+ b = { :attribute => 'b' }
60
+
61
+ Sham.config(A){ |c| c.attributes{ a } }
62
+ Sham.config(B){ |c| c.attributes{ b } }
63
+
64
+ A.should_receive(:new).with(a)
65
+ B.should_receive(:new).with(b)
66
+
67
+ A.sham!
68
+ B.sham!
69
+ end
70
+
71
+ it 'carries over to subclasses' do
72
+ Sham.config(parent)
73
+ child.should respond_to(:sham!)
74
+ end
75
+
76
+ it 'allows subclasses to define their own' do
77
+ Sham.config(parent){ |c| c.empty }
78
+ Sham.config(child){ |c| c.empty }
79
+
80
+ parent.sham_config(:default) \
81
+ .should_not == child.sham_config(:default)
82
+ end
83
+
84
+ it 'defaults to calling #new when #create is not present' do
85
+ Sham.config(parent){ |c| c.empty }
86
+
87
+ parent.should_receive(:new).once
88
+
89
+ parent.sham!
90
+ end
91
+
92
+ it 'allows shams to be built instead of created' do
93
+ Sham.config(parent){ |c| c.empty }
94
+ parent.should_receive(:create).never
95
+ parent.should_receive(:new).once
96
+
97
+ parent.sham!(:build)
98
+ end
99
+
100
+ it 'creates shams by default' do
101
+ Sham.config(parent){ |c| c.empty }
102
+ parent.stub(:create)
103
+ parent.should_receive(:create).once
104
+
105
+ parent.sham!
106
+ end
107
+
108
+ context 'alternative shams' do
109
+ let(:other){ { :id => 1 } }
110
+
111
+ before do
112
+ Sham.config(parent){ |c| c.empty }
113
+ Sham.config(parent, :other){ |c| c.attributes{ other } }
114
+ end
115
+
116
+ it 'builds them' do
117
+ parent.should_receive(:new).with(other)
118
+
119
+ parent.sham!(:build, :other)
120
+ end
121
+
122
+ it 'creates them' do
123
+ parent.should_receive(:create).with(other)
124
+
125
+ parent.sham!(:other)
126
+ end
127
+ end
128
+
129
+ context 'nested shams' do
130
+ before do
131
+ parent.stub(:create)
132
+
133
+ Sham.config(parent) do |c|
134
+ c.attributes do
135
+ { :child => Sham::Nested.new(child) }
136
+ end
137
+ end
138
+ end
139
+
140
+ it 'calls them' do
141
+ child.should_receive(:sham!)
142
+
143
+ parent.sham!
144
+ end
145
+
146
+ it 'prefers passed options' do
147
+ other_child = stub
148
+ parent.should_receive(:create).with({ :child => other_child })
149
+ parent.sham!(:child => other_child)
150
+ end
151
+ end
152
+ end
153
+
154
+ it 'configures attribute shams' do
155
+ attributes = { :first => 'first', :last => 'last' }
156
+ Sham.config(parent) do |c|
157
+ c.attributes{ attributes }
158
+ end
159
+
160
+ parent.should_receive(:new).with(attributes)
161
+ parent.sham!
162
+ end
163
+
164
+ it 'configures empty shams' do
165
+ Sham.config(parent){ |c| c.empty }
166
+ parent.should_receive(:new).with({})
167
+ parent.sham!
168
+ end
169
+
170
+ it 'configures no arg shams' do
171
+ Sham.config(parent){ |c| c.no_args }
172
+ parent.should_receive(:new).with()
173
+ parent.sham!
174
+ end
175
+
176
+ it 'configures parameter shams' do
177
+ parameters = [:first, :second]
178
+ Sham.config(parent) do |c|
179
+ c.parameters{ parameters }
180
+ end
181
+
182
+ parent.should_receive(:new).with(*parameters)
183
+ parent.sham!
184
+ end
185
+ end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'sham/data'
2
2
 
3
3
  describe Sham do
4
4
  context '#string!' do
@@ -0,0 +1,11 @@
1
+ require 'sham/nested'
2
+
3
+ describe Sham::Nested do
4
+ it 'is a sham base' do
5
+ Sham::Nested.new(stub).is_a?(Sham::Base).should be_true
6
+ end
7
+
8
+ it 'makes a sham base a sham nested' do
9
+ Sham::Base.new(stub).is_a?(Sham::Nested).should be_true
10
+ end
11
+ end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require 'sham/util'
2
2
 
3
3
  describe Sham::Util do
4
4
  context '#extract_options!' do
@@ -30,6 +30,11 @@ describe Sham::Util do
30
30
  end
31
31
 
32
32
  context '#constantize' do
33
+ before do
34
+ Object.send(:remove_const, :User) if defined?(User)
35
+ class User; end
36
+ end
37
+
33
38
  it 'should raise a NameError when the constant is not valid' do
34
39
  expect {
35
40
  described_class.constantize('user')
@@ -1,11 +1,3 @@
1
- class Employee < User
2
- end
1
+ class Employee; end
3
2
 
4
- Sham.config(Employee) do |c|
5
- c.attributes do
6
- {
7
- :name => "Employee #{Sham.string!}",
8
- :email => "#{Sham.string!}@company.com"
9
- }
10
- end
11
- end
3
+ Sham.config(Employee){ |c| c.empty }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sham
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-03 00:00:00.000000000Z
12
+ date: 2012-03-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70137106338160 !ruby/object:Gem::Requirement
16
+ requirement: &70125021740440 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70137106338160
24
+ version_requirements: *70125021740440
25
25
  description: Lightweight flexible factories for Ruby and Rails testing.
26
26
  email:
27
27
  - pan.thomakos@gmail.com
@@ -33,6 +33,7 @@ extra_rdoc_files:
33
33
  files:
34
34
  - .document
35
35
  - .gitignore
36
+ - .travis.yml
36
37
  - Gemfile
37
38
  - License.txt
38
39
  - README.markdown
@@ -40,17 +41,27 @@ files:
40
41
  - lib/sham.rb
41
42
  - lib/sham/base.rb
42
43
  - lib/sham/config.rb
44
+ - lib/sham/config/attributes.rb
45
+ - lib/sham/config/base.rb
46
+ - lib/sham/config/empty.rb
47
+ - lib/sham/config/no_args.rb
48
+ - lib/sham/config/parameters.rb
43
49
  - lib/sham/data.rb
50
+ - lib/sham/nested.rb
44
51
  - lib/sham/shammable.rb
45
52
  - lib/sham/util.rb
46
53
  - lib/sham/version.rb
47
54
  - sham.gemspec
55
+ - spec/lib/sham/base_spec.rb
56
+ - spec/lib/sham/config/attributes_spec.rb
57
+ - spec/lib/sham/config/empty_spec.rb
58
+ - spec/lib/sham/config/no_args_spec.rb
59
+ - spec/lib/sham/config/parameters_spec.rb
60
+ - spec/lib/sham/config_spec.rb
61
+ - spec/lib/sham/data_spec.rb
62
+ - spec/lib/sham/nested_spec.rb
63
+ - spec/lib/sham/util_spec.rb
48
64
  - spec/root/sham/employee.rb
49
- - spec/sham/base_spec.rb
50
- - spec/sham/config_spec.rb
51
- - spec/sham/data_spec.rb
52
- - spec/sham/util_spec.rb
53
- - spec/spec_helper.rb
54
65
  homepage: http://github.com/panthomakos/sham
55
66
  licenses: []
56
67
  post_install_message:
@@ -72,14 +83,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
83
  version: '0'
73
84
  requirements: []
74
85
  rubyforge_project: sham
75
- rubygems_version: 1.8.6
86
+ rubygems_version: 1.8.16
76
87
  signing_key:
77
88
  specification_version: 3
78
- summary: sham-1.0.2
89
+ summary: sham-1.0.3
79
90
  test_files:
91
+ - spec/lib/sham/base_spec.rb
92
+ - spec/lib/sham/config/attributes_spec.rb
93
+ - spec/lib/sham/config/empty_spec.rb
94
+ - spec/lib/sham/config/no_args_spec.rb
95
+ - spec/lib/sham/config/parameters_spec.rb
96
+ - spec/lib/sham/config_spec.rb
97
+ - spec/lib/sham/data_spec.rb
98
+ - spec/lib/sham/nested_spec.rb
99
+ - spec/lib/sham/util_spec.rb
80
100
  - spec/root/sham/employee.rb
81
- - spec/sham/base_spec.rb
82
- - spec/sham/config_spec.rb
83
- - spec/sham/data_spec.rb
84
- - spec/sham/util_spec.rb
85
- - spec/spec_helper.rb
@@ -1,15 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Sham::Base do
4
- let(:base){ Sham::Base.new(User, :name => Sham.string!) }
5
-
6
- it 'should call sham! on the klass' do
7
- User.should_receive(:sham!)
8
- base.sham!
9
- end
10
-
11
- it 'should properly set the attributes' do
12
- user = base.sham!
13
- user[:name].should == base.options[:name]
14
- end
15
- end
@@ -1,119 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class Company < Object; end
4
-
5
- describe Sham::Config do
6
- it 'should activate shams in the root directory' do
7
- begin
8
- expect {
9
- described_class.activate!(SPEC_DIR)
10
- }.to change{ defined?(Employee) }.from(nil).to('constant')
11
- ensure
12
- Object.send(:remove_const, :Employee) rescue nil
13
- end
14
- end
15
-
16
- it 'should include Sham::Shammable when configured' do
17
- expect {
18
- Sham.config(Company){ |c| c.empty }
19
- }.to change{ Company.include?(Sham::Shammable) }.from(false).to(true)
20
- end
21
-
22
- it 'should only include Sham::Shammable once when configured' do
23
- Company.should_receive(:include).never
24
-
25
- Sham.config(Company, :alternate){ |c| c.empty }
26
- end
27
-
28
- it 'should define sham! on the class' do
29
- class BiggerCompany < Object; end
30
-
31
- expect {
32
- Sham.config(BiggerCompany){ |c| c.empty }
33
- }.to change{ BiggerCompany.respond_to?(:sham!) }.from(false).to(true)
34
- end
35
-
36
- it 'should define sham_alternate! on the class' do
37
- class BiggestCompany < Object; end
38
-
39
- expect {
40
- Sham.config(BiggestCompany){ |c| c.empty }
41
- }.to change{ BiggestCompany.respond_to?(:sham_alternate!) } \
42
- .from(false).to(true)
43
- end
44
-
45
- context 'shams' do
46
- it 'should carry shams over to subclasses' do
47
- class SuperUser < User; end
48
-
49
- SuperUser.should respond_to(:sham!)
50
- SuperUser.sham![:identifier].should == User.sham![:identifier]
51
- end
52
-
53
- it 'should allow subclasses to define their own shams' do
54
- class PowerUser < User; end
55
-
56
- Sham.config(PowerUser){ |c| c.empty }
57
-
58
- User.sham_config(:default) \
59
- .should_not == PowerUser.sham_config(:default)
60
- end
61
-
62
- it 'should default to calling #new when #create is not present' do
63
- class SimpleUser
64
- def initialize(options = {}); end
65
- end
66
-
67
- Sham.config(SimpleUser){ |c| c.empty }
68
-
69
- SimpleUser.should_receive(:new).once
70
-
71
- SimpleUser.sham!
72
- end
73
-
74
- it 'should allow shams to be built instead of created' do
75
- User.should_receive(:create).never
76
-
77
- User.sham!(:build)
78
- end
79
-
80
- it 'should create shams by default' do
81
- User.should_receive(:create).once
82
-
83
- User.sham!
84
- end
85
-
86
- it 'should allow alternate shams to be built' do
87
- User.should_receive(:create).never
88
-
89
- User.sham!(:build, :super)
90
- end
91
-
92
- it 'should allow alternate shams to be created' do
93
- User.should_receive(:create).once
94
-
95
- User.sham!(:super)
96
- end
97
-
98
- it 'should sham alternatives with alternative options' do
99
- User.sham!(:super)[:identifier] \
100
- .should_not == User.sham![:identifier]
101
- end
102
-
103
- it 'should perform nested shams' do
104
- Profile.should_receive(:sham!).once
105
-
106
- User.sham!(:with_profile)
107
- end
108
-
109
- it 'should allow nested shams to be overwritten' do
110
- profile = Profile.new
111
-
112
- User.sham!(:with_profile, :profile => profile)[:profile] \
113
- .should == profile
114
-
115
- User.sham!(:with_profile)[:profile] \
116
- .should_not == profile
117
- end
118
- end
119
- end
@@ -1,45 +0,0 @@
1
- require 'bundler'
2
- Bundler.require(:default)
3
-
4
- SPEC_DIR = File.join(File.dirname(File.expand_path(__FILE__)), 'root')
5
-
6
- class User
7
- attr_accessor :attributes
8
-
9
- def initialize attributes = {}
10
- self.attributes = attributes
11
- end
12
-
13
- def self.create attributes = {}
14
- new(attributes)
15
- end
16
-
17
- def [] attribute
18
- attributes[attribute]
19
- end
20
- end
21
-
22
- Sham.config(User) do |c|
23
- c.attributes do
24
- {
25
- :name => Sham.string!,
26
- :email => "#{Sham.string!}@gmail.com",
27
- :identifier => 100
28
- }
29
- end
30
- end
31
-
32
- Sham.config(User, :super) do |c|
33
- c.attributes do
34
- { :identifier => 200 }
35
- end
36
- end
37
-
38
- class Profile < User; end
39
-
40
- Sham.config(User, :with_profile) do |c|
41
- c.attributes do
42
- { :profile => Sham::Base.new(Profile) }
43
- end
44
- end
45
- Sham.config(Profile){ |c| c.empty }