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.
- data/README.rdoc +390 -147
- data/lib/dupe/active_resource_extensions.rb +25 -0
- data/lib/dupe/attribute_template.rb +71 -0
- data/lib/dupe/cucumber_hooks.rb +15 -7
- data/lib/dupe/custom_mocks.rb +102 -0
- data/lib/dupe/database.rb +51 -0
- data/lib/dupe/dupe.rb +359 -372
- data/lib/dupe/log.rb +38 -0
- data/lib/dupe/mock.rb +50 -0
- data/lib/dupe/model.rb +55 -0
- data/lib/dupe/network.rb +38 -0
- data/lib/dupe/record.rb +35 -56
- data/lib/dupe/rest_validation.rb +16 -0
- data/lib/dupe/schema.rb +36 -0
- data/lib/dupe/sequence.rb +11 -10
- data/lib/dupe/singular_plural_detection.rb +9 -0
- data/lib/dupe/string.rb +6 -8
- data/lib/dupe/symbol.rb +3 -0
- data/lib/dupe.rb +13 -12
- data/rails_generators/dupe/templates/custom_mocks.rb +4 -34
- data/rails_generators/dupe/templates/dupe_setup.rb +3 -23
- data/spec/lib_specs/active_resource_extensions_spec.rb +29 -0
- data/spec/lib_specs/attribute_template_spec.rb +173 -0
- data/spec/lib_specs/database_spec.rb +133 -0
- data/spec/lib_specs/dupe_spec.rb +307 -0
- data/spec/lib_specs/log_spec.rb +78 -0
- data/spec/lib_specs/logged_request_spec.rb +22 -0
- data/spec/lib_specs/mock_definitions_spec.rb +32 -0
- data/spec/lib_specs/mock_spec.rb +67 -0
- data/spec/lib_specs/model_spec.rb +90 -0
- data/spec/lib_specs/network_spec.rb +77 -0
- data/spec/lib_specs/record_spec.rb +70 -0
- data/spec/lib_specs/rest_validation_spec.rb +17 -0
- data/spec/lib_specs/schema_spec.rb +90 -0
- data/spec/lib_specs/sequence_spec.rb +26 -0
- data/spec/lib_specs/string_spec.rb +31 -0
- data/spec/lib_specs/symbol_spec.rb +17 -0
- data/spec/spec_helper.rb +2 -5
- metadata +29 -7
- data/lib/dupe/active_resource.rb +0 -135
- data/lib/dupe/attribute.rb +0 -17
- data/lib/dupe/configuration.rb +0 -20
- data/lib/dupe/mock_service_response.rb +0 -55
- 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
|
data/spec/lib_specs/dupe_spec.rb
CHANGED
@@ -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
|