dupe 0.5.0 → 0.5.1
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 +123 -2
- data/lib/dupe/active_resource_extensions.rb +43 -0
- data/lib/dupe/custom_mocks.rb +9 -1
- data/lib/dupe/database.rb +18 -1
- data/lib/dupe/dupe.rb +16 -2
- data/lib/dupe/mock.rb +67 -29
- data/lib/dupe/network.rb +12 -4
- data/spec/lib_specs/active_resource_extensions_spec.rb +77 -1
- data/spec/lib_specs/database_spec.rb +30 -0
- data/spec/lib_specs/dupe_spec.rb +62 -4
- data/spec/lib_specs/mock_spec.rb +73 -24
- data/spec/lib_specs/network_spec.rb +27 -6
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -38,6 +38,11 @@ It will also place example Dupe definitions in RAILS_ROOT/features/dupe/definiti
|
|
38
38
|
Lastly, it will add a load_dupe.rb file (that loads up the definitions and custom mocks) to RAILS_ROOT/features/support/load_dupe.rb
|
39
39
|
|
40
40
|
|
41
|
+
= Tutorial
|
42
|
+
|
43
|
+
Checkout the {dupe example application}[http://github.com/moonmaster9000/dupe_example_app] for a tutorial on cuking an application with
|
44
|
+
ActiveResource and Dupe.
|
45
|
+
|
41
46
|
= Features
|
42
47
|
|
43
48
|
==Creating resources
|
@@ -508,7 +513,7 @@ Now, when you try to create an Author without a name, it will respond with the a
|
|
508
513
|
irb# a = a.new?
|
509
514
|
==> true
|
510
515
|
|
511
|
-
Because the resource
|
516
|
+
Because our custom Post mock determined that the resource was invalid, Dupe did not mock the resource:
|
512
517
|
|
513
518
|
irb# Dupe.find(:authors)
|
514
519
|
==> []
|
@@ -524,11 +529,127 @@ When we create the Author with the required attributes, it will now be considere
|
|
524
529
|
irb# a.new?
|
525
530
|
==> false
|
526
531
|
|
527
|
-
|
532
|
+
Since our custom Post mock considered the resource valid, it went ahead and created the resource:
|
528
533
|
|
529
534
|
irb# Dupe.find(:authors)
|
530
535
|
==> [<#Duped::Author name="CS Lewis" id=1>]
|
531
536
|
|
537
|
+
|
538
|
+
===PUT requests
|
539
|
+
|
540
|
+
In ActiveResource, when you update a resource that already exists via the "save" method, it translates to a PUT request.
|
541
|
+
Dupe provides basic PUT intercept mocks out of the box, and like GET and POST mocks,
|
542
|
+
it allows you to override the default PUT intercept mock, and create new ones.
|
543
|
+
|
544
|
+
Let's again examine an "author" resource:
|
545
|
+
|
546
|
+
irb# Dupe.define :author
|
547
|
+
|
548
|
+
irb# class Author < ActiveResource::Base; self.site = ''; end
|
549
|
+
==> ""
|
550
|
+
|
551
|
+
irb# Author.create :name => "CS Lewis" # --> Dupe intercepts this POST request
|
552
|
+
==> #<Author:0x1a4ca58 @attributes={"name"=>"CS Lewis", "id"=>1}, @prefix_options={}>
|
553
|
+
|
554
|
+
irb# Dupe.find :authors
|
555
|
+
==> [<#Duped::Author name="CS Lewis" id=1>]
|
556
|
+
|
557
|
+
irb# a = Author.find 1 # --> Dupe intercepts this GET request
|
558
|
+
==> #<Author:0x1a4ca58 @attributes={"name"=>"CS Lewis", "id"=>1}, @prefix_options={}>
|
559
|
+
|
560
|
+
So far, we've created a resource (via dupe's POST intercept mocking), and we've also found the resource we create (via dupe's GET
|
561
|
+
intercept mocking). Now, let's attempt to update (PUT) the resource:
|
562
|
+
|
563
|
+
irb# a.name = "Frank Herbert"
|
564
|
+
|
565
|
+
irb# a.save # --> Dupe intercepts this PUT request
|
566
|
+
==> true
|
567
|
+
|
568
|
+
Dupe intercepted the PUT request that ActiveResource attempted to send, and updated the Duped resource accordingly:
|
569
|
+
|
570
|
+
irb# a
|
571
|
+
==> #<Author:0x1a4ca58 @attributes={"name"=>"Frank Herbert", "id"=>1}, @prefix_options={}>
|
572
|
+
|
573
|
+
irb# Dupe.find :authors
|
574
|
+
==> [<#Duped::Author name="Frank Herbert" id=1>]
|
575
|
+
|
576
|
+
You can also overwrite the default PUT intercept mock for your resource by using the "Put" method:
|
577
|
+
|
578
|
+
irb# Put %r{/authors/(\d+)\.xml} do |id, put_data|
|
579
|
+
raise Dupe::UnprocessableEntity.new(:name => " must be present.") unless put_data[:name]
|
580
|
+
Dupe.find(:author) {|a| a.id == id.to_i}.merge! put_data
|
581
|
+
end
|
582
|
+
==> #<Dupe::Network::PostMock:0x1a1afe4 @url_pattern=/\/authors\.xml/, @response=#<Proc:0x01a1b084@(irb):13>, @verb=:post>
|
583
|
+
|
584
|
+
Now, if we try to update our Author without a name, it will respond with the appropriate errors.
|
585
|
+
|
586
|
+
irb# Dupe.find :authors
|
587
|
+
==> [<#Duped::Author name="Frank Herbert" id=1>]
|
588
|
+
|
589
|
+
irb# a = Author.find 1 # --> Dupe intercepts this GET request
|
590
|
+
==> #<Author:0x1a4ca58 @attributes={"name"=>"Frank Herbert", "id"=>1}, @prefix_options={}>
|
591
|
+
|
592
|
+
irb# a.name = nil
|
593
|
+
|
594
|
+
irb# a.save
|
595
|
+
==> false
|
596
|
+
|
597
|
+
irb# a.errors.on_base
|
598
|
+
==> ["name must be present"]
|
599
|
+
|
600
|
+
Since our Put intercept mock raise the Dupe::UnprocessableEntity exception,
|
601
|
+
the underlying Duped record remains unchanged, just as we would expect the real service to have operated:
|
602
|
+
|
603
|
+
irb# Dupe.find :authors
|
604
|
+
==> [<#Duped::Author name="Frank Herbert" id=1>]
|
605
|
+
|
606
|
+
We can, of course, at this point still update the name to a non-nil value and attempt to save it again:
|
607
|
+
|
608
|
+
irb# a.name = "Matt Parker"
|
609
|
+
|
610
|
+
irb# a.save
|
611
|
+
==> true
|
612
|
+
|
613
|
+
irb# Dupe.find :authors
|
614
|
+
==> [<#Duped::Author name="Matt Parker" id=1>]
|
615
|
+
|
616
|
+
===DELETE requests
|
617
|
+
|
618
|
+
As you might have guessed, Dupe also supports DELETE intercept mocking (ActiveResource::Base#destroy):
|
619
|
+
|
620
|
+
irb# Dupe.define :author
|
621
|
+
|
622
|
+
irb# class Author < ActiveResource::Base; self.site = ''; end
|
623
|
+
==> ""
|
624
|
+
|
625
|
+
irb# Author.create :name => "CS Lewis" # --> Dupe intercepts this POST request
|
626
|
+
==> #<Author:0x1a4ca58 @attributes={"name"=>"CS Lewis", "id"=>1}, @prefix_options={}>
|
627
|
+
|
628
|
+
irb# Dupe.find :authors
|
629
|
+
==> [<#Duped::Author name="CS Lewis" id=1>]
|
630
|
+
|
631
|
+
irb# a = Author.find 1 # --> Dupe intercepts this GET request
|
632
|
+
==> #<Author:0x1a4ca58 @attributes={"name"=>"CS Lewis", "id"=>1}, @prefix_options={}>
|
633
|
+
|
634
|
+
irb# a.destroy
|
635
|
+
==> #<ActiveResource::Response:0x181c1c0 @body="", @message="200", @code=200, @headers={"Content-Length"=>"0"}
|
636
|
+
|
637
|
+
irb# Dupe.find :authors
|
638
|
+
==> []
|
639
|
+
|
640
|
+
And also, as you might have guessed, you can override the default DELETE intercept mock for a resource:
|
641
|
+
|
642
|
+
irb# Delete %r{/books/(\d+)\.xml} do |id|
|
643
|
+
puts "deleting the book with id #{id}"
|
644
|
+
Dupe.delete(:book) {|b| b.id == id.to_i}
|
645
|
+
end
|
646
|
+
|
647
|
+
irb# a = Author.create :name => "some author"
|
648
|
+
|
649
|
+
irb# a.destroy
|
650
|
+
==> "deleting the book with id 1"
|
651
|
+
|
652
|
+
|
532
653
|
== More
|
533
654
|
|
534
655
|
Consult the API documentation at http://moonmaster9000.github.com/dupe/api/
|
@@ -50,5 +50,48 @@ module ActiveResource #:nodoc:
|
|
50
50
|
end
|
51
51
|
response
|
52
52
|
end
|
53
|
+
|
54
|
+
def put(path, body = '', headers = {}) #:nodoc:
|
55
|
+
begin
|
56
|
+
response = request(:put, path, body.to_s, build_request_headers(headers, :put))
|
57
|
+
|
58
|
+
# if the request threw an exception
|
59
|
+
rescue
|
60
|
+
resource_hash = Hash.from_xml(body)
|
61
|
+
resource_hash = resource_hash[resource_hash.keys.first]
|
62
|
+
resource_hash = {} unless resource_hash.kind_of?(Hash)
|
63
|
+
resource_hash.symbolize_keys!
|
64
|
+
|
65
|
+
begin
|
66
|
+
error = false
|
67
|
+
mocked_response, path = Dupe.network.request(:put, path, resource_hash)
|
68
|
+
rescue Dupe::UnprocessableEntity => e
|
69
|
+
mocked_response = {:error => e.message.to_s}.to_xml(:root => 'errors')
|
70
|
+
error = true
|
71
|
+
end
|
72
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
73
|
+
if error
|
74
|
+
mock.put(path, {}, mocked_response, 422, "Content-Type" => 'application/xml')
|
75
|
+
else
|
76
|
+
mock.put(path, {}, mocked_response, 204)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
response = request(:put, path, body.to_s, build_request_headers(headers, :put))
|
80
|
+
ActiveResource::HttpMock.delete_mock(:put, path)
|
81
|
+
end
|
82
|
+
response
|
83
|
+
end
|
84
|
+
|
85
|
+
def delete(path, headers = {})
|
86
|
+
Dupe.network.request(:delete, path)
|
87
|
+
|
88
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
89
|
+
mock.delete(path, {}, nil, 200)
|
90
|
+
end
|
91
|
+
response = request(:delete, path, build_request_headers(headers, :delete))
|
92
|
+
|
93
|
+
ActiveResource::HttpMock.delete_mock(:delete, path)
|
94
|
+
response
|
95
|
+
end
|
53
96
|
end
|
54
97
|
end
|
data/lib/dupe/custom_mocks.rb
CHANGED
@@ -105,4 +105,12 @@ end
|
|
105
105
|
|
106
106
|
def Post(url_pattern, &block)
|
107
107
|
Dupe.network.define_service_mock :post, url_pattern, block
|
108
|
-
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def Put(url_pattern, &block)
|
111
|
+
Dupe.network.define_service_mock :put, url_pattern, block
|
112
|
+
end
|
113
|
+
|
114
|
+
def Delete(url_pattern, &block)
|
115
|
+
Dupe.network.define_service_mock :delete, url_pattern, block
|
116
|
+
end
|
data/lib/dupe/database.rb
CHANGED
@@ -12,6 +12,23 @@ class Dupe
|
|
12
12
|
def initialize
|
13
13
|
@tables = {}
|
14
14
|
end
|
15
|
+
|
16
|
+
# database.delete :books # --> would delete all books
|
17
|
+
# database.delete :book # --> would delete the first book record found
|
18
|
+
# database.delete :book, proc {|b| b.id < 10} # --> would delete all books found who's id is less than 10
|
19
|
+
# database.delete :books, proc {|b| b.id < 10} # --> would delete all books found who's id is less than 10
|
20
|
+
def delete(resource_name, conditions=nil)
|
21
|
+
model_name = resource_name.to_s.singularize.to_sym
|
22
|
+
raise StandardError, "Invalid DELETE operation: The resource #{model_name} has not been defined" unless @tables[model_name]
|
23
|
+
|
24
|
+
if conditions
|
25
|
+
@tables[model_name].reject!(&conditions)
|
26
|
+
elsif resource_name.singular?
|
27
|
+
@tables[model_name].shift
|
28
|
+
elsif resource_name.plural?
|
29
|
+
@tables[model_name] = []
|
30
|
+
end
|
31
|
+
end
|
15
32
|
|
16
33
|
# pass in a Dupe::Database::Record object, and this method will store the record
|
17
34
|
# in the appropriate table
|
@@ -49,4 +66,4 @@ class Dupe
|
|
49
66
|
end
|
50
67
|
|
51
68
|
end
|
52
|
-
end
|
69
|
+
end
|
data/lib/dupe/dupe.rb
CHANGED
@@ -8,7 +8,7 @@ class Dupe
|
|
8
8
|
attr_reader :sequences #:nodoc:
|
9
9
|
attr_reader :database #:nodoc:
|
10
10
|
|
11
|
-
# set this to "true" if you Dupe to spit out mocked requests
|
11
|
+
# set this to "true" if you want Dupe to spit out mocked requests
|
12
12
|
# after each of your cucumber scenario's run
|
13
13
|
attr_accessor :debug
|
14
14
|
|
@@ -184,6 +184,16 @@ class Dupe
|
|
184
184
|
%r{^#{model_name.to_s.titleize.constantize.prefix rescue '/'}#{model_name.to_s.pluralize}\\.xml$},
|
185
185
|
proc { |post_body| Dupe.create(:#{model_name.to_s}, post_body) }
|
186
186
|
)
|
187
|
+
network.define_service_mock(
|
188
|
+
:put,
|
189
|
+
%r{^#{model_name.to_s.titleize.constantize.prefix rescue '/'}#{model_name.to_s.pluralize}/(\\d+)\\.xml$},
|
190
|
+
proc { |id, put_data| Dupe.find(:#{model_name.to_s}) {|resource| resource.id == id.to_i}.merge!(put_data) }
|
191
|
+
)
|
192
|
+
network.define_service_mock(
|
193
|
+
:delete,
|
194
|
+
%r{^#{model_name.to_s.titleize.constantize.prefix rescue '/'}#{model_name.to_s.pluralize}/(\\d+)\\.xml$},
|
195
|
+
proc { |id| Dupe.delete(:#{model_name.to_s}) {|resource| resource.id == id.to_i} }
|
196
|
+
)
|
187
197
|
}
|
188
198
|
eval(mocks)
|
189
199
|
end
|
@@ -392,6 +402,10 @@ class Dupe
|
|
392
402
|
end
|
393
403
|
end
|
394
404
|
|
405
|
+
def delete(resource, &conditions)
|
406
|
+
database.delete resource, conditions
|
407
|
+
end
|
408
|
+
|
395
409
|
def sequence(name, &block)
|
396
410
|
sequences[name.to_sym] = Sequence.new 1, block
|
397
411
|
end
|
@@ -517,4 +531,4 @@ end
|
|
517
531
|
|
518
532
|
class Dupe
|
519
533
|
class UnprocessableEntity < StandardError; end
|
520
|
-
end
|
534
|
+
end
|
data/lib/dupe/mock.rb
CHANGED
@@ -1,24 +1,18 @@
|
|
1
1
|
class Dupe
|
2
2
|
class Network #:nodoc:
|
3
3
|
class Mock #:nodoc:
|
4
|
-
include Dupe::Network::RestValidation
|
5
|
-
|
6
4
|
class ResourceNotFoundError < StandardError; end
|
7
5
|
|
8
|
-
attr_reader :verb
|
9
6
|
attr_reader :url_pattern
|
10
7
|
attr_reader :response
|
11
8
|
|
12
|
-
def initialize(
|
13
|
-
validate_request_type verb
|
14
|
-
|
9
|
+
def initialize(url_pattern, response_proc=nil)
|
15
10
|
raise(
|
16
11
|
ArgumentError,
|
17
12
|
"The URL pattern parameter must be a type of regular expression."
|
18
13
|
) unless url_pattern.kind_of?(Regexp)
|
19
14
|
|
20
15
|
@response = response_proc || proc {}
|
21
|
-
@verb = verb
|
22
16
|
@url_pattern = url_pattern
|
23
17
|
end
|
24
18
|
|
@@ -39,7 +33,7 @@ class Dupe
|
|
39
33
|
end
|
40
34
|
|
41
35
|
def process_response(resp, url)
|
42
|
-
raise NotImplementedError, "
|
36
|
+
raise NotImplementedError, "When you extend Dupe::Network::Mock, you must implement the #process_response instance method."
|
43
37
|
end
|
44
38
|
end
|
45
39
|
end
|
@@ -50,18 +44,21 @@ class Dupe
|
|
50
44
|
class GetMock < Mock #:nodoc:
|
51
45
|
def process_response(resp, url)
|
52
46
|
case resp
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
47
|
+
|
48
|
+
when NilClass
|
49
|
+
raise ResourceNotFoundError, "Failed with 404: the request '#{url}' returned nil."
|
50
|
+
|
51
|
+
when Dupe::Database::Record
|
52
|
+
resp = resp.to_xml_safe(:root => resp.__model__.name.to_s)
|
53
|
+
|
54
|
+
when Array
|
55
|
+
if resp.empty?
|
56
|
+
resp = [].to_xml :root => 'results'
|
57
|
+
else
|
58
|
+
resp = resp.map {|r| HashPruner.prune(r)}.to_xml(:root => resp.first.__model__.name.to_s.pluralize)
|
59
|
+
end
|
63
60
|
end
|
64
|
-
Dupe.network.log.add_request
|
61
|
+
Dupe.network.log.add_request :get, url, resp
|
65
62
|
resp
|
66
63
|
end
|
67
64
|
end
|
@@ -71,19 +68,60 @@ end
|
|
71
68
|
class Dupe
|
72
69
|
class Network
|
73
70
|
class PostMock < Mock #:nodoc:
|
71
|
+
|
72
|
+
# returns a tuple representing the xml of the processed entity, plus the url to the entity.
|
74
73
|
def process_response(resp, url)
|
75
74
|
case resp
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
75
|
+
|
76
|
+
when NilClass
|
77
|
+
raise StandardError, "Failed with 500: the request '#{url}' returned nil."
|
78
|
+
|
79
|
+
when Dupe::Database::Record
|
80
|
+
new_path = "/#{resp.__model__.name.to_s.pluralize}/#{resp.id}.xml"
|
81
|
+
resp = resp.to_xml_safe(:root => resp.__model__.name.to_s)
|
82
|
+
Dupe.network.log.add_request :post, url, resp
|
83
|
+
return resp, new_path
|
84
|
+
|
85
|
+
else
|
86
|
+
raise StandardError, "Unknown PostMock Response. Your Post intercept mocks must return a Duped resource object or nil"
|
85
87
|
end
|
86
88
|
end
|
87
89
|
end
|
88
90
|
end
|
89
|
-
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class Dupe
|
94
|
+
class Network
|
95
|
+
class PutMock < Mock #:nodoc:
|
96
|
+
|
97
|
+
# returns a tuple representing the xml of the processed entity, plus the url to the entity.
|
98
|
+
def process_response(resp, url)
|
99
|
+
case resp
|
100
|
+
|
101
|
+
when NilClass
|
102
|
+
raise StandardError, "Failed with 500: the request '#{url}' returned nil."
|
103
|
+
|
104
|
+
when Dupe::Database::Record
|
105
|
+
resp = nil
|
106
|
+
Dupe.network.log.add_request :put, url, ""
|
107
|
+
return resp, url
|
108
|
+
|
109
|
+
else
|
110
|
+
raise StandardError, "Unknown PutMock Response. Your Post intercept mocks must return a Duped resource object or nil"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class Dupe
|
118
|
+
class Network
|
119
|
+
class DeleteMock < Mock #:nodoc:
|
120
|
+
# logs the request
|
121
|
+
def process_response(resp, url)
|
122
|
+
Dupe.network.log.add_request :delete, url, ""
|
123
|
+
nil
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
data/lib/dupe/network.rb
CHANGED
@@ -21,15 +21,23 @@ class Dupe
|
|
21
21
|
validate_request_type verb
|
22
22
|
case verb
|
23
23
|
when :get
|
24
|
-
GetMock.new(
|
24
|
+
GetMock.new(url_pattern, response_proc).tap do |mock|
|
25
25
|
@mocks[verb] << mock
|
26
26
|
end
|
27
27
|
when :post
|
28
|
-
PostMock.new(
|
28
|
+
PostMock.new(url_pattern, response_proc).tap do |mock|
|
29
|
+
@mocks[verb].unshift mock
|
30
|
+
end
|
31
|
+
when :put
|
32
|
+
PutMock.new(url_pattern, response_proc).tap do |mock|
|
33
|
+
@mocks[verb].unshift mock
|
34
|
+
end
|
35
|
+
when :delete
|
36
|
+
DeleteMock.new(url_pattern, response_proc).tap do |mock|
|
29
37
|
@mocks[verb].unshift mock
|
30
38
|
end
|
31
39
|
else
|
32
|
-
raise StandardError, "Dupe does not
|
40
|
+
raise StandardError, "Dupe does not support mocking #{verb.to_s.upcase} requests."
|
33
41
|
end
|
34
42
|
end
|
35
43
|
|
@@ -45,4 +53,4 @@ class Dupe
|
|
45
53
|
end
|
46
54
|
|
47
55
|
end
|
48
|
-
end
|
56
|
+
end
|
@@ -62,4 +62,80 @@ describe ActiveResource::Connection do
|
|
62
62
|
b.errors.should be_empty
|
63
63
|
end
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
|
+
describe "#put" do
|
67
|
+
before do
|
68
|
+
@book = Dupe.create :book, :label => 'rooby', :title => 'Rooby'
|
69
|
+
class Book < ActiveResource::Base
|
70
|
+
self.site = ''
|
71
|
+
end
|
72
|
+
@ar_book = Book.find(1)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should pass a request off to the Dupe network if the original request failed" do
|
76
|
+
Dupe.network.should_receive(:request).with(:put, '/books/1.xml', Hash.from_xml(@book.merge(:title => "Rails!").to_xml(:root => 'book'))["book"].symbolize_keys!).once
|
77
|
+
@ar_book.title = 'Rails!'
|
78
|
+
@ar_book.save
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should parse the xml and turn the result into active resource objects" do
|
82
|
+
@book.title.should == "Rooby"
|
83
|
+
@ar_book.title = "Rails!"
|
84
|
+
@ar_book.save
|
85
|
+
@ar_book.new?.should == false
|
86
|
+
@ar_book.valid?.should == true
|
87
|
+
@ar_book.id.should == 1
|
88
|
+
@ar_book.label.should == "rooby"
|
89
|
+
@book.title.should == "Rails!"
|
90
|
+
@book.id.should == 1
|
91
|
+
@book.label.should == 'rooby'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should make ActiveResource throw an unprocessable entity exception if our Put mock throws a Dupe::UnprocessableEntity exception" do
|
95
|
+
Put %r{/books/(\d+)\.xml} do |id, put_data|
|
96
|
+
raise Dupe::UnprocessableEntity.new(:title => " must be present.") unless put_data[:title]
|
97
|
+
Dupe.find(:book) {|b| b.id == id.to_i}.merge!(put_data)
|
98
|
+
end
|
99
|
+
|
100
|
+
@ar_book.title = nil
|
101
|
+
@ar_book.save.should == false
|
102
|
+
@ar_book.errors.on_base.should_not be_empty
|
103
|
+
|
104
|
+
@ar_book.title = "Rails!"
|
105
|
+
@ar_book.save.should == true
|
106
|
+
# the following line should be true, were it not for a bug in active_resource 2.3.3 - 2.3.5
|
107
|
+
# i reported the bug here: https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4169-activeresourcebasesave-put-doesnt-clear-out-errors
|
108
|
+
# @ar_book.errors.should be_empty
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "#delete" do
|
113
|
+
before do
|
114
|
+
@book = Dupe.create :book, :label => 'rooby', :title => 'Rooby'
|
115
|
+
class Book < ActiveResource::Base
|
116
|
+
self.site = ''
|
117
|
+
end
|
118
|
+
@ar_book = Book.find(1)
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should pass a request off to the Dupe network if the original request failed" do
|
122
|
+
Dupe.network.should_receive(:request).with(:delete, '/books/1.xml').once
|
123
|
+
@ar_book.destroy
|
124
|
+
end
|
125
|
+
|
126
|
+
it "trigger a Dupe.delete to delete the mocked resource from the duped database" do
|
127
|
+
Dupe.find(:books).length.should == 1
|
128
|
+
@ar_book.destroy
|
129
|
+
Dupe.find(:books).length.should == 0
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should allow you to override the default DELETE intercept mock" do
|
133
|
+
Delete %r{/books/(\d+)\.xml} do |id|
|
134
|
+
raise StandardError, "Testing Delete override"
|
135
|
+
end
|
136
|
+
|
137
|
+
proc {@ar_book.destroy}.should raise_error(StandardError, "Testing Delete override")
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
@@ -16,6 +16,36 @@ describe Dupe::Database do
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
describe "delete" do
|
20
|
+
before do
|
21
|
+
Dupe.stub 10, :books
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should delete the first record found if the resource name is singular and there is no conditions proc" do
|
25
|
+
Dupe.find(:books).length.should == 10
|
26
|
+
Dupe.database.delete :book
|
27
|
+
Dupe.find(:books).length.should == 9
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should delete all records if the resource name is plural and there is no conditions proc" do
|
31
|
+
Dupe.find(:books).length.should == 10
|
32
|
+
Dupe.database.delete :books
|
33
|
+
Dupe.find(:books).length.should == 0
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should delete all matching records if there is a conditions proc and the resource name is singular" do
|
37
|
+
Dupe.find(:books).length.should == 10
|
38
|
+
Dupe.database.delete :book, proc {|b| b.id < 3}
|
39
|
+
Dupe.find(:books).length.should == 8
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should delete all matching records if there is a conditions proc and the resource name is plural" do
|
43
|
+
Dupe.find(:books).length.should == 10
|
44
|
+
Dupe.database.delete :books, proc {|b| b.id < 3}
|
45
|
+
Dupe.find(:books).length.should == 8
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
19
49
|
describe "insert" do
|
20
50
|
before do
|
21
51
|
Dupe.define :book
|
data/spec/lib_specs/dupe_spec.rb
CHANGED
@@ -173,15 +173,56 @@ describe Dupe do
|
|
173
173
|
Dupe.network.mocks[:get].length.should == 2
|
174
174
|
|
175
175
|
find_all_mock = Dupe.network.mocks[:get].first
|
176
|
-
find_all_mock.
|
176
|
+
find_all_mock.class.should == Dupe::Network::GetMock
|
177
177
|
find_all_mock.url_pattern.should == %r{^/books\.xml$}
|
178
178
|
find_all_mock.mocked_response('/books.xml').should == Dupe.find(:books).to_xml(:root => 'books')
|
179
179
|
|
180
180
|
find_one_mock = Dupe.network.mocks[:get].last
|
181
|
-
find_one_mock.
|
181
|
+
find_one_mock.class.should == Dupe::Network::GetMock
|
182
182
|
find_one_mock.url_pattern.should == %r{^/books/(\d+)\.xml$}
|
183
183
|
find_one_mock.mocked_response('/books/1.xml').should == Dupe.find(:book).to_xml(:root => 'book')
|
184
184
|
end
|
185
|
+
|
186
|
+
it "should add a POST (create resource) mock to the network" do
|
187
|
+
Dupe.network.mocks[:post].should be_empty
|
188
|
+
Dupe.define :book
|
189
|
+
Dupe.network.mocks[:post].should_not be_empty
|
190
|
+
Dupe.network.mocks[:post].length.should == 1
|
191
|
+
|
192
|
+
post_mock = Dupe.network.mocks[:post].first
|
193
|
+
post_mock.class.should == Dupe::Network::PostMock
|
194
|
+
post_mock.url_pattern.should == %r{^/books\.xml$}
|
195
|
+
resp, url = post_mock.mocked_response('/books.xml', {:title => "Rooby"})
|
196
|
+
resp.should == Dupe.find(:book).to_xml(:root => 'book')
|
197
|
+
url.should == "/books/1.xml"
|
198
|
+
end
|
199
|
+
|
200
|
+
it "should add a PUT (update resource) mock to the network" do
|
201
|
+
Dupe.network.mocks[:put].should be_empty
|
202
|
+
book = Dupe.create :book, :title => 'Rooby!'
|
203
|
+
Dupe.network.mocks[:put].should_not be_empty
|
204
|
+
Dupe.network.mocks[:put].length.should == 1
|
205
|
+
|
206
|
+
put_mock = Dupe.network.mocks[:put].first
|
207
|
+
put_mock.class.should == Dupe::Network::PutMock
|
208
|
+
put_mock.url_pattern.should == %r{^/books/(\d+)\.xml$}
|
209
|
+
resp, url = put_mock.mocked_response('/books/1.xml', {:title => "Rails!"})
|
210
|
+
resp.should == nil
|
211
|
+
url.should == "/books/1.xml"
|
212
|
+
book.title.should == "Rails!"
|
213
|
+
end
|
214
|
+
|
215
|
+
it "should add a DELETE mock to the network" do
|
216
|
+
Dupe.network.mocks[:delete].should be_empty
|
217
|
+
book = Dupe.create :book, :title => 'Rooby!'
|
218
|
+
Dupe.network.mocks[:delete].should_not be_empty
|
219
|
+
Dupe.network.mocks[:delete].length.should == 1
|
220
|
+
|
221
|
+
delete_mock = Dupe.network.mocks[:delete].first
|
222
|
+
delete_mock.class.should == Dupe::Network::DeleteMock
|
223
|
+
delete_mock.url_pattern.should == %r{^/books/(\d+)\.xml$}
|
224
|
+
end
|
225
|
+
|
185
226
|
|
186
227
|
it "should honor ActiveResource site prefix's for the find(:all) and find(<id>) mocks" do
|
187
228
|
Dupe.network.mocks[:get].should be_empty
|
@@ -191,12 +232,12 @@ describe Dupe do
|
|
191
232
|
Dupe.network.mocks[:get].length.should == 2
|
192
233
|
|
193
234
|
find_all_mock = Dupe.network.mocks[:get].first
|
194
|
-
find_all_mock.
|
235
|
+
find_all_mock.class.should == Dupe::Network::GetMock
|
195
236
|
find_all_mock.url_pattern.should == %r{^/book_services/authors\.xml$}
|
196
237
|
find_all_mock.mocked_response('/book_services/authors.xml').should == Dupe.find(:authors).to_xml(:root => 'authors')
|
197
238
|
|
198
239
|
find_one_mock = Dupe.network.mocks[:get].last
|
199
|
-
find_one_mock.
|
240
|
+
find_one_mock.class.should == Dupe::Network::GetMock
|
200
241
|
find_one_mock.url_pattern.should == %r{^/book_services/authors/(\d+)\.xml$}
|
201
242
|
find_one_mock.mocked_response('/book_services/authors/1.xml').should == Dupe.find(:author).to_xml(:root => 'author')
|
202
243
|
end
|
@@ -461,4 +502,21 @@ describe Dupe do
|
|
461
502
|
b2.genre.name.should == 'Science Fiction'
|
462
503
|
end
|
463
504
|
end
|
505
|
+
|
506
|
+
describe "##delete" do
|
507
|
+
it "should remove any resources that match the conditions provided in the block" do
|
508
|
+
Dupe.stub 10, :authors
|
509
|
+
Dupe.find(:authors).length.should == 10
|
510
|
+
Dupe.delete :author
|
511
|
+
Dupe.find(:authors).length.should == 9
|
512
|
+
Dupe.delete :authors
|
513
|
+
Dupe.find(:authors).length.should == 0
|
514
|
+
Dupe.create :author, :name => 'CS Lewis'
|
515
|
+
Dupe.create :author, :name => 'Robert Lewis Stevenson'
|
516
|
+
Dupe.create :author, :name => 'Frank Herbert'
|
517
|
+
Dupe.delete(:author) {|a| a.name.match /Lewis/}
|
518
|
+
Dupe.find(:authors).length.should == 1
|
519
|
+
Dupe.find(:authors).first.name.should == 'Frank Herbert'
|
520
|
+
end
|
521
|
+
end
|
464
522
|
end
|
data/spec/lib_specs/mock_spec.rb
CHANGED
@@ -6,26 +6,17 @@ describe Dupe::Network::Mock do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
describe "new" do
|
9
|
-
it "should require a valid REST type" do
|
10
|
-
proc { Dupe::Network::Mock.new :unknown, /\//, proc {} }.should raise_error(Dupe::Network::UnknownRestVerbError)
|
11
|
-
proc { Dupe::Network::Mock.new :get, /\//, proc {} }.should_not raise_error
|
12
|
-
proc { Dupe::Network::Mock.new :post, /\//, proc {} }.should_not raise_error
|
13
|
-
proc { Dupe::Network::Mock.new :put, /\//, proc {} }.should_not raise_error
|
14
|
-
proc { Dupe::Network::Mock.new :delete, /\//, proc {} }.should_not raise_error
|
15
|
-
end
|
16
|
-
|
17
9
|
it "should require the url be a kind of regular expression" do
|
18
|
-
proc { Dupe::Network::Mock.new
|
10
|
+
proc { Dupe::Network::Mock.new '', proc {} }.should raise_error(
|
19
11
|
ArgumentError,
|
20
12
|
"The URL pattern parameter must be a type of regular expression."
|
21
13
|
)
|
22
14
|
end
|
23
15
|
|
24
|
-
it "should set the
|
16
|
+
it "should set the, @url, and @response parameters accordingly" do
|
25
17
|
url_pattern = /\//
|
26
18
|
response = proc {}
|
27
|
-
mock = Dupe::Network::Mock.new
|
28
|
-
mock.verb.should == :get
|
19
|
+
mock = Dupe::Network::Mock.new url_pattern, response
|
29
20
|
mock.url_pattern.should == url_pattern
|
30
21
|
mock.response.should == response
|
31
22
|
end
|
@@ -35,7 +26,7 @@ describe Dupe::Network::Mock do
|
|
35
26
|
it "should determine if a given string matches the mock's url pattern" do
|
36
27
|
url = %r{/blogs/(\d+).xml}
|
37
28
|
response = proc {}
|
38
|
-
mock = Dupe::Network::Mock.new
|
29
|
+
mock = Dupe::Network::Mock.new url, response
|
39
30
|
mock.match?('/blogs/1.xml').should == true
|
40
31
|
mock.match?('/bogs/1.xml').should == false
|
41
32
|
end
|
@@ -53,13 +44,13 @@ describe Dupe::Network::GetMock do
|
|
53
44
|
url_pattern = %r{/books/(\d+)\.xml}
|
54
45
|
response = proc {|id| Dupe.find(:book) {|b| b.id == id.to_i}}
|
55
46
|
book = Dupe.create :book
|
56
|
-
mock = Dupe::Network::GetMock.new
|
47
|
+
mock = Dupe::Network::GetMock.new url_pattern, response
|
57
48
|
mock.mocked_response('/books/1.xml').should == book.to_xml(:root => 'book')
|
58
49
|
|
59
50
|
proc { mock.mocked_response('/books/2.xml') }.should raise_error(Dupe::Network::GetMock::ResourceNotFoundError)
|
60
51
|
|
61
52
|
Dupe.define :author
|
62
|
-
mock = Dupe::Network::GetMock.new
|
53
|
+
mock = Dupe::Network::GetMock.new %r{/authors\.xml$}, proc {Dupe.find :authors}
|
63
54
|
mock.mocked_response('/authors.xml').should == [].to_xml(:root => 'results')
|
64
55
|
end
|
65
56
|
|
@@ -67,7 +58,7 @@ describe Dupe::Network::GetMock do
|
|
67
58
|
url_pattern = %r{/books/([a-zA-Z0-9-]+)\.xml}
|
68
59
|
response = proc {|label| Dupe.find(:book) {|b| b.label == label}}
|
69
60
|
book = Dupe.create :book, :label => 'rooby'
|
70
|
-
mock = Dupe::Network::GetMock.new
|
61
|
+
mock = Dupe::Network::GetMock.new url_pattern, response
|
71
62
|
Dupe.network.log.requests.length.should == 0
|
72
63
|
mock.mocked_response('/books/rooby.xml')
|
73
64
|
Dupe.network.log.requests.length.should == 1
|
@@ -79,7 +70,7 @@ describe Dupe::Network::GetMock do
|
|
79
70
|
url_pattern = %r{/authors/(\d+)\.xml}
|
80
71
|
response = proc { |id| Dupe.find(:author) {|a| a.id == id.to_i}}
|
81
72
|
Dupe.define :author
|
82
|
-
mock = Dupe::Network::GetMock.new
|
73
|
+
mock = Dupe::Network::GetMock.new url_pattern, response
|
83
74
|
proc {mock.mocked_response('/authors/1.xml')}.should raise_error(Dupe::Network::GetMock::ResourceNotFoundError)
|
84
75
|
end
|
85
76
|
end
|
@@ -87,13 +78,13 @@ describe Dupe::Network::GetMock do
|
|
87
78
|
describe "on a mock object whose response returns an empty array" do
|
88
79
|
it "should convert the empty array to an xml array record set with root 'results'" do
|
89
80
|
Dupe.define :author
|
90
|
-
mock = Dupe::Network::GetMock.new
|
81
|
+
mock = Dupe::Network::GetMock.new %r{/authors\.xml$}, proc {Dupe.find :authors}
|
91
82
|
mock.mocked_response('/authors.xml').should == [].to_xml(:root => 'results')
|
92
83
|
end
|
93
84
|
|
94
85
|
it "should add a request to the Dupe::Network#log" do
|
95
86
|
Dupe.define :author
|
96
|
-
mock = Dupe::Network::GetMock.new
|
87
|
+
mock = Dupe::Network::GetMock.new %r{/authors\.xml$}, proc {Dupe.find :authors}
|
97
88
|
Dupe.network.log.requests.length.should == 0
|
98
89
|
mock.mocked_response('/authors.xml')
|
99
90
|
Dupe.network.log.requests.length.should == 1
|
@@ -103,13 +94,13 @@ describe Dupe::Network::GetMock do
|
|
103
94
|
describe "on a mock object whose response returns an array of duped records" do
|
104
95
|
it "should convert the array to xml" do
|
105
96
|
Dupe.create :author
|
106
|
-
mock = Dupe::Network::GetMock.new
|
97
|
+
mock = Dupe::Network::GetMock.new %r{/authors\.xml$}, proc {Dupe.find :authors}
|
107
98
|
mock.mocked_response('/authors.xml').should == Dupe.find(:authors).to_xml(:root => 'authors')
|
108
99
|
end
|
109
100
|
|
110
101
|
it "should add a request to the Dupe::Network#log" do
|
111
102
|
Dupe.create :author
|
112
|
-
mock = Dupe::Network::GetMock.new
|
103
|
+
mock = Dupe::Network::GetMock.new %r{/authors\.xml$}, proc {Dupe.find :authors}
|
113
104
|
Dupe.network.log.requests.length.should == 0
|
114
105
|
mock.mocked_response('/authors.xml')
|
115
106
|
Dupe.network.log.requests.length.should == 1
|
@@ -127,7 +118,7 @@ describe Dupe::Network::PostMock do
|
|
127
118
|
describe "on a mock object whose response returns a location of a new record" do
|
128
119
|
it "should convert the new post to xml" do
|
129
120
|
Dupe.define :author
|
130
|
-
mock = Dupe::Network::PostMock.new
|
121
|
+
mock = Dupe::Network::PostMock.new %r{/authors\.xml$}, proc {|post_data| Dupe.create(:author, post_data)}
|
131
122
|
resp, url = mock.mocked_response('/authors.xml', {:name => "Rachel"})
|
132
123
|
resp.should == Dupe.find(:authors).first.to_xml_safe(:root => 'author')
|
133
124
|
url.should == "/authors/1.xml"
|
@@ -135,11 +126,69 @@ describe Dupe::Network::PostMock do
|
|
135
126
|
|
136
127
|
it "should add a request to the Dupe::Network#log" do
|
137
128
|
Dupe.define :author
|
138
|
-
mock = Dupe::Network::PostMock.new
|
129
|
+
mock = Dupe::Network::PostMock.new %r{/authors\.xml$}, proc {|post_data| Dupe.create(:author, post_data)}
|
139
130
|
Dupe.network.log.requests.length.should == 0
|
140
131
|
mock.mocked_response('/authors.xml', {:name => "Rachel"})
|
141
132
|
Dupe.network.log.requests.length.should == 1
|
142
133
|
end
|
143
134
|
end
|
144
135
|
end
|
145
|
-
end
|
136
|
+
end
|
137
|
+
|
138
|
+
describe Dupe::Network::PutMock do
|
139
|
+
before do
|
140
|
+
Dupe.reset
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "mocked_response" do
|
144
|
+
describe "on a mock object whose response returns a location of a new record" do
|
145
|
+
before do
|
146
|
+
Dupe.define :author
|
147
|
+
@a = Dupe.create :author, :name => "Matt"
|
148
|
+
@mock = Dupe::Network::PutMock.new %r{/authors/(\d+)\.xml$}, proc {|id, put_data| Dupe.find(:author) {|a| a.id == id.to_i}.merge!(put_data)}
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should convert the put to xml" do
|
152
|
+
resp, url = @mock.mocked_response('/authors/1.xml', {:name => "Rachel"})
|
153
|
+
resp.should == nil
|
154
|
+
@a.name.should == "Rachel"
|
155
|
+
url.should == "/authors/1.xml"
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should add a request to the Dupe::Network#log" do
|
159
|
+
Dupe.network.log.requests.length.should == 0
|
160
|
+
@mock.mocked_response('/authors/1.xml', {:name => "Rachel"})
|
161
|
+
Dupe.network.log.requests.length.should == 1
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe Dupe::Network::DeleteMock do
|
168
|
+
before do
|
169
|
+
Dupe.reset
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "mocked_response" do
|
173
|
+
describe "on a mock object whose response returns a location of a new record" do
|
174
|
+
before do
|
175
|
+
Dupe.define :author
|
176
|
+
@a = Dupe.create :author, :name => "Matt"
|
177
|
+
@mock = Dupe::Network::DeleteMock.new %r{/authors/(\d+)\.xml$}, proc {|id| Dupe.delete(:author) {|a| a.id == id.to_i}}
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should convert the put to xml" do
|
181
|
+
Dupe.find(:authors).length.should == 1
|
182
|
+
resp = @mock.mocked_response('/authors/1.xml')
|
183
|
+
resp.should == nil
|
184
|
+
Dupe.find(:authors).length.should == 0
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should add a request to the Dupe::Network#log" do
|
188
|
+
Dupe.network.log.requests.length.should == 0
|
189
|
+
@mock.mocked_response('/authors/1.xml')
|
190
|
+
Dupe.network.log.requests.length.should == 1
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
@@ -68,7 +68,7 @@ describe Dupe::Network do
|
|
68
68
|
proc { @network.define_service_mock :invalid_rest_verb, // }.should raise_error(Dupe::Network::UnknownRestVerbError)
|
69
69
|
proc { @network.define_service_mock :get, // }.should_not raise_error(Dupe::Network::UnknownRestVerbError)
|
70
70
|
proc { @network.define_service_mock :post, // }.should_not raise_error(Dupe::Network::UnknownRestVerbError)
|
71
|
-
|
71
|
+
proc { @network.define_service_mock :put, // }.should_not raise_error(Dupe::Network::UnknownRestVerbError)
|
72
72
|
end
|
73
73
|
|
74
74
|
it "should require a valid Regexp url pattern" do
|
@@ -76,7 +76,6 @@ describe Dupe::Network do
|
|
76
76
|
proc { @network.define_service_mock :post, 'not a regular expression' }.should raise_error(ArgumentError)
|
77
77
|
proc { @network.define_service_mock :get, // }.should_not raise_error
|
78
78
|
proc { @network.define_service_mock :post, // }.should_not raise_error
|
79
|
-
|
80
79
|
end
|
81
80
|
|
82
81
|
it "should create and return a new get service mock when given valid parameters" do
|
@@ -86,7 +85,7 @@ describe Dupe::Network do
|
|
86
85
|
@network.mocks[:get].should be_empty
|
87
86
|
mock = @network.define_service_mock verb, pattern, response
|
88
87
|
@network.mocks[:get].should_not be_empty
|
89
|
-
@network.mocks[:
|
88
|
+
@network.mocks[:get].first.class.should == Dupe::Network::GetMock
|
90
89
|
@network.mocks[:get].length.should == 1
|
91
90
|
@network.mocks[:get].first.should == mock
|
92
91
|
end
|
@@ -98,12 +97,34 @@ describe Dupe::Network do
|
|
98
97
|
@network.mocks[:post].should be_empty
|
99
98
|
mock = @network.define_service_mock verb, pattern, response
|
100
99
|
@network.mocks[:post].should_not be_empty
|
101
|
-
@network.mocks[:post].first.class ==
|
100
|
+
@network.mocks[:post].first.class.should == Dupe::Network::PostMock
|
102
101
|
@network.mocks[:post].length.should == 1
|
103
102
|
@network.mocks[:post].first.should == mock
|
104
103
|
end
|
105
|
-
|
106
104
|
|
105
|
+
it "should create and return a new put service mock when given valid parameters" do
|
106
|
+
verb = :put
|
107
|
+
pattern = //
|
108
|
+
response = proc { 'test' }
|
109
|
+
@network.mocks[:put].should be_empty
|
110
|
+
mock = @network.define_service_mock verb, pattern, response
|
111
|
+
@network.mocks[:put].should_not be_empty
|
112
|
+
@network.mocks[:put].first.class.should == Dupe::Network::PutMock
|
113
|
+
@network.mocks[:put].length.should == 1
|
114
|
+
@network.mocks[:put].first.should == mock
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should create and return a new delete service mock when given valid parameters" do
|
118
|
+
verb = :delete
|
119
|
+
pattern = //
|
120
|
+
response = proc { 'test' }
|
121
|
+
@network.mocks[:delete].should be_empty
|
122
|
+
mock = @network.define_service_mock verb, pattern, response
|
123
|
+
@network.mocks[:delete].should_not be_empty
|
124
|
+
@network.mocks[:delete].first.class.should == Dupe::Network::DeleteMock
|
125
|
+
@network.mocks[:delete].length.should == 1
|
126
|
+
@network.mocks[:delete].first.should == mock
|
127
|
+
end
|
107
128
|
end
|
108
129
|
|
109
|
-
end
|
130
|
+
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.5.
|
4
|
+
version: 0.5.1
|
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-03-
|
12
|
+
date: 2010-03-14 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|