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 CHANGED
@@ -21,6 +21,7 @@ class Dupe
21
21
  end
22
22
  @tables[record.__model__.name] ||= []
23
23
  @tables[record.__model__.name] << record
24
+ record.__model__.run_after_create_callbacks(record)
24
25
  end
25
26
 
26
27
  # pass in a model_name (e.g., :book) and optionally a proc with
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.to_xml(:root => resp.__model__.name.to_s)
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
- @schema.after_create_callbacks.each do |callback|
24
- callback.call record
25
- end
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'
@@ -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.to_xml(:root => '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
@@ -108,8 +108,8 @@ describe Dupe::Network::Mock do
108
108
  mock.mocked_response('/authors.xml')
109
109
  Dupe.network.log.requests.length.should == 1
110
110
  end
111
- end
111
+ end
112
112
  end
113
113
 
114
114
 
115
- end
115
+ end
@@ -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
- book.label.should == 'untitled'
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
- book.label.should == 'rooby-on-rails'
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.6
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-01-31 00:00:00 -05:00
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