rdo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,220 @@
1
+ require "spec_helper"
2
+
3
+ describe RDO::Connection do
4
+ after(:each) { RDO::Connection.drivers.clear }
5
+
6
+ describe ".register_driver" do
7
+ before(:each) do
8
+ RDO::Connection.register_driver(:bob, RDO::Driver)
9
+ end
10
+
11
+ it "registers a driver name for a driver class" do
12
+ RDO::Connection.drivers["bob"].should == RDO::Driver
13
+ end
14
+ end
15
+
16
+ describe "#initialize" do
17
+ let(:driver) { double(:driver, open: true) }
18
+ let(:driver_class) { double(new: driver) }
19
+
20
+ before(:each) { RDO::Connection.register_driver(:test, driver_class) }
21
+
22
+ context "with a connection uri string" do
23
+ context "for a registered driver" do
24
+ it "instantiates the driver" do
25
+ driver_class.should_receive(:new).and_return(driver)
26
+ RDO::Connection.new("test://whatever")
27
+ end
28
+
29
+ it "converts the uri to an options hash" do
30
+ driver_class.should_receive(:new).
31
+ with(hash_including(driver: "test")).
32
+ and_return(driver)
33
+
34
+ RDO::Connection.new("test://whatever")
35
+ end
36
+
37
+ it "parses the host name" do
38
+ driver_class.should_receive(:new).
39
+ with(hash_including(host: "whatever")).
40
+ and_return(driver)
41
+
42
+ RDO::Connection.new("test://whatever:3456")
43
+ end
44
+
45
+ it "parses the username" do
46
+ driver_class.should_receive(:new).
47
+ with(hash_including(user: "bob")).
48
+ and_return(driver)
49
+
50
+ RDO::Connection.new("test://bob:@whatever:3456")
51
+ end
52
+
53
+ it "parses the password" do
54
+ driver_class.should_receive(:new).
55
+ with(hash_including(password: "secret")).
56
+ and_return(driver)
57
+
58
+ RDO::Connection.new("test://user:secret@whatever:3456")
59
+ end
60
+
61
+ it "parses the port number" do
62
+ driver_class.should_receive(:new).
63
+ with(hash_including(port: 3456)).
64
+ and_return(driver)
65
+
66
+ RDO::Connection.new("test://whatever:3456")
67
+ end
68
+
69
+ it "parses the path" do
70
+ driver_class.should_receive(:new).
71
+ with(hash_including(path: "/some/path.db")).
72
+ and_return(driver)
73
+
74
+ RDO::Connection.new("test://whatever/some/path.db")
75
+ end
76
+
77
+ it "parses the database name" do
78
+ driver_class.should_receive(:new).
79
+ with(hash_including(database: "my_db")).
80
+ and_return(driver)
81
+
82
+ RDO::Connection.new("test://whatever/my_db")
83
+ end
84
+
85
+ it "parses the encoding" do
86
+ driver_class.should_receive(:new).
87
+ with(hash_including(encoding: "utf-8")).
88
+ and_return(driver)
89
+
90
+ RDO::Connection.new("test://whatever/my_db?encoding=utf-8")
91
+ end
92
+
93
+ it "parses driver-specific options" do
94
+ driver_class.should_receive(:new).
95
+ with(hash_including(special_mode: "true")).
96
+ and_return(driver)
97
+
98
+ RDO::Connection.new("test://whatever/my_db?encoding=utf-8&special_mode=true")
99
+ end
100
+
101
+ context "with only a path" do
102
+ it "parses the path" do
103
+ driver_class.should_receive(:new).
104
+ with(hash_including(path: "/some/path.db")).
105
+ and_return(driver)
106
+
107
+ RDO::Connection.new("test:/some/path.db")
108
+ end
109
+ end
110
+
111
+ it "invokes #open on the driver" do
112
+ driver.should_receive(:open).and_return(true)
113
+ RDO::Connection.new("test://host/db")
114
+ end
115
+ end
116
+
117
+ context "for an unknown driver" do
118
+ it "raises an RDO::Exception" do
119
+ expect {
120
+ RDO::Connection.new("wat://ever")
121
+ }.to raise_error(RDO::Exception)
122
+ end
123
+ end
124
+ end
125
+
126
+ context "with an options hash" do
127
+ context "for a registered driver" do
128
+ it "instantiates the driver" do
129
+ driver_class.should_receive(:new).and_return(driver)
130
+ RDO::Connection.new(driver: :test, host: "whatever")
131
+ end
132
+
133
+ it "passes the options to the driver" do
134
+ driver_class.should_receive(:new).
135
+ with(hash_including(host: "whatever")).
136
+ and_return(driver)
137
+ RDO::Connection.new(driver: :test, host: "whatever")
138
+ end
139
+
140
+ it "invokes #open on the driver" do
141
+ driver.should_receive(:open).and_return(true)
142
+ RDO::Connection.new(driver: :test, host: "whatever")
143
+ end
144
+ end
145
+
146
+ context "for an unknown driver" do
147
+ it "raises an RDO::Exception" do
148
+ expect {
149
+ RDO::Connection.new(driver: :wat, host: "test")
150
+ }.to raise_error(RDO::Exception)
151
+ end
152
+ end
153
+ end
154
+ end
155
+
156
+ describe "driver methods" do
157
+ let(:connection) { RDO::Connection.new("test://host") }
158
+ let(:driver) { double(:driver, open: true) }
159
+ let(:driver_class) { double(new: driver) }
160
+
161
+ before(:each) do
162
+ RDO::Connection.register_driver(:test, driver_class)
163
+ connection
164
+ end
165
+
166
+ describe "#open" do
167
+ it "delegates to the driver" do
168
+ driver.should_receive(:open).and_return(true)
169
+ connection.open.should == true
170
+ end
171
+ end
172
+
173
+ describe "#close" do
174
+ it "delegates to the driver" do
175
+ driver.should_receive(:close).and_return(true)
176
+ connection.close.should == true
177
+ end
178
+ end
179
+
180
+ describe "#open?" do
181
+ it "delegates to the driver" do
182
+ driver.should_receive(:open?).and_return(false)
183
+ connection.should_not be_open
184
+ end
185
+ end
186
+
187
+ describe "#execute" do
188
+ let(:result) { RDO::Result.new([]) }
189
+
190
+ it "delegates to the driver" do
191
+ driver.should_receive(:execute).
192
+ with("SELECT * FROM bob WHERE ?", true).
193
+ and_return(result)
194
+ connection.execute("SELECT * FROM bob WHERE ?", true).should == result
195
+ end
196
+ end
197
+
198
+ describe "#prepare" do
199
+ let(:stmt) { RDO::Statement.new(stub(:executor)) }
200
+
201
+ it "delegates to the driver" do
202
+ driver.should_receive(:prepare).
203
+ with("SELECT * FROM bob WHERE ?").
204
+ and_return(stmt)
205
+ connection.prepare("SELECT * FROM bob WHERE ?").should == stmt
206
+ end
207
+ end
208
+
209
+ describe "#quote" do
210
+ let(:quoted) { "Weird ['] quotes" }
211
+
212
+ it "delegates to the driver" do
213
+ driver.should_receive(:quote).
214
+ with("Weird ' quotes").
215
+ and_return(quoted)
216
+ connection.quote("Weird ' quotes").should == quoted
217
+ end
218
+ end
219
+ end
220
+ end
@@ -0,0 +1,29 @@
1
+ require "spec_helper"
2
+
3
+ describe RDO::Driver do
4
+ describe "#initialize" do
5
+ it "does not call #open" do
6
+ RDO::DriverWithEverything.new.should_not be_open
7
+ end
8
+ end
9
+
10
+ describe "#prepare" do
11
+ let(:driver) { RDO::DriverWithoutStatements.new }
12
+
13
+ it "returns a Statement" do
14
+ driver.prepare("SELECT * FROM bob WHERE ?").should be_a_kind_of(RDO::Statement)
15
+ end
16
+
17
+ it "has the correct command" do
18
+ driver.prepare("SELECT * FROM bob WHERE ?").command.should == "SELECT * FROM bob WHERE ?"
19
+ end
20
+
21
+ it "calls #execute on the driver" do
22
+ driver.should_receive(:execute).
23
+ with("SELECT * FROM bob WHERE ?", true).
24
+ and_return(RDO::Result.new([]))
25
+ stmt = driver.prepare("SELECT * FROM bob WHERE ?")
26
+ stmt.execute(true).should be_a_kind_of(RDO::Result)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ require "spec_helper"
2
+
3
+ describe RDO::Driver, "emulated prepared statements" do
4
+ let(:driver) { RDO::DriverWithoutStatements.new }
5
+
6
+ describe "#command" do
7
+ it "returns the command string" do
8
+ driver.prepare("SELECT * FROM users").command.should == "SELECT * FROM users"
9
+ end
10
+ end
11
+
12
+ describe "#execute" do
13
+ let(:result) { stub(:result) }
14
+
15
+ it "delegates to the driver" do
16
+ driver.should_receive(:execute).with(
17
+ "SELECT * FROM users WHERE ? AND ?", 1, 2
18
+ ).and_return(result)
19
+ driver.prepare("SELECT * FROM users WHERE ? AND ?").execute(1, 2).should == result
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,117 @@
1
+ require "spec_helper"
2
+
3
+ describe RDO::Result do
4
+ it "is enumerable" do
5
+ RDO::Result.new([]).should be_a_kind_of(Enumerable)
6
+ end
7
+
8
+ describe "#each" do
9
+ let(:result) { RDO::Result.new([{id: 7}, {id: 42}]) }
10
+
11
+ it "enumerates all tuples" do
12
+ tuples = []
13
+ result.each{|row| tuples << row}
14
+ tuples.should == [{id: 7}, {id: 42}]
15
+ end
16
+
17
+ it "returns the result" do
18
+ result.each.should equal(result)
19
+ end
20
+ end
21
+
22
+ describe "#info" do
23
+ let(:result) { RDO::Result.new([], foo: "bar", zip: 42) }
24
+
25
+ it "returns all info passed to #initialize" do
26
+ result.info.should == {foo: "bar", zip: 42}
27
+ end
28
+ end
29
+
30
+ describe "#insert_id" do
31
+ context "when provided in the info" do
32
+ let(:result) { RDO::Result.new([], insert_id: 21) }
33
+
34
+ it "returns the ID from the info" do
35
+ result.insert_id.should == 21
36
+ end
37
+ end
38
+
39
+ context "when not provided in the info" do
40
+ context "and there are tuples" do
41
+ let(:result) { RDO::Result.new([{id: 6, name: "bob"}]) }
42
+
43
+ it "infers from the tuples" do
44
+ result.insert_id.should == 6
45
+ end
46
+ end
47
+
48
+ context "and there are no tuples" do
49
+ let(:result) { RDO::Result.new([]) }
50
+
51
+ it "returns nil" do
52
+ result.insert_id.should be_nil
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "#affected_rows" do
59
+ context "when provided in the info" do
60
+ let(:result) { RDO::Result.new([], affected_rows: 3) }
61
+
62
+ it "returns the value from the info" do
63
+ result.affected_rows.should == 3
64
+ end
65
+ end
66
+
67
+ context "when not provided in the info" do
68
+ let(:result) { RDO::Result.new([]) }
69
+
70
+ it "returns nil" do
71
+ result.insert_id.should be_nil
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "#count" do
77
+ context "when provided in the info" do
78
+ let(:result) { RDO::Result.new([{id: 7}, {id: 42}], count: 50) }
79
+
80
+ it "returns the count from the info" do
81
+ result.count.should == 50
82
+ end
83
+
84
+ context "with a block given" do
85
+ it "delegates to Enumerable" do
86
+ result.count{|row| row[:id] > 10}.should == 1
87
+ end
88
+ end
89
+ end
90
+
91
+ context "when not provided in the info" do
92
+ let(:result) { RDO::Result.new([{id: 7}, {id: 42}]) }
93
+
94
+ it "delegates to Enumerable" do
95
+ result.count.should == 2
96
+ end
97
+ end
98
+ end
99
+
100
+ describe "#first_value" do
101
+ context "when there are tuples" do
102
+ let(:result) { RDO::Result.new([{id: 6, name: "bob"}]) }
103
+
104
+ it "reads the first column in the first tuple" do
105
+ result.first_value.should == 6
106
+ end
107
+ end
108
+
109
+ context "when there are no tuples" do
110
+ let(:result) { RDO::Result.new([]) }
111
+
112
+ it "returns nil" do
113
+ result.first_value.should be_nil
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe RDO::Statement do
4
+ let(:executor) { double(:executor) }
5
+ let(:stmt) { RDO::Statement.new(executor) }
6
+
7
+ describe "#command" do
8
+ let(:command) { "SELECT * FROM users" }
9
+
10
+ it "delegates to the executor" do
11
+ executor.should_receive(:command).and_return(command)
12
+ stmt.command.should == command
13
+ end
14
+ end
15
+
16
+ describe "#execute" do
17
+ let(:result) { stub(:result) }
18
+
19
+ it "delegates to the executor" do
20
+ executor.should_receive(:execute).with(1, 2).and_return(result)
21
+ stmt.execute(1, 2).should == result
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,92 @@
1
+ require "spec_helper"
2
+
3
+ describe RDO::Util do
4
+ describe ".system_time_zone" do
5
+ it "returns the time zone of the local system" do
6
+ require "date"
7
+ RDO::Util.system_time_zone.should == DateTime.now.zone
8
+ end
9
+ end
10
+
11
+ describe ".float" do
12
+ context "with Infinity" do
13
+ it "returns Float::INFINITY" do
14
+ RDO::Util.float("Infinity").should == Float::INFINITY
15
+ end
16
+ end
17
+
18
+ context "with -Infinity" do
19
+ it "returns -Float::INFINITY" do
20
+ RDO::Util.float("-Infinity").should == -Float::INFINITY
21
+ end
22
+ end
23
+
24
+ context "with NaN" do
25
+ it "returns Float::NAN" do
26
+ RDO::Util.float("NaN").should be_nan
27
+ end
28
+ end
29
+
30
+ context "with a number" do
31
+ it "returns a Float" do
32
+ RDO::Util.float("1.2").should == 1.2
33
+ end
34
+ end
35
+
36
+ context "with an exponent" do
37
+ it "returns a Float" do
38
+ RDO::Util.float("1.1E-2").should == Float("1.1E-2")
39
+ end
40
+ end
41
+ end
42
+
43
+ describe "decimal" do
44
+ context "with NaN" do
45
+ it "returns NaN" do
46
+ RDO::Util.decimal("NaN").should be_nan
47
+ end
48
+ end
49
+
50
+ context "with a number" do
51
+ it "returns a BigDecimal" do
52
+ require "bigdecimal"
53
+ RDO::Util.decimal("1.2").should == BigDecimal("1.2")
54
+ end
55
+ end
56
+
57
+ context "with an exponent" do
58
+ it "returns a BigDecimal" do
59
+ require "bigdecimal"
60
+ RDO::Util.decimal("1E-2").should == BigDecimal("1E-2")
61
+ end
62
+ end
63
+ end
64
+
65
+ describe ".date" do
66
+ it "returns a Date" do
67
+ RDO::Util.date("2012-09-22").should == Date.new(2012, 9, 22)
68
+ end
69
+
70
+ context "with BC" do
71
+ it "returns a Date" do
72
+ RDO::Util.date("431-09-22 BC").should == Date.new(-430, 9, 22)
73
+ end
74
+ end
75
+ end
76
+
77
+ describe ".date_time_with_zone" do
78
+ it "returns a DateTime" do
79
+ require "date"
80
+ RDO::Util.date_time_with_zone("2012-09-22 10:04:32 +06:00").should ==
81
+ DateTime.parse("2012-09-22 10:04:32 +06:00")
82
+ end
83
+ end
84
+
85
+ describe ".date_time_without_zone" do
86
+ it "returns a DateTime in the system time zone" do
87
+ require "date"
88
+ RDO::Util.date_time_without_zone("2012-09-22 10:04:32").should ==
89
+ DateTime.parse("2012-09-22 10:04:32 #{DateTime.now.zone}")
90
+ end
91
+ end
92
+ end