Fetching contributors…
Cannot retrieve contributors at this time
225 lines (170 sloc) 9.3 KB
bug fix: correctly handle blank POST body (samsonw
updated specs for rails 3.1 compatibility (tomeric) (
when rails 3 went out of beta, the gem started install rails 3 activeresource/activemodel, because of a bug in the gemspec.
this release fixes the gemspec.
includes PUT and DELETE intercept mocks (checkout the README.rdoc)
includes POST intercept mocks (checkout the README.rdoc)
fixes issue #6 (
see commit (
fixes issue #5 (
see commit (
Created a hash pruning algorithm that overcomes ActiveSupport's to_xml limitations.
Basically, this allows you to have cyclicly referential records rendered into xml.
For example:
dupe_gem = Dupe.create :gem, :name => 'dupe'
matt = Dupe.create :author, :name => 'matt' = matt
matt.gems = [dupe_gem]
In Dupe's previous incarnations, if you had called "/authors/1.xml", you would have gotten a
"stack level too deep" error? Why? Because ActiveSupport's to_xml method for Hash objects
can't handle cyclical stuctures (in this case, dupe_gem has an author matt, who has a gem dupe_gem,
which has an author matt, who has a gem dupe_gem, etc. etc. etc. second star to the left straight
on till morning).
So I've written a HashPruner that performs a di-graph cycle detection / elimination operation
on any hash. dupe now adds a "to_xml_safe" method to hashes, which will essentially run the hash
in question through the pruner before passing itself off to ActiveSupport's "to_xml".
So now, "/authors/1.xml" will not error out on cyclical structure, but in fact return xml not unlike
ActiveRecord would have produced had these been actual relational database records.
Dupe.sequence works just like Factory Girl sequences. Check the README.rdoc on github.
Dupe.define now supports a uniquify method:
>> Dupe.define :book do |book|
?> book.uniquify :title, :genre, :author
>> end
=> #<Dupe::Model:0x1ab1a34 @id_sequence=#<Sequence:0x1ab19f8 @current_value=1>, @name=:book, @schema=#<Dupe::Model::Schema:0x1ab1a0c @after_create_callbacks=[#<Proc:0x01ac8338@./lib/dupe/schema.rb:40>, #<Proc:0x01ac8338@./lib/dupe/schema.rb:40>, #<Proc:0x01ac8338@./lib/dupe/schema.rb:40>], @attribute_templates={}>>
>> b = Dupe.create :book
=> <#Duped::Book author="book 1 author" title="book 1 title" genre="book 1 genre" id=1>
>> b2 = Dupe.create :book, :title => 'Rooby'
=> <#Duped::Book author="book 2 author" title="Rooby" genre="book 2 genre" id=2>
Dupe.define will now create resource mocks for find(:all) and find(<id>) honoring ActiveResource prefix's.
For example, before this patch:
class Author < ActiveResource::Base; = ''; end
Dupe.define :author
--> that would have generated network mocks with url_patterns like
%r{/authors\.xml$} and %r{/authors/(\d+)\.xml$}.
Now, with this patch, the previous two lines would generate mocks responding to:
--> %r{^/services/authors\.xml$} # find :all
--> %r{^/services/authors/(\d+)\.xml$} # find <id>
script/generate now does the following:
creates the following directories:
it places example Dupe definitions in RAILS_ROOT/features/dupe/definitions/definitions.rb
it places example custom mocks in RAILS_ROOT/features/dupe/custom_mocks/custom_mocks.rb
it also adds a load_dupe.rb file (that loads up the definitions and custom mocks) to RAILS_ROOT/features/support/load_dupe.rb
Bug fix: fixes issue #3 (
Bug fix: fixes issue #2 (
This is a major rewrite of Dupe. Under the hood, it's architecturally much more sound - and maintainable. It goes much
farther with tried and true OO design principles than previous incarnations. It also now includes a spec suite instead of
a cucumber suite (though a higher-level cucumber test suite is in the making), with code coverage above 95%.
New features include procs as default attributes, Dupe.find_or_create, and Dupe.define after_create callbacks, and
a new API for url-intercept mocks. Checkout README.rdoc for an overview.
* fixing cucumber After scenario hook (broke by last patch release)
* Dupe.create now returns hashes just like Dupe.find, allowing you to do this:
a = Dupe.create :author, :name => 'Andreas Eschbach'
b = Dupe.create :book, :title => 'The Carpet Makers', :author => a
* added support for intercept mocking. Instead of using the clunky Dupe.define_mocks for setting up
custom mocks, you can now use the CustomMocks module. Add a .rb file to your features/support/
that looks like this
module CustomMocks
# Maps a service request url to a Dupe find. By default, Dupe will only
# mock simple requests like SomeResource.find(some_id) or SomeResource.find(:all)
# For example, suppose you have a Book < ActiveResource::Base class, and
# somewhere your code does:
# Book.find :all, :params => {:limit => 10, :offset => 20}
# That in turn will send off a request to a url like:
# /books?limit=10&offset=20
# In this file, you could add a "when" statement like:
# when %r{^/books?limit=\d+&offset=\d+$}
# start = $2.to_i
# finish = start + $1.to_i
# Dupe.find(:books)[start..finish]
def custom_service(url)
case url
when %r{^/books?author_id=([^&]*)$}
Dupe.find(:books) {|b| == $1}
raise{There is no custom service mapping for "#{url}". Now go to features/support/custom_mocks.rb and add it.})
* removed spurious debug output (sorry)
* now supporting active resource prefixes.
For example, suppose you have an ActiveResource class like:
class Book < ActiveResource::Base = ""
Then Dupe will mock url responses prefixed with "/restful_services/", (e.g., if you
created a book record with Dupe like Dupe.create :book, :name => 'Bible', :author => 'God',
then Dupe would mock the response to "/restful_services/books.xml" with the appropriate xml)
* bug fix for hasmany associations
for example, suppose you had the following definition for a book resource that has many authors:
Dupe.define :book do |book|
book.authors do |author_names|
author_names.split(', ').map {|name| Dupe.find(:author) {|a| == name }}
you can now do a find like:
Dupe.find(:books) {|b| b.authors.collect {|a|}.include?('some author')}
before you would have had to do:
Dupe.find(:books) {|b| b.authors.collect {|a| a[:name]}.include?('some author')}
* rdoc documentation updates
* bumped the minor number because this release is not backwards compatible.
* stub now works more intuitively. Suppose you had a :book resource, and you wanted to stub
20 "sci-fi" books where both the title and author were different for every resource .
Dupe.stub 20, :books, :like => {:genre => "sci-fi", :title => proc {|n| "title-#{n}"}, :author => proc {|n| "author-#{n}"}}
* ruby 1.8.6 compat fix (Symbol doesn't support upcase)
* patched ActiveResource::Connection.get/delete/put/post/head to log appropriate request headers in the request log.
* configuration options now behave diffently if that option name is singular v. plural
for example,
Dupe.configuration :resource do |config|
config.record_identifiers :id
would result in the Dupe.factories[:resource].configuration.config[:record_identifiers] being set to [:id] (since
"record identifiers" is plural, it assumes you're specifying an array of values).
Dupe.configuration do |global_config|
global_config.debug true
sets Dupe.global_configuration.config[:debug] = true (it assumes that since "debug" is singular, that configuration can
only have one value, so it doesn't bother putting it in an array).
mostly, you'll never really need to know how Dupe.configuration is storing the configuration internally.
* new global configuration option "debug". will output all request attempts / mocked responses that occurred
during the course of a scenario. consult the api documentation ( for
more information.
* initial github publish. includes all the basic api: configure (factory), create, stub, define, define_mocks, find.