dupe 0.3.7 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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