dupe 0.4.5 → 0.4.6

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/README.rdoc CHANGED
@@ -4,11 +4,10 @@ There are lots of great tools out there to ease the burden of prototyping Active
4
4
 
5
5
  But what about prototyping ActiveResource records? That's where Dupe steps in.
6
6
 
7
-
8
7
  == Motivation
9
8
 
10
- Dupe is ideally suited for cuking the client side of a service-oriented (ActiveResource) application.
11
-
9
+ If you're going to create a service-oriented rails app with ActiveResource, why not cuke the front end first?
10
+ Let the behavior of the front-end drive the services you build on the backend. That's exactly what Dupe makes possible.
12
11
 
13
12
  == Installation
14
13
 
@@ -18,7 +17,7 @@ If you want to install this for use in something other than a rails project, sim
18
17
 
19
18
  If you're going to use this in a rails project, add this to your cucumber.rb environment (config/environments/cucumber.rb)
20
19
 
21
- config.gem 'dupe', :lib => 'dupe', :version => '>=0.4.0'
20
+ config.gem 'dupe'
22
21
 
23
22
  Then run this rake task to install the gem:
24
23
 
@@ -124,17 +123,15 @@ Notice that by using the plural form of the model name, we ensure that we receiv
124
123
 
125
124
  ==Finding or Creating Resources
126
125
 
127
- You might have seen this one coming:
126
+ You might have seen this one coming.
127
+
128
+ Let's assume no genres currently exist. If we call the "find_or_create" method, it will create a new :genre.
128
129
 
129
- irb# Dupe.find :genre
130
- Dupe::Database::TableDoesNotExistError: The table ':genre' does not exist.
131
- from /Library/Ruby/Gems/1.8/gems/dupe-0.4.0/lib/dupe/database.rb:30:in `select'
132
- from /Library/Ruby/Gems/1.8/gems/dupe-0.4.0/lib/dupe/dupe.rb:295:in `find'
133
- from (irb):40
134
-
135
130
  irb# Dupe.find_or_create :genre
136
131
  ==> <#Duped::Genre id=1>
137
132
 
133
+ If we call it again, it will find the :genre we already created:
134
+
138
135
  irb# Dupe.find_or_create :genre
139
136
  ==> <#Duped::Genre id=1>
140
137
 
@@ -263,7 +260,7 @@ Now, let's create a book:
263
260
 
264
261
  === Uniquify attributes
265
262
 
266
- If you'd just like to make sure that some attributes get a unique value (probably), then you can use the uniquify
263
+ If you'd just like to make sure that some attributes get a unique value, then you can use the uniquify
267
264
  method:
268
265
 
269
266
  irb# Dupe.define :book do |attrs|
@@ -280,6 +277,29 @@ any records it creates:
280
277
  ==> <#Duped::Book author="book 2 author" title="Rooby" genre="book 2 genre" id=2>
281
278
 
282
279
 
280
+ === Sequences
281
+
282
+ The "uniquify" method is great if don't care too much about the format of the values it creates. But what if you'd like to ensure
283
+ that the value of an attribute conforms to a specific format?
284
+
285
+ irb# Dupe.sequence :email do |n|
286
+ --# "email-#{n}@somewhere.com"
287
+ --# end
288
+
289
+ irb# Dupe.define :user do |user|
290
+ --# user.uniquify :name
291
+ --# user.email do
292
+ --# Dupe.next :email
293
+ --# end
294
+ --# end
295
+
296
+ irb# Dupe.create :user
297
+ ==> <#Duped::User name="user 1 name" id=1 email="email-1@somewhere.com">
298
+
299
+ irb# Dupe.create :user
300
+ ==> <#Duped::User name="user 2 name" id=2 email="email-2@somewhere.com">
301
+
302
+
283
303
  === Callbacks
284
304
 
285
305
  Suppose we'd like to make sure that our books get a unique label. We can accomplish that with an after_create callback:
@@ -302,6 +322,9 @@ Suppose we'd like to make sure that our books get a unique label. We can accompl
302
322
  ==> <#Duped::Book author=nil label="rooby-on-rails--1" title="Rooby on Rails" publish_date=nil id=1 isbn=842518>
303
323
 
304
324
 
325
+
326
+
327
+
305
328
  = ActiveResource
306
329
 
307
330
  So how does Dupe actually help us to spec/test ActiveResource-based applications? It uses a simple, yet sophisticated "intercept-mocking" technique, whereby failed network requests sent by ActiveResource fallback to the "Duped" network. Consider the following:
data/lib/dupe/dupe.rb CHANGED
@@ -5,6 +5,7 @@ class Dupe
5
5
  class << self
6
6
 
7
7
  attr_reader :models #:nodoc:
8
+ attr_reader :sequences #:nodoc:
8
9
  attr_reader :database #:nodoc:
9
10
 
10
11
  # set this to "true" if you Dupe to spit out mocked requests
@@ -385,6 +386,15 @@ class Dupe
385
386
  results
386
387
  end
387
388
  end
389
+
390
+ def sequence(name, &block)
391
+ sequences[name.to_sym] = Sequence.new 1, block
392
+ end
393
+
394
+ def next(name)
395
+ raise ArgumentError, "Unknown sequence \":#{name}\"" unless sequences.has_key?(name)
396
+ sequences[name].next
397
+ end
388
398
 
389
399
  def models #:nodoc:
390
400
  @models ||= {}
@@ -397,14 +407,23 @@ class Dupe
397
407
  def database #:nodoc:
398
408
  @database ||= Dupe::Database.new
399
409
  end
410
+
411
+ def sequences #:nodoc:
412
+ @sequences ||= {}
413
+ end
400
414
 
401
- # clears out all model definitions and database records / tables.
415
+ # clears out all model definitions, sequences, and database records / tables.
402
416
  def reset
403
417
  reset_models
404
418
  reset_database
405
419
  reset_network
420
+ reset_sequences
406
421
  end
407
422
 
423
+ def reset_sequences
424
+ @sequences = {}
425
+ end
426
+
408
427
  def reset_models
409
428
  @models = {}
410
429
  end
data/lib/dupe/sequence.rb CHANGED
@@ -1,12 +1,20 @@
1
1
  class Sequence #:nodoc:
2
2
  attr_reader :current_value
3
3
 
4
- def initialize(starting_at=1)
4
+ def initialize(starting_at=1, sequencer=nil)
5
5
  @current_value = starting_at
6
+ if sequencer && sequencer.arity != 1
7
+ raise ArgumentError, "Your block must accept a single parameter"
8
+ end
9
+ @transformer = sequencer
6
10
  end
7
11
 
8
12
  def next
9
13
  @current_value += 1
10
- @current_value - 1
14
+ if @transformer
15
+ @transformer.call(@current_value - 1)
16
+ else
17
+ @current_value - 1
18
+ end
11
19
  end
12
- end
20
+ end
@@ -5,14 +5,67 @@ describe Dupe do
5
5
  Dupe.reset
6
6
  end
7
7
 
8
+ describe "#sequences" do
9
+ it "should be empty on initialization" do
10
+ Dupe.sequences.should == {}
11
+ end
12
+ end
13
+
14
+ describe "#sequence" do
15
+ it "should require a sequence name and a block" do
16
+ proc {Dupe.sequence}.should raise_error(ArgumentError)
17
+ proc {Dupe.sequence :name}.should_not raise_error
18
+ proc {Dupe.sequence(:name) {}}.should raise_error(ArgumentError, "Your block must accept a single parameter")
19
+ proc {Dupe.sequence(:name) {|n| n}}.should_not raise_error
20
+ end
21
+
22
+ it "should store the sequence in a sequences hash" do
23
+ Dupe.sequences.should be_empty
24
+
25
+ Dupe.sequence :email do |n|
26
+ "email-#{n}@address.com"
27
+ end
28
+
29
+ Dupe.sequences.should_not be_empty
30
+ Dupe.sequences.keys.include?(:email).should == true
31
+ Dupe.sequences[:email].should be_kind_of(Sequence)
32
+ end
33
+ end
34
+
35
+ describe "#next" do
36
+ it "should require a sequence name" do
37
+ Dupe.sequence :email do |n|
38
+ "email-#{n}@address.com"
39
+ end
40
+
41
+ proc {Dupe.next}.should raise_error(ArgumentError)
42
+ proc {Dupe.next :title}.should raise_error(ArgumentError, 'Unknown sequence ":title"')
43
+ Dupe.next(:email).should == "email-1@address.com"
44
+ Dupe.next(:email).should == "email-2@address.com"
45
+ end
46
+ end
47
+
8
48
  describe "reset" do
9
49
  it "should call reset_models, reset_database, and reset_network" do
10
50
  Dupe.should_receive(:reset_models).once
11
51
  Dupe.should_receive(:reset_database).once
12
52
  Dupe.should_receive(:reset_network).once
53
+ Dupe.should_receive(:reset_sequences).once
13
54
  Dupe.reset
14
55
  end
15
56
  end
57
+
58
+ describe "reset_sequences" do
59
+ it "should reset the sequences to an empty hash" do
60
+ Dupe.sequences.should == {}
61
+ Dupe.sequence :email do |n|
62
+ n
63
+ end
64
+ Dupe.sequences.should_not be_empty
65
+ Dupe.reset_sequences
66
+ Dupe.sequences.should == {}
67
+ end
68
+ end
16
69
 
17
70
  describe "reset_models" do
18
71
  it "should reset @models to an empty hash" do
@@ -6,6 +6,14 @@ describe Sequence do
6
6
  Sequence.new.current_value.should == 1
7
7
  Sequence.new(500).current_value.should == 500
8
8
  end
9
+
10
+ it "should accept a block that takes a single parameter" do
11
+ proc {Sequence.new 1, proc {}}.should raise_error(ArgumentError, "Your block must accept a single parameter")
12
+ proc {Sequence.new 1, proc {|n| n}}.should_not raise_error
13
+ proc {Sequence.new 1, proc {|n,m| n}}.should raise_error(ArgumentError, "Your block must accept a single parameter")
14
+ s = Sequence.new 1, proc {|n| "email-#{n}@address.com"}
15
+ s.current_value.should == 1
16
+ end
9
17
  end
10
18
 
11
19
  describe "next" do
@@ -21,6 +29,11 @@ describe Sequence do
21
29
  s.current_value.should == 501
22
30
  s.next.should == 501
23
31
  s.current_value.should == 502
32
+
33
+ s = Sequence.new 1, proc {|n| "email-#{n}@address.com"}
34
+ s.next.should == "email-1@address.com"
35
+ s.next.should == "email-2@address.com"
36
+ s.current_value.should == 3
24
37
  end
25
38
  end
26
- end
39
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dupe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Parker
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-25 00:00:00 -05:00
12
+ date: 2010-01-31 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency