dupe 0.3.7 → 0.4.0

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.
Files changed (44) hide show
  1. data/README.rdoc +390 -147
  2. data/lib/dupe/active_resource_extensions.rb +25 -0
  3. data/lib/dupe/attribute_template.rb +71 -0
  4. data/lib/dupe/cucumber_hooks.rb +15 -7
  5. data/lib/dupe/custom_mocks.rb +102 -0
  6. data/lib/dupe/database.rb +51 -0
  7. data/lib/dupe/dupe.rb +359 -372
  8. data/lib/dupe/log.rb +38 -0
  9. data/lib/dupe/mock.rb +50 -0
  10. data/lib/dupe/model.rb +55 -0
  11. data/lib/dupe/network.rb +38 -0
  12. data/lib/dupe/record.rb +35 -56
  13. data/lib/dupe/rest_validation.rb +16 -0
  14. data/lib/dupe/schema.rb +36 -0
  15. data/lib/dupe/sequence.rb +11 -10
  16. data/lib/dupe/singular_plural_detection.rb +9 -0
  17. data/lib/dupe/string.rb +6 -8
  18. data/lib/dupe/symbol.rb +3 -0
  19. data/lib/dupe.rb +13 -12
  20. data/rails_generators/dupe/templates/custom_mocks.rb +4 -34
  21. data/rails_generators/dupe/templates/dupe_setup.rb +3 -23
  22. data/spec/lib_specs/active_resource_extensions_spec.rb +29 -0
  23. data/spec/lib_specs/attribute_template_spec.rb +173 -0
  24. data/spec/lib_specs/database_spec.rb +133 -0
  25. data/spec/lib_specs/dupe_spec.rb +307 -0
  26. data/spec/lib_specs/log_spec.rb +78 -0
  27. data/spec/lib_specs/logged_request_spec.rb +22 -0
  28. data/spec/lib_specs/mock_definitions_spec.rb +32 -0
  29. data/spec/lib_specs/mock_spec.rb +67 -0
  30. data/spec/lib_specs/model_spec.rb +90 -0
  31. data/spec/lib_specs/network_spec.rb +77 -0
  32. data/spec/lib_specs/record_spec.rb +70 -0
  33. data/spec/lib_specs/rest_validation_spec.rb +17 -0
  34. data/spec/lib_specs/schema_spec.rb +90 -0
  35. data/spec/lib_specs/sequence_spec.rb +26 -0
  36. data/spec/lib_specs/string_spec.rb +31 -0
  37. data/spec/lib_specs/symbol_spec.rb +17 -0
  38. data/spec/spec_helper.rb +2 -5
  39. metadata +29 -7
  40. data/lib/dupe/active_resource.rb +0 -135
  41. data/lib/dupe/attribute.rb +0 -17
  42. data/lib/dupe/configuration.rb +0 -20
  43. data/lib/dupe/mock_service_response.rb +0 -55
  44. data/spec/lib_specs/dupe_record_spec.rb +0 -57
@@ -0,0 +1,173 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Dupe::Model::Schema::AttributeTemplate do
4
+ describe "new" do
5
+ it "should require a name" do
6
+ proc {
7
+ Dupe::Model::Schema::AttributeTemplate.new
8
+ }.should raise_error(ArgumentError)
9
+ end
10
+
11
+ it "should set the name if one is passed to it" do
12
+ attribute = Dupe::Model::Schema::AttributeTemplate.new(:title)
13
+ attribute.name.should == :title
14
+ end
15
+
16
+ it "should set a default value if one is passed to it" do
17
+ attribute =
18
+ Dupe::Model::Schema::AttributeTemplate.new(
19
+ :title,
20
+ :default => 'Untitled'
21
+ )
22
+ attribute.default.should == 'Untitled'
23
+ end
24
+
25
+ it "should verify that the transformer is a proc" do
26
+ proc {
27
+ attribute =
28
+ Dupe::Model::Schema::AttributeTemplate.new(
29
+ :title,
30
+ :default => nil,
31
+ :transformer => 'not a proc'
32
+ )
33
+ }.should raise_error(
34
+ ArgumentError,
35
+ "Your transformer must be a kind of proc."
36
+ )
37
+ end
38
+
39
+ it "should verify that the transformer requires a single parameter" do
40
+ proc {
41
+ attribute = Dupe::Model::Schema::AttributeTemplate.new(
42
+ :title,
43
+ :default => nil,
44
+ :transformer => proc {'test'}
45
+ )
46
+ }.should raise_error(
47
+ ArgumentError,
48
+ "Your transformer must accept a parameter."
49
+ )
50
+ end
51
+
52
+ it "should set the transformer if one is passed" do
53
+ transformer = proc {|dont_care| }
54
+ attribute = Dupe::Model::Schema::AttributeTemplate.new(
55
+ :title,
56
+ :default => nil,
57
+ :transformer => transformer
58
+ )
59
+ attribute.transformer.should == transformer
60
+ end
61
+ end
62
+
63
+ describe "generate" do
64
+ describe "on an attribute without a default value and without a transformer" do
65
+ before do
66
+ @attribute = Dupe::Model::Schema::AttributeTemplate.new(:title)
67
+ end
68
+
69
+ it "should generate a key with the name of the attribute" do
70
+ key, value = @attribute.generate
71
+ key.should == @attribute.name
72
+ end
73
+
74
+ describe "when passed nothing" do
75
+ it "should generate a nil value" do
76
+ key, value = @attribute.generate
77
+ value.should == nil
78
+ end
79
+ end
80
+
81
+ describe "when passed a value" do
82
+ it "should generate a value equal to the value passed in" do
83
+ key, value = @attribute.generate('test')
84
+ value.should == 'test'
85
+ end
86
+ end
87
+ end
88
+
89
+ describe "on an attribute with a default value but without a transformer" do
90
+ before do
91
+ @attribute = Dupe::Model::Schema::AttributeTemplate.new(:title, :default => 'Untitled')
92
+ end
93
+
94
+ it "should generate a key with the name of the attribute" do
95
+ key, value = @attribute.generate
96
+ key.should == @attribute.name
97
+ end
98
+
99
+ describe "when passed nothing" do
100
+ it "should generate a value equal to the default value" do
101
+ key, value = @attribute.generate
102
+ value.should == @attribute.default
103
+ end
104
+ end
105
+
106
+ describe "when passed a value" do
107
+ it "should generate a value equal to the value passed in" do
108
+ title = '2001: A Space Odyssey'
109
+ key, value = @attribute.generate title
110
+ value.should == title
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "on an attribute with a default value that is a proc" do
116
+ before do
117
+ @default_value = proc { 'knock' * 3 }
118
+ @attribute = Dupe::Model::Schema::AttributeTemplate.new(:title, :default => @default_value)
119
+ end
120
+
121
+ it "should generate a key with the name of the attribute" do
122
+ key, value = @attribute.generate
123
+ key.should == @attribute.name
124
+ end
125
+
126
+ describe "when passed nothing" do
127
+ it "should return the value of the default_value proc" do
128
+ key, value = @attribute.generate
129
+ value.should == @default_value.call
130
+ end
131
+ end
132
+
133
+ describe "when passed a value" do
134
+ it "should generate a value equal to the value passed in" do
135
+ title = 'Rooby'
136
+ key, value = @attribute.generate title
137
+ value.should == title
138
+ end
139
+ end
140
+
141
+ end
142
+
143
+ describe "on an attribute with a transformer" do
144
+ before do
145
+ @transformer = proc {|dont_care| 'test'}
146
+ @attribute = Dupe::Model::Schema::AttributeTemplate.new(
147
+ :title,
148
+ :default => nil,
149
+ :transformer => @transformer
150
+ )
151
+ end
152
+
153
+ it "should generate a key with the name of the attribute" do
154
+ key, value = @attribute.generate
155
+ key.should == @attribute.name
156
+ end
157
+
158
+ describe "when passed nothing" do
159
+ it "should generate a value equal to the default" do
160
+ key, value = @attribute.generate
161
+ value.should == @attribute.default
162
+ end
163
+ end
164
+
165
+ describe "when passed a value" do
166
+ it "should generate a value equal to the value returned by the transformer" do
167
+ key, value = @attribute.generate 'blah'
168
+ value.should == @transformer.call('blah')
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,133 @@
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 "insert" do
20
+ before do
21
+ Dupe.define :book
22
+ @book = Dupe.models[:book].create :title => 'test'
23
+ @database = Dupe::Database.new
24
+ end
25
+
26
+ it "should require a record" do
27
+ proc {@database.insert}.should raise_error(ArgumentError)
28
+ proc {
29
+ @database.insert 'not a Dupe::Database::Record object'
30
+ }.should raise_error(
31
+ ArgumentError,
32
+ "You may only insert well-defined Dupe::Database::Record objects"
33
+ )
34
+ proc {
35
+ @database.insert Dupe::Database::Record.new
36
+ }.should raise_error(
37
+ ArgumentError,
38
+ "You may only insert well-defined Dupe::Database::Record objects"
39
+ )
40
+ proc {@database.insert @book}.should_not raise_error
41
+ end
42
+
43
+ it "should create a new table if one does not already exist upon insert" do
44
+ @database.tables.should be_empty
45
+ @database.insert @book
46
+ @database.tables[:book].should_not be_nil
47
+ @database.tables[:book].should be_kind_of(Array)
48
+ @database.tables[:book].should_not be_empty
49
+ @database.tables[:book].first.should_not be_nil
50
+ @database.tables[:book].first.should == @book
51
+ end
52
+ end
53
+
54
+ describe "select" do
55
+ before do
56
+ Dupe.define :book
57
+ @book = Dupe.models[:book].create :title => 'test'
58
+ @database = Dupe::Database.new
59
+ @database.insert @book
60
+ end
61
+
62
+ it "should require a valid model name" do
63
+ proc { @database.select }.should raise_error(ArgumentError)
64
+ proc { @database.select :undefined_model }.should raise_error(
65
+ Dupe::Database::TableDoesNotExistError,
66
+ "The table ':undefined_model' does not exist."
67
+ )
68
+ proc { @database.select :book }.should_not raise_error
69
+ end
70
+
71
+ it "should accept a conditions proc" do
72
+ proc { @database.select :book, proc {|c| true} }.should_not raise_error
73
+ end
74
+
75
+ it "should verify that the conditions proc accepts a single parameter" do
76
+ proc { @database.select :book, proc {true} }.should raise_error(
77
+ Dupe::Database::InvalidQueryError,
78
+ "There was a problem with your select conditions. Please consult the API."
79
+ )
80
+ end
81
+
82
+ it "should find the requested items and return an array" do
83
+ results = @database.select :book, proc {|b| b.title == 'test' }
84
+ results.should be_kind_of(Array)
85
+ results.should_not be_empty
86
+ results.first.__model__.should == Dupe.models[:book]
87
+ results.first.__model__.name.should == :book
88
+ results.first.title.should == 'test'
89
+ results.first.id.should == 1
90
+ end
91
+ end
92
+
93
+ describe "create_table" do
94
+ it "should create a database table if one doesn't already exist" do
95
+ @database = Dupe::Database.new
96
+ @database.tables.length.should == 0
97
+ @database.tables[:book].should be_nil
98
+ @database.create_table 'book'
99
+ @database.tables[:book].should_not be_nil
100
+ @database.tables.length.should == 1
101
+ @database.tables[:book].should == []
102
+
103
+ # make sure it doesn't overwrite a table that already exists
104
+ m = Dupe::Model.new :book
105
+ record = m.create
106
+ @database.insert record
107
+ @database.tables[:book].length.should == 1
108
+ @database.tables[:book].first.should == record
109
+ @database.create_table :book
110
+ @database.tables[:book].length.should == 1
111
+ @database.tables[:book].first.should == record
112
+ end
113
+ end
114
+
115
+ describe "truncate_tables" do
116
+ it "should remove all records from all tables" do
117
+ Dupe.create :book
118
+ Dupe.create :author
119
+ Dupe.create :publisher
120
+ Dupe.database.tables.length.should == 3
121
+ Dupe.database.tables[:book].length.should == 1
122
+ Dupe.database.tables[:author].length.should == 1
123
+ Dupe.database.tables[:publisher].length.should == 1
124
+ Dupe.database.truncate_tables
125
+ Dupe.database.tables.length.should == 3
126
+ Dupe.database.tables[:book].length.should == 0
127
+ Dupe.database.tables[:author].length.should == 0
128
+ Dupe.database.tables[:publisher].length.should == 0
129
+ end
130
+ end
131
+
132
+
133
+ end
@@ -1,4 +1,311 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe Dupe do
4
+ before do
5
+ Dupe.reset
6
+ end
7
+
8
+ describe "reset" do
9
+ it "should call reset_models, reset_database, and reset_network" do
10
+ Dupe.should_receive(:reset_models).once
11
+ Dupe.should_receive(:reset_database).once
12
+ Dupe.should_receive(:reset_network).once
13
+ Dupe.reset
14
+ end
15
+ end
16
+
17
+ describe "reset_models" do
18
+ it "should reset @models to an empty hash" do
19
+ Dupe.models.length.should == 0
20
+ Dupe.define :book do |attrs|
21
+ attrs.title
22
+ attrs.author
23
+ end
24
+ Dupe.models.length.should == 1
25
+ Dupe.reset_models
26
+ Dupe.models.should == {}
27
+ end
28
+ end
29
+
30
+ describe "reset_database" do
31
+ it "should clear out the database" do
32
+ Dupe.define :book
33
+ Dupe.define :author
34
+ Dupe.database.tables.length.should == 2
35
+ Dupe.reset_database
36
+ Dupe.database.tables.should be_empty
37
+ end
38
+ end
39
+
40
+ describe "reset_network" do
41
+ it "should clear out the network" do
42
+ Dupe.create :book
43
+ Dupe.network.mocks.values.inject(false) {|b,v| b || !v.empty?}.should == true
44
+ Dupe.network.mocks[:get].should_not be_empty
45
+ Dupe.reset_network
46
+ Dupe.network.mocks.values.inject(false) {|b,v| b || !v.empty?}.should == false
47
+ end
48
+ end
49
+
50
+ describe "define" do
51
+
52
+ # Dupe.define :model_name
53
+ it "should accept a single symbol parameter" do
54
+ proc {
55
+ Dupe.define :book
56
+ }.should_not raise_error
57
+ end
58
+
59
+ # Dupe.define :model_name do |attrs|
60
+ # attrs.attr1 'Default Value'
61
+ # attrs.attr2 do |value|
62
+ # 'transformed value'
63
+ # end
64
+ # end
65
+ it "should accept a symbol plus a block (that accepts a single parameter)" do
66
+ proc {
67
+ Dupe.define :book do
68
+ end
69
+ }.should raise_error(
70
+ ArgumentError,
71
+ "Unknown Dupe.define parameter format. Please consult the API" +
72
+ " for information on how to use Dupe.define"
73
+ )
74
+
75
+ proc {
76
+ Dupe.define :book do |attrs|
77
+ attrs.author 'Anon'
78
+ attrs.title 'Untitled'
79
+ end
80
+ }.should_not raise_error
81
+ end
82
+
83
+ it "should create a model and a schema with the desired definition" do
84
+ Dupe.define :book do |attrs|
85
+ attrs.author 'Anon'
86
+ attrs.genre do
87
+ 'Unknown' + rand(2).to_s
88
+ end
89
+ attrs.title 'Untitled' do |value|
90
+ "transformed #{value}"
91
+ end
92
+ end
93
+
94
+ Dupe.models.length.should == 1
95
+ Dupe.models[:book].schema.attribute_templates[:author].name.should == :author
96
+ Dupe.models[:book].schema.attribute_templates[:author].default.should == 'Anon'
97
+ Dupe.models[:book].schema.attribute_templates[:title].name.should == :title
98
+ Dupe.models[:book].schema.attribute_templates[:title].default.should == 'Untitled'
99
+ Dupe.models[:book].schema.attribute_templates[:title].transformer.should be_kind_of(Proc)
100
+ Dupe.models[:book].schema.attribute_templates[:title].transformer.call('value').should == 'transformed value'
101
+ Dupe.models[:book].schema.attribute_templates[:genre].name.should == :genre
102
+ Dupe.models[:book].schema.attribute_templates[:genre].transformer.should be_nil
103
+ Dupe.models[:book].schema.attribute_templates[:genre].default.should be_kind_of(Proc)
104
+ Dupe.models[:book].schema.attribute_templates[:genre].default.call.should match(/^Unknown\d$/)
105
+ end
106
+
107
+ it "should add a table to the database" do
108
+ Dupe.database.tables.length.should == 0
109
+ Dupe.database.tables[:book].should be_nil
110
+ Dupe.define :book
111
+ Dupe.database.tables.length.should == 1
112
+ Dupe.database.tables[:book].should_not be_nil
113
+ Dupe.database.tables[:book].should == []
114
+ end
115
+
116
+ it "should add find(:all) and find(<id>) mocks to the database" do
117
+ Dupe.network.mocks[:get].should be_empty
118
+ Dupe.create :book
119
+ Dupe.network.mocks[:get].should_not be_empty
120
+ Dupe.network.mocks[:get].length.should == 2
121
+
122
+ find_all_mock = Dupe.network.mocks[:get].first
123
+ find_all_mock.verb.should == :get
124
+ find_all_mock.url_pattern.should == %r{/books\.xml$}
125
+ find_all_mock.mocked_response('/books.xml').should == Dupe.find(:books).to_xml(:root => 'books')
126
+
127
+ find_one_mock = Dupe.network.mocks[:get].last
128
+ find_one_mock.verb.should == :get
129
+ find_one_mock.url_pattern.should == %r{/books/(\d+)\.xml$}
130
+ find_one_mock.mocked_response('/books/1.xml').should == Dupe.find(:book).to_xml(:root => 'book')
131
+ end
132
+
133
+ end
134
+
135
+ describe "create" do
136
+ it "should require a model name parameter" do
137
+ proc {Dupe.create}.should raise_error(ArgumentError)
138
+ proc {Dupe.create :book}.should_not raise_error(ArgumentError)
139
+ end
140
+
141
+ it "should create a model if one doesn't already exist" do
142
+ Dupe.models.should be_empty
143
+ Dupe.create :book
144
+ Dupe.models.should_not be_empty
145
+ Dupe.models[:book].should_not be_nil
146
+ Dupe.models[:book].name.should == :book
147
+ end
148
+
149
+ it "should be smart enough to singularize the model name before lookup/create" do
150
+ Dupe.define :book
151
+ Dupe.models.should_not be_empty
152
+ Dupe.models.length.should == 1
153
+ Dupe.models[:book].should_not be_nil
154
+ Dupe.create :books
155
+ Dupe.models.length.should == 1
156
+ Dupe.models[:books].should be_nil
157
+ Dupe.models[:book].should_not be_nil
158
+ Dupe.create :authors
159
+ Dupe.models.length.should == 2
160
+ Dupe.models[:author].should_not be_nil
161
+ Dupe.models[:author].name.should == :author
162
+ Dupe.models[:authors].should be_nil
163
+ end
164
+
165
+ it "should create (and return) a database record if passed a single hash" do
166
+ Dupe.define :book
167
+ Dupe.database.tables[:book].should be_empty
168
+ @book = Dupe.create :book, :title => 'test'
169
+ Dupe.database.tables[:book].should_not be_empty
170
+ Dupe.database.tables[:book].length.should == 1
171
+ Dupe.database.tables[:book].first.should == @book
172
+ end
173
+
174
+ it "should create several records if passed an array of hashes (and return an array of the records created)" do
175
+ Dupe.define :book
176
+ Dupe.database.tables[:book].should be_empty
177
+ @books = Dupe.create :books, [{:title => 'Book 1'}, {:title => 'Book 2'}]
178
+ Dupe.database.tables[:book].should_not be_empty
179
+ Dupe.database.tables[:book].length.should == 2
180
+ Dupe.database.tables[:book].first.should == @books.first
181
+ Dupe.database.tables[:book].last.should == @books.last
182
+ end
183
+ end
184
+
185
+ describe "find" do
186
+ before do
187
+ Dupe.define :book
188
+ @book = Dupe.create :book
189
+ end
190
+
191
+ it "should require a model name parameter" do
192
+ proc { Dupe.find }.should raise_error(ArgumentError)
193
+ end
194
+
195
+ it "should require the model to exist" do
196
+ proc { Dupe.find :unknown_models }.should raise_error(Dupe::Database::TableDoesNotExistError)
197
+ end
198
+
199
+ it "should return an array if you ask for a plural model (e.g., Dupe.find :books)" do
200
+ result = Dupe.find :books
201
+ result.should be_kind_of(Array)
202
+ result.should_not be_empty
203
+ result.length.should == 1
204
+ result.first.should == @book
205
+ end
206
+
207
+ it "should return a single record (or nil) if you ask for a singular model (e.g., Dupe.find :book)" do
208
+ result = Dupe.find :book
209
+ result.should be_kind_of(Dupe::Database::Record)
210
+ result.should == @book
211
+
212
+ result = Dupe.find(:book) {|b| false}
213
+ result.should be_nil
214
+ end
215
+ end
216
+
217
+ describe "debug" do
218
+ it "should default to false" do
219
+ Dupe.debug.should == false
220
+ end
221
+
222
+ it "should allow you to set it to true" do
223
+ Dupe.debug = true
224
+ Dupe.debug.should == true
225
+ end
226
+
227
+ it "should persist across a Dupe.reset" do
228
+ Dupe.debug = true
229
+ Dupe.debug.should == true
230
+ Dupe.reset
231
+ Dupe.debug.should == true
232
+ end
233
+ end
234
+
235
+ describe "stub" do
236
+ it ": when called with only a count and a model_name, it should generate that many blank (id-only) records" do
237
+ Dupe.database.tables[:author].should be_nil
238
+ authors = Dupe.stub 20, :authors
239
+ authors.length.should == 20
240
+ Dupe.database.tables[:author].length.should == 20
241
+ authors.collect(&:id).should == (1..20).to_a
242
+ end
243
+
244
+ it "should accept procs on stubs" do
245
+ Dupe.database.tables[:author].should be_nil
246
+ authors =
247
+ Dupe.stub(
248
+ 2,
249
+ :authors,
250
+ :like => {
251
+ :name => proc {|n| "Author #{n}"},
252
+ :bio => proc {|n| "Author #{n}'s bio"}
253
+ }
254
+ )
255
+ authors.first.name.should == "Author 1"
256
+ authors.first.bio.should == "Author 1's bio"
257
+ authors.last.name.should == "Author 2"
258
+ authors.last.bio.should == "Author 2's bio"
259
+ Dupe.database.tables[:author].length.should == 2
260
+ end
261
+
262
+ it "shouldn't care if the model_name is singular or plural" do
263
+ Dupe.database.tables.should be_empty
264
+ Dupe.stub 5, :author
265
+ Dupe.database.tables.should_not be_empty
266
+ Dupe.database.tables.length.should == 1
267
+ Dupe.database.tables[:author].length.should == 5
268
+ Dupe.stub 5, :authors
269
+ Dupe.database.tables[:author].length.should == 10
270
+ Dupe.database.tables.length.should == 1
271
+ end
272
+ end
273
+
274
+ describe "find_or_create" do
275
+ it "should require a model name" do
276
+ proc { Dupe.find_or_create }.should raise_error(ArgumentError)
277
+ end
278
+
279
+ it "should find a result if one exists" do
280
+ b = Dupe.create :book, :title => 'Rooby', :serial_number => 21345
281
+ found_book = Dupe.find_or_create :book, :title => 'Rooby', :serial_number => 21345
282
+ b.should === found_book
283
+
284
+ g = Dupe.create :genre, :name => 'Science Fiction', :label => 'sci-fi'
285
+ found_genre = Dupe.find_or_create :genre, :name => 'Science Fiction', :label => 'sci-fi'
286
+ g.should === found_genre
287
+ end
288
+
289
+ it "should create a result if one does not exist" do
290
+ Dupe.database.tables.should be_empty
291
+ author = Dupe.find_or_create :author, :name => 'Matt Parker', :age => 27, :label => 'matt-parker'
292
+ Dupe.database.tables.should_not be_empty
293
+ author.should === (Dupe.find(:author) {|a| a.label == 'matt-parker' && a.age == 27})
294
+ end
295
+
296
+ it "should return an array of results if passed a plural model name" do
297
+ books = Dupe.stub 20, :books, :like => { :title => proc {|n| "book ##{n} title"} }
298
+ bs = Dupe.find_or_create :books
299
+ books.should == bs
300
+ end
301
+
302
+ it "should create and return an array of results if passed a plural model name for which no matching records exist" do
303
+ Dupe.database.tables.should be_empty
304
+ books = Dupe.find_or_create :books, :author => 'test'
305
+ Dupe.database.tables.length.should == 1
306
+ books.should be_kind_of(Array)
307
+ books.should == Dupe.find(:books)
308
+ end
309
+
310
+ end
4
311
  end
@@ -0,0 +1,78 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Dupe::Network::Log do
4
+ before do
5
+ Dupe.reset
6
+ end
7
+
8
+ describe "##new" do
9
+ it "should initialize the request entries to an empty array" do
10
+ log = Dupe::Network::Log.new
11
+ log.requests.should == []
12
+ end
13
+ end
14
+
15
+ describe "#add_request" do
16
+ before do
17
+ @log = Dupe::Network::Log.new
18
+ end
19
+
20
+ it "should require a valid HTTP verb" do
21
+ proc {
22
+ @log.add_request :invalid_http_verb, '/some_url'
23
+ }.should raise_error(Dupe::Network::UnknownRestVerbError)
24
+ proc {
25
+ Dupe::Network::VERBS.each do |verb|
26
+ @log.add_request verb, '/some_url'
27
+ end
28
+ }.should_not raise_error
29
+ end
30
+
31
+ it "should require a url" do
32
+ proc {
33
+ @log.add_request :get
34
+ }.should raise_error(ArgumentError)
35
+ proc {
36
+ @log.add_request :get, '/a_url'
37
+ }.should_not raise_error
38
+ end
39
+
40
+ it "should add a Dupe::Network::Log::MockedRequest to requests" do
41
+ @log.requests.should be_empty
42
+ path = '/translate?q=hola&from=spanish&to=english'
43
+ response_body = 'hello'
44
+ @log.add_request :get, path, response_body
45
+ @log.requests.should_not be_empty
46
+ @log.requests.length.should == 1
47
+ logged_request = @log.requests.first
48
+ logged_request.should be_kind_of(Dupe::Network::Log::Request)
49
+ logged_request.verb.should == :get
50
+ logged_request.path.should == path
51
+ logged_request.response_body.should == response_body
52
+ end
53
+ end
54
+
55
+ describe "#pretty_print" do
56
+ before do
57
+ @log = Dupe::Network::Log.new
58
+ @log.add_request :get, '/knock-knock', "who's there?"
59
+ end
60
+ it "should return a formatted list of mocked requests" do
61
+ @log.pretty_print.should ==
62
+ "Logged Requests:\n" +
63
+ " Request: GET /knock-knock\n" +
64
+ " Response:\n" +
65
+ " who's there?\n\n"
66
+ end
67
+ end
68
+
69
+ describe "#reset" do
70
+ it "should clear out all logged requests" do
71
+ @log = Dupe::Network::Log.new
72
+ @log.add_request :get, '/knock-knock', "who's there?"
73
+ @log.requests.should_not be_empty
74
+ @log.reset
75
+ @log.requests.should be_empty
76
+ end
77
+ end
78
+ end