sham 1.0.2 → 1.0.3

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.
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 }