rdo 0.0.1

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.
@@ -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