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 +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +2 -0
- data/README.markdown +92 -43
- data/Rakefile +6 -0
- data/lib/sham.rb +1 -0
- data/lib/sham/base.rb +3 -5
- data/lib/sham/config.rb +22 -10
- data/lib/sham/config/attributes.rb +26 -0
- data/lib/sham/config/base.rb +35 -0
- data/lib/sham/config/empty.rb +18 -0
- data/lib/sham/config/no_args.rb +18 -0
- data/lib/sham/config/parameters.rb +27 -0
- data/lib/sham/nested.rb +5 -0
- data/lib/sham/shammable.rb +26 -51
- data/lib/sham/version.rb +1 -1
- data/spec/lib/sham/base_spec.rb +16 -0
- data/spec/lib/sham/config/attributes_spec.rb +44 -0
- data/spec/lib/sham/config/empty_spec.rb +26 -0
- data/spec/lib/sham/config/no_args_spec.rb +26 -0
- data/spec/lib/sham/config/parameters_spec.rb +43 -0
- data/spec/lib/sham/config_spec.rb +185 -0
- data/spec/{sham → lib/sham}/data_spec.rb +1 -1
- data/spec/lib/sham/nested_spec.rb +11 -0
- data/spec/{sham → lib/sham}/util_spec.rb +6 -1
- data/spec/root/sham/employee.rb +2 -10
- metadata +31 -16
- data/spec/sham/base_spec.rb +0 -15
- data/spec/sham/config_spec.rb +0 -119
- data/spec/spec_helper.rb +0 -45
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -8,66 +8,66 @@ Lightweight flexible factories for Ruby and Rails testing.
|
|
8
8
|
|
9
9
|
## Getting Started
|
10
10
|
|
11
|
-
Create a
|
11
|
+
Create a configuration file for any of your models or classes.
|
12
12
|
|
13
|
-
#
|
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
|
21
|
-
|
22
|
-
load
|
23
|
-
your
|
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
|
30
|
-
path
|
31
|
-
|
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
|
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
|
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
|
-
|
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
|
-
|
56
|
-
Sham and RSpec.
|
56
|
+
The following is an example of an RSpec test for `ActiveRecord` validations.
|
57
57
|
|
58
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
##
|
86
|
+
## Parameter/Argument Shams
|
87
87
|
|
88
|
-
You can
|
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
|
-
#
|
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
|
-
|
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
|
-
|
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
|
-
#
|
113
|
-
Sham.config(User)
|
114
|
-
c.empty
|
115
|
-
end
|
148
|
+
# sham/user.rb
|
149
|
+
Sham.config(User){ |c| c.empty }
|
116
150
|
|
117
|
-
|
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
|
162
|
+
## Nested Shams
|
122
163
|
|
123
|
-
|
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
|
-
#
|
169
|
+
# sham/line_item_sham.rb
|
126
170
|
Sham.config(LineItem) do |c|
|
127
171
|
c.attributes do
|
128
|
-
{ :item => Sham::
|
172
|
+
{ :item => Sham::Nested.new(Item) }
|
129
173
|
end
|
130
174
|
end
|
131
175
|
|
132
|
-
The nested shams will automatically be
|
133
|
-
|
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
|
-
##
|
183
|
+
## Sham Inheritance
|
140
184
|
|
141
|
-
Sham plays well with
|
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
|
162
|
-
line to this block after you have re-loaded your models
|
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
data/lib/sham.rb
CHANGED
data/lib/sham/base.rb
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
module Sham
|
2
2
|
class Base
|
3
|
-
|
4
|
-
|
5
|
-
def initialize klass, options = {}
|
3
|
+
def initialize klass, *args
|
6
4
|
@klass = klass
|
7
|
-
@
|
5
|
+
@args = args
|
8
6
|
end
|
9
7
|
|
10
8
|
def sham!
|
11
|
-
@klass.sham!(
|
9
|
+
@klass.sham!(*@args)
|
12
10
|
end
|
13
11
|
end
|
14
12
|
end
|
data/lib/sham/config.rb
CHANGED
@@ -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.
|
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
|
-
|
22
|
-
|
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
|
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,
|
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,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
|
data/lib/sham/nested.rb
ADDED
data/lib/sham/shammable.rb
CHANGED
@@ -1,63 +1,38 @@
|
|
1
|
+
require 'sham/util'
|
2
|
+
|
1
3
|
module Sham
|
2
|
-
|
3
|
-
def
|
4
|
-
|
5
|
-
|
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
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
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
|
-
|
34
|
+
def extract_type!(args)
|
35
|
+
args.shift if sham_config(args.first)
|
61
36
|
end
|
62
37
|
end
|
63
38
|
end
|
data/lib/sham/version.rb
CHANGED
@@ -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 '
|
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')
|
data/spec/root/sham/employee.rb
CHANGED
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.
|
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:
|
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: &
|
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: *
|
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.
|
86
|
+
rubygems_version: 1.8.16
|
76
87
|
signing_key:
|
77
88
|
specification_version: 3
|
78
|
-
summary: sham-1.0.
|
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
|
data/spec/sham/base_spec.rb
DELETED
@@ -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
|
data/spec/sham/config_spec.rb
DELETED
@@ -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
|
data/spec/spec_helper.rb
DELETED
@@ -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 }
|