superdupe 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +37 -1
- data/lib/superdupe/active_resource_extensions.rb +2 -1
- data/lib/superdupe/dupe.rb +15 -14
- data/lib/superdupe/mock.rb +6 -2
- data/lib/superdupe/record.rb +7 -1
- data/spec/lib_specs/active_resource_extensions_spec.rb +78 -114
- data/spec/spec_helper.rb +1 -1
- metadata +4 -36
- data/spec/lib_specs/attribute_template_spec.rb +0 -173
- data/spec/lib_specs/database_spec.rb +0 -163
- data/spec/lib_specs/dupe_spec.rb +0 -522
- data/spec/lib_specs/hash_pruner_spec.rb +0 -73
- data/spec/lib_specs/log_spec.rb +0 -78
- data/spec/lib_specs/logged_request_spec.rb +0 -22
- data/spec/lib_specs/mock_definitions_spec.rb +0 -58
- data/spec/lib_specs/mock_spec.rb +0 -194
- data/spec/lib_specs/model_spec.rb +0 -95
- data/spec/lib_specs/network_spec.rb +0 -130
- data/spec/lib_specs/record_spec.rb +0 -70
- data/spec/lib_specs/rest_validation_spec.rb +0 -17
- data/spec/lib_specs/schema_spec.rb +0 -109
- data/spec/lib_specs/sequence_spec.rb +0 -39
- data/spec/lib_specs/string_spec.rb +0 -31
- data/spec/lib_specs/symbol_spec.rb +0 -17
@@ -1,163 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
|
3
|
-
describe Dupe::Database do
|
4
|
-
before do
|
5
|
-
Dupe.reset
|
6
|
-
end
|
7
|
-
|
8
|
-
describe "new" do
|
9
|
-
before do
|
10
|
-
@database = Dupe::Database.new
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should initialize an empty table set" do
|
14
|
-
@database.tables.should be_kind_of(Hash)
|
15
|
-
@database.tables.should be_empty
|
16
|
-
end
|
17
|
-
end
|
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
|
-
|
49
|
-
describe "insert" do
|
50
|
-
before do
|
51
|
-
Dupe.define :book
|
52
|
-
@book = Dupe.models[:book].create :title => 'test'
|
53
|
-
@database = Dupe::Database.new
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should require a record" do
|
57
|
-
proc {@database.insert}.should raise_error(ArgumentError)
|
58
|
-
proc {
|
59
|
-
@database.insert 'not a Dupe::Database::Record object'
|
60
|
-
}.should raise_error(
|
61
|
-
ArgumentError,
|
62
|
-
"You may only insert well-defined Dupe::Database::Record objects"
|
63
|
-
)
|
64
|
-
proc {
|
65
|
-
@database.insert Dupe::Database::Record.new
|
66
|
-
}.should raise_error(
|
67
|
-
ArgumentError,
|
68
|
-
"You may only insert well-defined Dupe::Database::Record objects"
|
69
|
-
)
|
70
|
-
proc {@database.insert @book}.should_not raise_error
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should create a new table if one does not already exist upon insert" do
|
74
|
-
@database.tables.should be_empty
|
75
|
-
@database.insert @book
|
76
|
-
@database.tables[:book].should_not be_nil
|
77
|
-
@database.tables[:book].should be_kind_of(Array)
|
78
|
-
@database.tables[:book].should_not be_empty
|
79
|
-
@database.tables[:book].first.should_not be_nil
|
80
|
-
@database.tables[:book].first.should == @book
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
describe "select" do
|
85
|
-
before do
|
86
|
-
Dupe.define :book
|
87
|
-
@book = Dupe.models[:book].create :title => 'test'
|
88
|
-
@database = Dupe::Database.new
|
89
|
-
@database.insert @book
|
90
|
-
end
|
91
|
-
|
92
|
-
it "should require a valid model name" do
|
93
|
-
proc { @database.select }.should raise_error(ArgumentError)
|
94
|
-
proc { @database.select :undefined_model }.should raise_error(
|
95
|
-
Dupe::Database::TableDoesNotExistError,
|
96
|
-
"The table ':undefined_model' does not exist."
|
97
|
-
)
|
98
|
-
proc { @database.select :book }.should_not raise_error
|
99
|
-
end
|
100
|
-
|
101
|
-
it "should accept a conditions proc" do
|
102
|
-
proc { @database.select :book, proc {|c| true} }.should_not raise_error
|
103
|
-
end
|
104
|
-
|
105
|
-
it "should verify that the conditions proc accepts a single parameter" do
|
106
|
-
proc { @database.select :book, proc {true} }.should raise_error(
|
107
|
-
Dupe::Database::InvalidQueryError,
|
108
|
-
"There was a problem with your select conditions. Please consult the API."
|
109
|
-
)
|
110
|
-
end
|
111
|
-
|
112
|
-
it "should find the requested items and return an array" do
|
113
|
-
results = @database.select :book, proc {|b| b.title == 'test' }
|
114
|
-
results.should be_kind_of(Array)
|
115
|
-
results.should_not be_empty
|
116
|
-
results.first.__model__.should == Dupe.models[:book]
|
117
|
-
results.first.__model__.name.should == :book
|
118
|
-
results.first.title.should == 'test'
|
119
|
-
results.first.id.should == 1
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
describe "create_table" do
|
124
|
-
it "should create a database table if one doesn't already exist" do
|
125
|
-
@database = Dupe::Database.new
|
126
|
-
@database.tables.length.should == 0
|
127
|
-
@database.tables[:book].should be_nil
|
128
|
-
@database.create_table 'book'
|
129
|
-
@database.tables[:book].should_not be_nil
|
130
|
-
@database.tables.length.should == 1
|
131
|
-
@database.tables[:book].should == []
|
132
|
-
|
133
|
-
# make sure it doesn't overwrite a table that already exists
|
134
|
-
m = Dupe::Model.new :book
|
135
|
-
record = m.create
|
136
|
-
@database.insert record
|
137
|
-
@database.tables[:book].length.should == 1
|
138
|
-
@database.tables[:book].first.should == record
|
139
|
-
@database.create_table :book
|
140
|
-
@database.tables[:book].length.should == 1
|
141
|
-
@database.tables[:book].first.should == record
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
describe "truncate_tables" do
|
146
|
-
it "should remove all records from all tables" do
|
147
|
-
Dupe.create :book
|
148
|
-
Dupe.create :author
|
149
|
-
Dupe.create :publisher
|
150
|
-
Dupe.database.tables.length.should == 3
|
151
|
-
Dupe.database.tables[:book].length.should == 1
|
152
|
-
Dupe.database.tables[:author].length.should == 1
|
153
|
-
Dupe.database.tables[:publisher].length.should == 1
|
154
|
-
Dupe.database.truncate_tables
|
155
|
-
Dupe.database.tables.length.should == 3
|
156
|
-
Dupe.database.tables[:book].length.should == 0
|
157
|
-
Dupe.database.tables[:author].length.should == 0
|
158
|
-
Dupe.database.tables[:publisher].length.should == 0
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
|
163
|
-
end
|
data/spec/lib_specs/dupe_spec.rb
DELETED
@@ -1,522 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
|
3
|
-
describe Dupe do
|
4
|
-
before do
|
5
|
-
Dupe.reset
|
6
|
-
end
|
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
|
-
|
48
|
-
describe "reset" do
|
49
|
-
it "should call reset_models, reset_database, and reset_network" do
|
50
|
-
Dupe.should_receive(:reset_models).once
|
51
|
-
Dupe.should_receive(:reset_database).once
|
52
|
-
Dupe.should_receive(:reset_network).once
|
53
|
-
Dupe.should_receive(:reset_sequences).once
|
54
|
-
Dupe.reset
|
55
|
-
end
|
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
|
69
|
-
|
70
|
-
describe "reset_models" do
|
71
|
-
it "should reset @models to an empty hash" do
|
72
|
-
Dupe.models.length.should == 0
|
73
|
-
Dupe.define :book do |attrs|
|
74
|
-
attrs.title
|
75
|
-
attrs.author
|
76
|
-
end
|
77
|
-
Dupe.models.length.should == 1
|
78
|
-
Dupe.reset_models
|
79
|
-
Dupe.models.should == {}
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe "reset_database" do
|
84
|
-
it "should clear out the database" do
|
85
|
-
Dupe.define :book
|
86
|
-
Dupe.define :author
|
87
|
-
Dupe.database.tables.length.should == 2
|
88
|
-
Dupe.reset_database
|
89
|
-
Dupe.database.tables.should be_empty
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
describe "reset_network" do
|
94
|
-
it "should clear out the network" do
|
95
|
-
Dupe.create :book
|
96
|
-
Dupe.network.mocks.values.inject(false) {|b,v| b || !v.empty?}.should == true
|
97
|
-
Dupe.network.mocks[:get].should_not be_empty
|
98
|
-
Dupe.reset_network
|
99
|
-
Dupe.network.mocks.values.inject(false) {|b,v| b || !v.empty?}.should == false
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
describe "define" do
|
104
|
-
|
105
|
-
# Dupe.define :model_name
|
106
|
-
it "should accept a single symbol parameter" do
|
107
|
-
proc {
|
108
|
-
Dupe.define :book
|
109
|
-
}.should_not raise_error
|
110
|
-
end
|
111
|
-
|
112
|
-
# Dupe.define :model_name do |attrs|
|
113
|
-
# attrs.attr1 'Default Value'
|
114
|
-
# attrs.attr2 do |value|
|
115
|
-
# 'transformed value'
|
116
|
-
# end
|
117
|
-
# end
|
118
|
-
it "should accept a symbol plus a block (that accepts a single parameter)" do
|
119
|
-
proc {
|
120
|
-
Dupe.define :book do
|
121
|
-
end
|
122
|
-
}.should raise_error(
|
123
|
-
ArgumentError,
|
124
|
-
"Unknown Dupe.define parameter format. Please consult the API" +
|
125
|
-
" for information on how to use Dupe.define"
|
126
|
-
)
|
127
|
-
|
128
|
-
proc {
|
129
|
-
Dupe.define :book do |attrs|
|
130
|
-
attrs.author 'Anon'
|
131
|
-
attrs.title 'Untitled'
|
132
|
-
end
|
133
|
-
}.should_not raise_error
|
134
|
-
end
|
135
|
-
|
136
|
-
it "should create a model and a schema with the desired definition" do
|
137
|
-
Dupe.define :book do |attrs|
|
138
|
-
attrs.author 'Anon'
|
139
|
-
attrs.genre do
|
140
|
-
'Unknown' + rand(2).to_s
|
141
|
-
end
|
142
|
-
attrs.title 'Untitled' do |value|
|
143
|
-
"transformed #{value}"
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
Dupe.models.length.should == 1
|
148
|
-
Dupe.models[:book].schema.attribute_templates[:author].name.should == :author
|
149
|
-
Dupe.models[:book].schema.attribute_templates[:author].default.should == 'Anon'
|
150
|
-
Dupe.models[:book].schema.attribute_templates[:title].name.should == :title
|
151
|
-
Dupe.models[:book].schema.attribute_templates[:title].default.should == 'Untitled'
|
152
|
-
Dupe.models[:book].schema.attribute_templates[:title].transformer.should be_kind_of(Proc)
|
153
|
-
Dupe.models[:book].schema.attribute_templates[:title].transformer.call('value').should == 'transformed value'
|
154
|
-
Dupe.models[:book].schema.attribute_templates[:genre].name.should == :genre
|
155
|
-
Dupe.models[:book].schema.attribute_templates[:genre].transformer.should be_nil
|
156
|
-
Dupe.models[:book].schema.attribute_templates[:genre].default.should be_kind_of(Proc)
|
157
|
-
Dupe.models[:book].schema.attribute_templates[:genre].default.call.should match(/^Unknown\d$/)
|
158
|
-
end
|
159
|
-
|
160
|
-
it "should add a table to the database" do
|
161
|
-
Dupe.database.tables.length.should == 0
|
162
|
-
Dupe.database.tables[:book].should be_nil
|
163
|
-
Dupe.define :book
|
164
|
-
Dupe.database.tables.length.should == 1
|
165
|
-
Dupe.database.tables[:book].should_not be_nil
|
166
|
-
Dupe.database.tables[:book].should == []
|
167
|
-
end
|
168
|
-
|
169
|
-
it "should add find(:all) and find(<id>) mocks to the network" do
|
170
|
-
Dupe.network.mocks[:get].should be_empty
|
171
|
-
Dupe.create :book
|
172
|
-
Dupe.network.mocks[:get].should_not be_empty
|
173
|
-
Dupe.network.mocks[:get].length.should == 2
|
174
|
-
|
175
|
-
find_all_mock = Dupe.network.mocks[:get].first
|
176
|
-
find_all_mock.class.should == Dupe::Network::GetMock
|
177
|
-
find_all_mock.url_pattern.should == %r{^/books\.xml$}
|
178
|
-
find_all_mock.mocked_response('/books.xml').should == Dupe.find(:books).to_xml(:root => 'books')
|
179
|
-
|
180
|
-
find_one_mock = Dupe.network.mocks[:get].last
|
181
|
-
find_one_mock.class.should == Dupe::Network::GetMock
|
182
|
-
find_one_mock.url_pattern.should == %r{^/books/(\d+)\.xml$}
|
183
|
-
find_one_mock.mocked_response('/books/1.xml').should == Dupe.find(:book).to_xml(:root => 'book')
|
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
|
-
|
226
|
-
|
227
|
-
it "should honor ActiveResource site prefix's for the find(:all) and find(<id>) mocks" do
|
228
|
-
Dupe.network.mocks[:get].should be_empty
|
229
|
-
class Author < ActiveResource::Base; self.site='http://somewhere.com/book_services'; end
|
230
|
-
Dupe.create :author
|
231
|
-
Dupe.network.mocks[:get].should_not be_empty
|
232
|
-
Dupe.network.mocks[:get].length.should == 2
|
233
|
-
|
234
|
-
find_all_mock = Dupe.network.mocks[:get].first
|
235
|
-
find_all_mock.class.should == Dupe::Network::GetMock
|
236
|
-
find_all_mock.url_pattern.should == %r{^/book_services/authors\.xml$}
|
237
|
-
find_all_mock.mocked_response('/book_services/authors.xml').should == Dupe.find(:authors).to_xml(:root => 'authors')
|
238
|
-
|
239
|
-
find_one_mock = Dupe.network.mocks[:get].last
|
240
|
-
find_one_mock.class.should == Dupe::Network::GetMock
|
241
|
-
find_one_mock.url_pattern.should == %r{^/book_services/authors/(\d+)\.xml$}
|
242
|
-
find_one_mock.mocked_response('/book_services/authors/1.xml').should == Dupe.find(:author).to_xml(:root => 'author')
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
describe "create" do
|
247
|
-
it "should require a model name parameter" do
|
248
|
-
proc {Dupe.create}.should raise_error(ArgumentError)
|
249
|
-
proc {Dupe.create :book}.should_not raise_error(ArgumentError)
|
250
|
-
end
|
251
|
-
|
252
|
-
it "should create a model if one doesn't already exist" do
|
253
|
-
Dupe.models.should be_empty
|
254
|
-
Dupe.create :book
|
255
|
-
Dupe.models.should_not be_empty
|
256
|
-
Dupe.models[:book].should_not be_nil
|
257
|
-
Dupe.models[:book].name.should == :book
|
258
|
-
end
|
259
|
-
|
260
|
-
it "should be smart enough to singularize the model name before lookup/create" do
|
261
|
-
Dupe.define :book
|
262
|
-
Dupe.models.should_not be_empty
|
263
|
-
Dupe.models.length.should == 1
|
264
|
-
Dupe.models[:book].should_not be_nil
|
265
|
-
Dupe.create :books
|
266
|
-
Dupe.models.length.should == 1
|
267
|
-
Dupe.models[:books].should be_nil
|
268
|
-
Dupe.models[:book].should_not be_nil
|
269
|
-
Dupe.create :authors
|
270
|
-
Dupe.models.length.should == 2
|
271
|
-
Dupe.models[:author].should_not be_nil
|
272
|
-
Dupe.models[:author].name.should == :author
|
273
|
-
Dupe.models[:authors].should be_nil
|
274
|
-
end
|
275
|
-
|
276
|
-
it "should create (and return) a database record if passed a single hash" do
|
277
|
-
Dupe.define :book
|
278
|
-
Dupe.database.tables[:book].should be_empty
|
279
|
-
@book = Dupe.create :book, :title => 'test'
|
280
|
-
Dupe.database.tables[:book].should_not be_empty
|
281
|
-
Dupe.database.tables[:book].length.should == 1
|
282
|
-
Dupe.database.tables[:book].first.should == @book
|
283
|
-
end
|
284
|
-
|
285
|
-
it "should create several records if passed an array of hashes (and return an array of the records created)" do
|
286
|
-
Dupe.define :book
|
287
|
-
Dupe.database.tables[:book].should be_empty
|
288
|
-
@books = Dupe.create :books, [{:title => 'Book 1'}, {:title => 'Book 2'}]
|
289
|
-
Dupe.database.tables[:book].should_not be_empty
|
290
|
-
Dupe.database.tables[:book].length.should == 2
|
291
|
-
Dupe.database.tables[:book].first.should == @books.first
|
292
|
-
Dupe.database.tables[:book].last.should == @books.last
|
293
|
-
end
|
294
|
-
|
295
|
-
it "should symbolize hash keys to keep from duplicating column names" do
|
296
|
-
b = Dupe.create :book, 'title' => 'War And Peace', :title => 'War And Peace'
|
297
|
-
b.title.should == 'War And Peace'
|
298
|
-
b[:title].should == 'War And Peace'
|
299
|
-
b['title'].should == nil
|
300
|
-
|
301
|
-
bs = Dupe.create :books, [{:test => 2, 'test' => 2}, {:test => 4, 'test' => 4}]
|
302
|
-
bs.first.test.should == 2
|
303
|
-
bs.first[:test].should == 2
|
304
|
-
bs.first['test'].should == nil
|
305
|
-
bs.last.test.should == 4
|
306
|
-
bs.last[:test].should == 4
|
307
|
-
bs.last['test'].should == nil
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
describe "create resources with unique attributes" do
|
312
|
-
before do
|
313
|
-
Dupe.define :book do |book|
|
314
|
-
book.uniquify :title, :author, :genre
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
|
-
it "should uniquify the appropriate columns if they don't already have values" do
|
319
|
-
b = Dupe.create :book
|
320
|
-
b.title.should == "book 1 title"
|
321
|
-
b.author.should == "book 1 author"
|
322
|
-
b.genre.should == "book 1 genre"
|
323
|
-
|
324
|
-
b = Dupe.create :book, :title => 'Rooby Rocks', :isbn => 1
|
325
|
-
b.title.should == 'Rooby Rocks'
|
326
|
-
b.author.should == "book 2 author"
|
327
|
-
b.genre.should == "book 2 genre"
|
328
|
-
b.isbn.should == 1
|
329
|
-
end
|
330
|
-
end
|
331
|
-
|
332
|
-
describe "create resources that have an after_create callback" do
|
333
|
-
before do
|
334
|
-
Dupe.define :book do |book|
|
335
|
-
book.uniquify :title, :author, :genre
|
336
|
-
|
337
|
-
book.after_create do |b|
|
338
|
-
b.label = b.title.downcase.gsub(/\ +/, '-') unless b.label
|
339
|
-
end
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
|
-
it "should create a label based on the title if a label is passed in during the create call" do
|
344
|
-
b = Dupe.create :book, :title => 'Testing Testing'
|
345
|
-
b.label.should == 'testing-testing'
|
346
|
-
b = Dupe.create :book, :title => 'Testing Testing', :label => 'testbook'
|
347
|
-
b.label.should == 'testbook'
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
describe "find" do
|
352
|
-
before do
|
353
|
-
Dupe.define :book
|
354
|
-
@book = Dupe.create :book
|
355
|
-
end
|
356
|
-
|
357
|
-
it "should require a model name parameter" do
|
358
|
-
proc { Dupe.find }.should raise_error(ArgumentError)
|
359
|
-
end
|
360
|
-
|
361
|
-
it "should require the model to exist" do
|
362
|
-
proc { Dupe.find :unknown_models }.should raise_error(Dupe::Database::TableDoesNotExistError)
|
363
|
-
end
|
364
|
-
|
365
|
-
it "should return an array if you ask for a plural model (e.g., Dupe.find :books)" do
|
366
|
-
result = Dupe.find :books
|
367
|
-
result.should be_kind_of(Array)
|
368
|
-
result.should_not be_empty
|
369
|
-
result.length.should == 1
|
370
|
-
result.first.should == @book
|
371
|
-
end
|
372
|
-
|
373
|
-
it "should return a single record (or nil) if you ask for a singular model (e.g., Dupe.find :book)" do
|
374
|
-
result = Dupe.find :book
|
375
|
-
result.should be_kind_of(Dupe::Database::Record)
|
376
|
-
result.should == @book
|
377
|
-
|
378
|
-
result = Dupe.find(:book) {|b| false}
|
379
|
-
result.should be_nil
|
380
|
-
end
|
381
|
-
end
|
382
|
-
|
383
|
-
describe "debug" do
|
384
|
-
it "should default to false" do
|
385
|
-
Dupe.debug.should == false
|
386
|
-
end
|
387
|
-
|
388
|
-
it "should allow you to set it to true" do
|
389
|
-
Dupe.debug = true
|
390
|
-
Dupe.debug.should == true
|
391
|
-
end
|
392
|
-
|
393
|
-
it "should persist across a Dupe.reset" do
|
394
|
-
Dupe.debug = true
|
395
|
-
Dupe.debug.should == true
|
396
|
-
Dupe.reset
|
397
|
-
Dupe.debug.should == true
|
398
|
-
end
|
399
|
-
end
|
400
|
-
|
401
|
-
describe "stub" do
|
402
|
-
it ": when called with only a count and a model_name, it should generate that many blank (id-only) records" do
|
403
|
-
Dupe.database.tables[:author].should be_nil
|
404
|
-
authors = Dupe.stub 20, :authors
|
405
|
-
authors.length.should == 20
|
406
|
-
Dupe.database.tables[:author].length.should == 20
|
407
|
-
authors.collect(&:id).should == (1..20).to_a
|
408
|
-
end
|
409
|
-
|
410
|
-
it "should accept procs on stubs" do
|
411
|
-
Dupe.database.tables[:author].should be_nil
|
412
|
-
authors =
|
413
|
-
Dupe.stub(
|
414
|
-
2,
|
415
|
-
:authors,
|
416
|
-
:like => {
|
417
|
-
:name => proc {|n| "Author #{n}"},
|
418
|
-
:bio => proc {|n| "Author #{n}'s bio"}
|
419
|
-
}
|
420
|
-
)
|
421
|
-
authors.first.name.should == "Author 1"
|
422
|
-
authors.first.bio.should == "Author 1's bio"
|
423
|
-
authors.last.name.should == "Author 2"
|
424
|
-
authors.last.bio.should == "Author 2's bio"
|
425
|
-
Dupe.database.tables[:author].length.should == 2
|
426
|
-
end
|
427
|
-
|
428
|
-
it "shouldn't care if the model_name is singular or plural" do
|
429
|
-
Dupe.database.tables.should be_empty
|
430
|
-
Dupe.stub 5, :author
|
431
|
-
Dupe.database.tables.should_not be_empty
|
432
|
-
Dupe.database.tables.length.should == 1
|
433
|
-
Dupe.database.tables[:author].length.should == 5
|
434
|
-
Dupe.stub 5, :authors
|
435
|
-
Dupe.database.tables[:author].length.should == 10
|
436
|
-
Dupe.database.tables.length.should == 1
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
|
-
describe "find_or_create" do
|
441
|
-
it "should require a model name" do
|
442
|
-
proc { Dupe.find_or_create }.should raise_error(ArgumentError)
|
443
|
-
end
|
444
|
-
|
445
|
-
it "should find a result if one exists" do
|
446
|
-
b = Dupe.create :book, :title => 'Rooby', :serial_number => 21345
|
447
|
-
found_book = Dupe.find_or_create :book, :title => 'Rooby', :serial_number => 21345
|
448
|
-
b.should === found_book
|
449
|
-
|
450
|
-
g = Dupe.create :genre, :name => 'Science Fiction', :label => 'sci-fi'
|
451
|
-
found_genre = Dupe.find_or_create :genre, :name => 'Science Fiction', :label => 'sci-fi'
|
452
|
-
g.should === found_genre
|
453
|
-
end
|
454
|
-
|
455
|
-
it "should create a result if one does not exist" do
|
456
|
-
Dupe.database.tables.should be_empty
|
457
|
-
author = Dupe.find_or_create :author, :name => 'Matt Parker', :age => 27, :label => 'matt-parker'
|
458
|
-
Dupe.database.tables.should_not be_empty
|
459
|
-
author.should === (Dupe.find(:author) {|a| a.label == 'matt-parker' && a.age == 27})
|
460
|
-
end
|
461
|
-
|
462
|
-
it "should return an array of results if passed a plural model name" do
|
463
|
-
books = Dupe.stub 20, :books, :like => { :title => proc {|n| "book ##{n} title"} }
|
464
|
-
bs = Dupe.find_or_create :books
|
465
|
-
books.should == bs
|
466
|
-
end
|
467
|
-
|
468
|
-
it "should create and return an array of results if passed a plural model name for which no matching records exist" do
|
469
|
-
Dupe.database.tables.should be_empty
|
470
|
-
books = Dupe.find_or_create :books, :author => 'test'
|
471
|
-
Dupe.database.tables.length.should == 1
|
472
|
-
books.should be_kind_of(Array)
|
473
|
-
books.should == Dupe.find(:books)
|
474
|
-
end
|
475
|
-
|
476
|
-
end
|
477
|
-
|
478
|
-
describe "creating resources should not change definitions (regression test)" do
|
479
|
-
before do
|
480
|
-
Dupe.define :book do |book|
|
481
|
-
book.authors []
|
482
|
-
book.genre do
|
483
|
-
Dupe.find_or_create :genre, :name => 'Sci-fi'
|
484
|
-
end
|
485
|
-
end
|
486
|
-
end
|
487
|
-
|
488
|
-
it "should not add a record to the definition when the default value is an array" do
|
489
|
-
b = Dupe.create :book
|
490
|
-
a = Dupe.create :author
|
491
|
-
b.authors << a
|
492
|
-
b.authors.include?(a).should be_true
|
493
|
-
b2 = Dupe.create :book
|
494
|
-
b2.authors.should be_empty
|
495
|
-
end
|
496
|
-
|
497
|
-
it "should not dupe the value returned by a lazy attribute" do
|
498
|
-
b = Dupe.create :book
|
499
|
-
b2 = Dupe.create :book
|
500
|
-
b.genre.should == b2.genre
|
501
|
-
b.genre.name = 'Science Fiction'
|
502
|
-
b2.genre.name.should == 'Science Fiction'
|
503
|
-
end
|
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
|
522
|
-
end
|