UNPKG

6.9 kBJavaScriptView Raw
1'use strict'
2const expect = require('expect.js')
3const _ = require('lodash')
4
5const describe = require('mocha').describe
6const it = require('mocha').it
7
8const Pool = require('../')
9
10describe('pool', function () {
11 describe('with callbacks', function () {
12 it('works totally unconfigured', function (done) {
13 const pool = new Pool()
14 pool.connect(function (err, client, release) {
15 if (err) return done(err)
16 client.query('SELECT NOW()', function (err, res) {
17 release()
18 if (err) return done(err)
19 expect(res.rows).to.have.length(1)
20 pool.end(done)
21 })
22 })
23 })
24
25 it('passes props to clients', function (done) {
26 const pool = new Pool({ binary: true })
27 pool.connect(function (err, client, release) {
28 release()
29 if (err) return done(err)
30 expect(client.binary).to.eql(true)
31 pool.end(done)
32 })
33 })
34
35 it('can run a query with a callback without parameters', function (done) {
36 const pool = new Pool()
37 pool.query('SELECT 1 as num', function (err, res) {
38 expect(res.rows[0]).to.eql({ num: 1 })
39 pool.end(function () {
40 done(err)
41 })
42 })
43 })
44
45 it('can run a query with a callback', function (done) {
46 const pool = new Pool()
47 pool.query('SELECT $1::text as name', ['brianc'], function (err, res) {
48 expect(res.rows[0]).to.eql({ name: 'brianc' })
49 pool.end(function () {
50 done(err)
51 })
52 })
53 })
54
55 it('passes connection errors to callback', function (done) {
56 const pool = new Pool({ port: 53922 })
57 pool.query('SELECT $1::text as name', ['brianc'], function (err, res) {
58 expect(res).to.be(undefined)
59 expect(err).to.be.an(Error)
60 // a connection error should not polute the pool with a dead client
61 expect(pool.totalCount).to.equal(0)
62 pool.end(function (err) {
63 done(err)
64 })
65 })
66 })
67
68 it('does not pass client to error callback', function (done) {
69 const pool = new Pool({ port: 58242 })
70 pool.connect(function (err, client, release) {
71 expect(err).to.be.an(Error)
72 expect(client).to.be(undefined)
73 expect(release).to.be.a(Function)
74 pool.end(done)
75 })
76 })
77
78 it('removes client if it errors in background', function (done) {
79 const pool = new Pool()
80 pool.connect(function (err, client, release) {
81 release()
82 if (err) return done(err)
83 client.testString = 'foo'
84 setTimeout(function () {
85 client.emit('error', new Error('on purpose'))
86 }, 10)
87 })
88 pool.on('error', function (err) {
89 expect(err.message).to.be('on purpose')
90 expect(err.client).to.not.be(undefined)
91 expect(err.client.testString).to.be('foo')
92 err.client.connection.stream.on('end', function () {
93 pool.end(done)
94 })
95 })
96 })
97
98 it('should not change given options', function (done) {
99 const options = { max: 10 }
100 const pool = new Pool(options)
101 pool.connect(function (err, client, release) {
102 release()
103 if (err) return done(err)
104 expect(options).to.eql({ max: 10 })
105 pool.end(done)
106 })
107 })
108
109 it('does not create promises when connecting', function (done) {
110 const pool = new Pool()
111 const returnValue = pool.connect(function (err, client, release) {
112 release()
113 if (err) return done(err)
114 pool.end(done)
115 })
116 expect(returnValue).to.be(undefined)
117 })
118
119 it('does not create promises when querying', function (done) {
120 const pool = new Pool()
121 const returnValue = pool.query('SELECT 1 as num', function (err) {
122 pool.end(function () {
123 done(err)
124 })
125 })
126 expect(returnValue).to.be(undefined)
127 })
128
129 it('does not create promises when ending', function (done) {
130 const pool = new Pool()
131 const returnValue = pool.end(done)
132 expect(returnValue).to.be(undefined)
133 })
134
135 it('never calls callback syncronously', function (done) {
136 const pool = new Pool()
137 pool.connect((err, client) => {
138 if (err) throw err
139 client.release()
140 setImmediate(() => {
141 let called = false
142 pool.connect((err, client) => {
143 if (err) throw err
144 called = true
145 client.release()
146 setImmediate(() => {
147 pool.end(done)
148 })
149 })
150 expect(called).to.equal(false)
151 })
152 })
153 })
154 })
155
156 describe('with promises', function () {
157 it('connects, queries, and disconnects', function () {
158 const pool = new Pool()
159 return pool.connect().then(function (client) {
160 return client.query('select $1::text as name', ['hi']).then(function (res) {
161 expect(res.rows).to.eql([{ name: 'hi' }])
162 client.release()
163 return pool.end()
164 })
165 })
166 })
167
168 it('executes a query directly', () => {
169 const pool = new Pool()
170 return pool.query('SELECT $1::text as name', ['hi']).then((res) => {
171 expect(res.rows).to.have.length(1)
172 expect(res.rows[0].name).to.equal('hi')
173 return pool.end()
174 })
175 })
176
177 it('properly pools clients', function () {
178 const pool = new Pool({ poolSize: 9 })
179 const promises = _.times(30, function () {
180 return pool.connect().then(function (client) {
181 return client.query('select $1::text as name', ['hi']).then(function (res) {
182 client.release()
183 return res
184 })
185 })
186 })
187 return Promise.all(promises).then(function (res) {
188 expect(res).to.have.length(30)
189 expect(pool.totalCount).to.be(9)
190 return pool.end()
191 })
192 })
193
194 it('supports just running queries', function () {
195 const pool = new Pool({ poolSize: 9 })
196 const text = 'select $1::text as name'
197 const values = ['hi']
198 const query = { text: text, values: values }
199 const promises = _.times(30, () => pool.query(query))
200 return Promise.all(promises).then(function (queries) {
201 expect(queries).to.have.length(30)
202 return pool.end()
203 })
204 })
205
206 it('recovers from query errors', function () {
207 const pool = new Pool()
208
209 const errors = []
210 const promises = _.times(30, () => {
211 return pool.query('SELECT asldkfjasldkf').catch(function (e) {
212 errors.push(e)
213 })
214 })
215 return Promise.all(promises).then(() => {
216 expect(errors).to.have.length(30)
217 expect(pool.totalCount).to.equal(0)
218 expect(pool.idleCount).to.equal(0)
219 return pool.query('SELECT $1::text as name', ['hi']).then(function (res) {
220 expect(res.rows).to.eql([{ name: 'hi' }])
221 return pool.end()
222 })
223 })
224 })
225 })
226})