dupe 0.4.6 → 0.4.7
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/lib/dupe/database.rb +1 -0
- data/lib/dupe/dupe.rb +4 -0
- data/lib/dupe/hash_pruner.rb +37 -0
- data/lib/dupe/mock.rb +3 -3
- data/lib/dupe/model.rb +7 -3
- data/lib/dupe.rb +2 -1
- data/spec/lib_specs/dupe_spec.rb +19 -0
- data/spec/lib_specs/hash_pruner.rb +73 -0
- data/spec/lib_specs/mock_definitions_spec.rb +1 -1
- data/spec/lib_specs/mock_spec.rb +2 -2
- data/spec/lib_specs/model_spec.rb +7 -2
- metadata +4 -2
data/lib/dupe/database.rb
CHANGED
data/lib/dupe/dupe.rb
CHANGED
|
@@ -468,6 +468,7 @@ class Dupe
|
|
|
468
468
|
"as the second parameter to create_and_insert."
|
|
469
469
|
) if !into || !into.kind_of?(Hash) || !into[:into]
|
|
470
470
|
|
|
471
|
+
# do we have several records to create, and are they each a hash?
|
|
471
472
|
if records.kind_of?(Array) and
|
|
472
473
|
records.inject(true) {|bool, r| bool and r.kind_of?(Hash)}
|
|
473
474
|
[].tap do |results|
|
|
@@ -475,8 +476,11 @@ class Dupe
|
|
|
475
476
|
results << models[into[:into]].create(record).tap {|r| database.insert r}
|
|
476
477
|
end
|
|
477
478
|
end
|
|
479
|
+
|
|
480
|
+
# do we only have one record to create, and is it a hash?
|
|
478
481
|
elsif records.kind_of?(Hash)
|
|
479
482
|
models[into[:into]].create(records).tap {|r| database.insert r}
|
|
483
|
+
|
|
480
484
|
else
|
|
481
485
|
raise ArgumentError, "You must call Dupe.create with either a hash or an array of hashes."
|
|
482
486
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
class HashPruner
|
|
2
|
+
class << self
|
|
3
|
+
def prune(hash)
|
|
4
|
+
HashPruner.new.prune hash
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def initialize()
|
|
9
|
+
@visited = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def prune(item)
|
|
13
|
+
if item.kind_of? Array
|
|
14
|
+
item.map {|i| prune(i)}.reject {|v| v==nil}
|
|
15
|
+
elsif item.kind_of? Hash
|
|
16
|
+
if @visited[item.object_id]
|
|
17
|
+
item.dup.delete_if {|k,v| v.kind_of?(Hash) || v.kind_of?(Array)}
|
|
18
|
+
else
|
|
19
|
+
@visited[item.object_id] = true
|
|
20
|
+
new_hash = {}
|
|
21
|
+
item.each do |k,v|
|
|
22
|
+
new_hash[k] = prune(v)
|
|
23
|
+
end
|
|
24
|
+
@visited.delete item.object_id
|
|
25
|
+
new_hash
|
|
26
|
+
end
|
|
27
|
+
else
|
|
28
|
+
item
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class Hash
|
|
34
|
+
def to_xml_safe(options={})
|
|
35
|
+
HashPruner.prune(self).to_xml(options)
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/dupe/mock.rb
CHANGED
|
@@ -39,12 +39,12 @@ class Dupe
|
|
|
39
39
|
when NilClass
|
|
40
40
|
raise ResourceNotFoundError, "Failed with 404: the request '#{url}' returned nil."
|
|
41
41
|
when Dupe::Database::Record
|
|
42
|
-
resp = resp.
|
|
42
|
+
resp = resp.to_xml_safe(:root => resp.__model__.name.to_s)
|
|
43
43
|
when Array
|
|
44
44
|
if resp.empty?
|
|
45
45
|
resp = [].to_xml :root => 'results'
|
|
46
46
|
else
|
|
47
|
-
resp = resp.to_xml(:root => resp.first.__model__.name.to_s.pluralize)
|
|
47
|
+
resp = resp.map {|r| HashPruner.prune(r)}.to_xml(:root => resp.first.__model__.name.to_s.pluralize)
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
@@ -55,4 +55,4 @@ class Dupe
|
|
|
55
55
|
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
|
-
end
|
|
58
|
+
end
|
data/lib/dupe/model.rb
CHANGED
|
@@ -20,9 +20,13 @@ class Dupe
|
|
|
20
20
|
record.id = @id_sequence.next
|
|
21
21
|
record.merge! default_record
|
|
22
22
|
record.merge! transform(attributes)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# called by the Dupe::Database#insert method
|
|
27
|
+
def run_after_create_callbacks(record)
|
|
28
|
+
@schema.after_create_callbacks.each do |callback|
|
|
29
|
+
callback.call record
|
|
26
30
|
end
|
|
27
31
|
end
|
|
28
32
|
|
data/lib/dupe.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'dupe/hash_pruner'
|
|
1
2
|
require 'active_resource'
|
|
2
3
|
require 'active_resource/http_mock'
|
|
3
4
|
require 'dupe/singular_plural_detection'
|
|
@@ -16,4 +17,4 @@ require 'dupe/schema'
|
|
|
16
17
|
require 'dupe/model'
|
|
17
18
|
require 'dupe/custom_mocks'
|
|
18
19
|
require 'dupe/active_resource_extensions'
|
|
19
|
-
require 'dupe/cucumber_hooks'
|
|
20
|
+
require 'dupe/cucumber_hooks'
|
data/spec/lib_specs/dupe_spec.rb
CHANGED
|
@@ -288,6 +288,25 @@ describe Dupe do
|
|
|
288
288
|
end
|
|
289
289
|
end
|
|
290
290
|
|
|
291
|
+
describe "create resources that have an after_create callback" do
|
|
292
|
+
before do
|
|
293
|
+
Dupe.define :book do |book|
|
|
294
|
+
book.uniquify :title, :author, :genre
|
|
295
|
+
|
|
296
|
+
book.after_create do |b|
|
|
297
|
+
b.label = b.title.downcase.gsub(/\ +/, '-') unless b.label
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
it "should create a label based on the title if a label is passed in during the create call" do
|
|
303
|
+
b = Dupe.create :book, :title => 'Testing Testing'
|
|
304
|
+
b.label.should == 'testing-testing'
|
|
305
|
+
b = Dupe.create :book, :title => 'Testing Testing', :label => 'testbook'
|
|
306
|
+
b.label.should == 'testbook'
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
|
|
291
310
|
describe "find" do
|
|
292
311
|
before do
|
|
293
312
|
Dupe.define :book
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
|
2
|
+
|
|
3
|
+
describe HashPruner do
|
|
4
|
+
describe "#prune" do
|
|
5
|
+
it "should nil out any repeated hashes" do
|
|
6
|
+
clarke = {:name => "Arthur C. Clarke"}
|
|
7
|
+
heinlein = {:name => "Robert Heinlein"}
|
|
8
|
+
sci_fi = {:name => "Science Fiction", :authors => [clarke, heinlein]}
|
|
9
|
+
clarke[:genre] = sci_fi
|
|
10
|
+
odyssey = {:name => "2001", :genre => sci_fi, :author => clarke}
|
|
11
|
+
hoag = {:name => "the unpleasant profession", :genre => sci_fi, :author => heinlein}
|
|
12
|
+
clarke[:books] = [odyssey]
|
|
13
|
+
heinlein[:books] = [hoag]
|
|
14
|
+
|
|
15
|
+
HashPruner.prune(clarke).should ==
|
|
16
|
+
{
|
|
17
|
+
:name=>"Arthur C. Clarke",
|
|
18
|
+
:genre => {
|
|
19
|
+
:name => "Science Fiction",
|
|
20
|
+
:authors => [
|
|
21
|
+
{
|
|
22
|
+
:name=>"Arthur C. Clarke"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
:name=>"Robert Heinlein",
|
|
26
|
+
:books=> [
|
|
27
|
+
{
|
|
28
|
+
:name => "the unpleasant profession",
|
|
29
|
+
:genre => {
|
|
30
|
+
:name => "Science Fiction"
|
|
31
|
+
},
|
|
32
|
+
:author => {
|
|
33
|
+
:name => "Robert Heinlein"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
:books=> [
|
|
41
|
+
{
|
|
42
|
+
:name => "2001",
|
|
43
|
+
:genre => {
|
|
44
|
+
:name => "Science Fiction",
|
|
45
|
+
:authors => [
|
|
46
|
+
{
|
|
47
|
+
:name => "Arthur C. Clarke"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
:name=>"Robert Heinlein",
|
|
51
|
+
:books=> [
|
|
52
|
+
{
|
|
53
|
+
:name => "the unpleasant profession",
|
|
54
|
+
:genre => {
|
|
55
|
+
:name => "Science Fiction"
|
|
56
|
+
},
|
|
57
|
+
:author => {
|
|
58
|
+
:name => "Robert Heinlein"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
},
|
|
65
|
+
:author => {
|
|
66
|
+
:name => "Arthur C. Clarke"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -26,7 +26,7 @@ describe "Mock Definition Methods" do
|
|
|
26
26
|
Dupe.network.mocks[:get].last.should == mock
|
|
27
27
|
Dupe.network.mocks[:get].last.url_pattern.should == %r{/books/([^&]+)\.xml}
|
|
28
28
|
book = Dupe.find(:book)
|
|
29
|
-
Dupe.network.request(:get, '/books/rooby.xml').should == book.
|
|
29
|
+
Dupe.network.request(:get, '/books/rooby.xml').should == book.to_xml_safe(:root => 'book')
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
end
|
data/spec/lib_specs/mock_spec.rb
CHANGED
|
@@ -77,13 +77,18 @@ describe Dupe::Model do
|
|
|
77
77
|
book.id.should == 1
|
|
78
78
|
book.title.should == 'Untitled'
|
|
79
79
|
book.author.should == 'Anon'
|
|
80
|
-
|
|
80
|
+
|
|
81
|
+
# the callback shouldn't get run until the database record is inserted into the duped 'database'
|
|
82
|
+
book.label.should == nil
|
|
81
83
|
|
|
82
84
|
book = @book_model.create :title => 'Rooby On Rails', :author => 'Matt Parker'
|
|
83
85
|
book.__model__.name.should == :book
|
|
84
86
|
book.id.should == 2
|
|
85
87
|
book.title.should == 'Rooby On Rails'
|
|
86
|
-
|
|
88
|
+
|
|
89
|
+
# the callback shouldn't get run until the database record is inserted into the duped 'database'
|
|
90
|
+
book.label.should == nil
|
|
91
|
+
|
|
87
92
|
book.author.should == 'Author: Matt Parker'
|
|
88
93
|
end
|
|
89
94
|
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.
|
|
4
|
+
version: 0.4.7
|
|
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-
|
|
12
|
+
date: 2010-02-03 00:00:00 -05:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
@@ -42,6 +42,7 @@ files:
|
|
|
42
42
|
- lib/dupe/custom_mocks.rb
|
|
43
43
|
- lib/dupe/database.rb
|
|
44
44
|
- lib/dupe/dupe.rb
|
|
45
|
+
- lib/dupe/hash_pruner.rb
|
|
45
46
|
- lib/dupe/log.rb
|
|
46
47
|
- lib/dupe/mock.rb
|
|
47
48
|
- lib/dupe/model.rb
|
|
@@ -90,6 +91,7 @@ test_files:
|
|
|
90
91
|
- spec/lib_specs/attribute_template_spec.rb
|
|
91
92
|
- spec/lib_specs/database_spec.rb
|
|
92
93
|
- spec/lib_specs/dupe_spec.rb
|
|
94
|
+
- spec/lib_specs/hash_pruner.rb
|
|
93
95
|
- spec/lib_specs/log_spec.rb
|
|
94
96
|
- spec/lib_specs/logged_request_spec.rb
|
|
95
97
|
- spec/lib_specs/mock_definitions_spec.rb
|