README.markdown in sham-1.0.2 vs README.markdown in sham-1.0.3
- old
+ new
@@ -6,70 +6,70 @@
gem install sham
## Getting Started
-Create a sham file for each of your models:
+Create a configuration file for any of your models or classes.
- # in sham/user.rb
+ # sham/user.rb
Sham.config(User) do |c|
c.attributes do
{ :name => "Sample User" }
end
end
-To load your shams you can either include the files individually, or define
-your shams directly in your test file. Sham also provides a helper function to
-load shams under the sham directory. To load all your shams add the following to
-your application.rb or test.rb file:
+To load a shams you can either include the configuration file directly, or
+define the sham inline in a test file. Sham provides a helper function to
+load all files under the sham directory. If you are using Rails you can load
+all your shams by adding the following to `config/environments/test.rb`.
config.after_initialize do
Sham::Config.activate!
end
-If you are not using Rails you can activate all of your shams by specifying a
-path under which your shams are defined. For instance, this command will load
-all Ruby files under the `/my/project/path/sham` directory and and all
-subdirectories.
+If you aren't using Rails you can activate all of your shams by specifying a
+configuration path. The following command will load all Ruby files under the
+`/my/project/path/sham` directory.
Sham::Config.activate!('/my/project/path')
-To enable all Shams in cucumber, add the following to your
-features/support/env.rb file:
+To load all your shams in Cucumber, modify your `features/support/env.rb` file.
require 'sham'
Sham::Config.activate!
-You can now "sham" your models and pass additional attributes at creation:
+You can now "sham" your models! When you sham a model it is created with the
+default options you specified in the config file. But you can also overwrite
+any number of them and add additional attributes on a case-by-case basis.
User.sham!
User.sham!(:name => "New Name")
User.sham!(:age => 23)
-You can use sham to build models without automatically saving them as well:
+Sham can also create objects without automatically saving using the `:build`
+option.
user = User.sham!(:build, :name => "I have not been saved")
user.save
## RSpec Example
-Here is an example of testing validations on an ActiveRecord::Base class using
-Sham and RSpec.
+The following is an example of an RSpec test for `ActiveRecord` validations.
- # in app/models/item.rb
+ # app/models/item.rb
class Item < ActiveRecord::Base
validates_numericality_of :quantity, :greater_than => 0
end
- # in sham/item.rb
+ # sham/item.rb
Sham.config(Item) do |c|
c.attributes do
{ :quantity => 1 }
end
end
- # in spec/models/item_spec.rb
+ # spec/models/item_spec.rb
require 'spec_helper'
require './sham/item'
describe Item do
it "should not allow items with a negative price" do
@@ -81,15 +81,49 @@
item = Item.sham!(:build, :quantity => 10)
item.valid?.should be_true
end
end
-## Alternative Shams
+## Parameter/Argument Shams
-You can easily define alternative sham configurations:
+You can also define shams for initializers that take a list of arguments
+instead of an attribute hash. For example, if you had a `User` class.
- # in sham/item.rb
+ # lib/user.rb
+ class User
+ attr_accessor :first, :last
+
+ def initialize(first, last)
+ self.first = first
+ self.last = last
+ end
+ end
+
+You could create a parameter sham like this:
+
+ # sham/user.rb
+ Sham.config(User) do |c|
+ c.parameters do
+ ['John', 'Doe']
+ end
+ end
+
+And invoke it like this:
+
+ User.sham!
+ User.sham!('Jane', 'Doe')
+
+Unlike attribute shams, if arguments are passed to a parameter sham, those
+arguments are the only ones passed to the constructor and the parameters are
+not merged with the defaults.
+
+## Multiple Sham Configurations
+
+Sometimes you want to be able to configure more than one sham per class. Sham
+makes it easy to define alternative configurations by specifying a config name.
+
+ # sham/item.rb
Sham.config(Item, :small) do |c|
c.attributes do
{ :weight => 10.0 }
end
end
@@ -98,74 +132,89 @@
c.attributes do
{ :weight => 100.0 }
end
end
-These can be invoked using:
+Alternative sham configurations can be invoked by passing their name into the
+`sham!` command.
Item.sham!(:small, :quantity => 100)
Item.sham!(:large, :build, :quantity => 0)
## Empty Shams
-You can easily define empty shams using the empty function:
+Sometimes you simply want to be able to sham an object without passing any
+default options. Sham makes this easy by providing an `empty` configuration.
- # in sham/user.rb
- Sham.config(User) do |c|
- c.empty
- end
+ # sham/user.rb
+ Sham.config(User){ |c| c.empty }
-This can be invoked using:
+Empty configurations behave just like empty hashes. That means you can simply
+pass your own attributes in when shamming the class.
User.sham!
+ User.sham!(:name => 'John Doe')
-## Nested Shamming
+For parameter based shams you can create empty configurations using the
+`no_args` option.
-You can nest shammed models inside others:
+ Sham.config(User){ |c| c.no_args }
- # in sham/line_item_sham.rb
+## Nested Shams
+
+Sometimes you want one sham to be responsible for creating additional shams when
+it is initialized. For instance, a `LineItem` might require an `Item` to be
+considered a valid object. Sham makes this kind of nested sham very easy to
+configure, and allows you to overwrite the 'sub-object' during initialization.
+
+ # sham/line_item_sham.rb
Sham.config(LineItem) do |c|
c.attributes do
- { :item => Sham::Base.new(Item) }
+ { :item => Sham::Nested.new(Item) }
end
end
-The nested shams will automatically be invoked and can be overridden during a
-sham call:
+The nested shams will automatically be created and can also be overwritten
+during initialization:
LineItem.sham!
LineItem.sham!(:item => Item.sham!(:weight => 100))
-## Subclass Shams
+## Sham Inheritance
-Sham plays well with subclassing. That means shams defined on parent classes
-will be available to child classes as well:
+Sham plays well with inheritance. That means shams defined on parent classes
+will be available to child classes as well.
Sham.config(Person) do |c|
c.empty
end
class Person; end
class Employee < Person; end
Employee.sham!
+You can also define different shams for your subclasses instead of relying on
+the parent object.
+
## Reloading Shams with Spork
[Spork](https://rubygems.org/gems/spork) is a great gem that creates a
Distributed Ruby environment that you can run your RSpec and Cucumber tests
against. If you are using Rails it is often necessary to re-load your models and
controllers between Spork test runs so that the Spork DRB picks up your latest
model changes. This is usually accomplished using a Spork 'each run' block. This
block of code gets executed before each test run. If you want to be able to
-reload your shams with Spork all you need to do is add a Sham::Config.activate!
-line to this block after you have re-loaded your models and controllers.
+reload your shams with Spork all you need to do is add a
+`Sham::Config.activate!` line to this block after you have re-loaded your models
+and controllers.
Spork.each_run do
- ActiveSupport::Dependencies.clear
- ActiveRecord::Base.instantiate_observers
Sham::Config.activate!
end if Spork.using_spork?
This change will cause sham to be re-loaded so that you can continue to use it
-with Spork.
+with Spork. If you take this approach it's important to remove the call to
+`Sham::Config.activate!` from your `test.rb` file.
+
+## Build Status [![Build Status](https://secure.travis-ci.org/panthomakos/sham.png)](http://travis-ci.org/panthomakos/sham)