Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/migrate tests to node runner #2593

Merged
merged 3 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
96 changes: 57 additions & 39 deletions test/unix.js → test/node-test/unix.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
'use strict'

const { test } = require('tap')
const { Client, Pool } = require('..')
const { test } = require('node:test')
const { Client, Pool } = require('../../')
const http = require('http')
const https = require('https')
const pem = require('https-pem')
const fs = require('fs')
const { tspl } = require('@matteo.collina/tspl')

if (process.platform !== 'win32') {
test('http unix get', (t) => {
t.plan(7)
test('http unix get', async (t) => {
let client
const p = tspl(t, { plan: 7 })

const server = http.createServer((req, res) => {
t.equal('/', req.url)
t.equal('GET', req.method)
t.equal('localhost', req.headers.host)
p.equal('/', req.url)
p.equal('GET', req.method)
p.equal('localhost', req.headers.host)
res.setHeader('Content-Type', 'text/plain')
res.end('hello')
})
t.teardown(server.close.bind(server))

t.after(() => {
server.close()
client.close()
})

try {
fs.unlinkSync('/var/tmp/test3.sock')
Expand All @@ -27,41 +33,47 @@ if (process.platform !== 'win32') {
}

server.listen('/var/tmp/test3.sock', () => {
const client = new Client({
client = new Client({
hostname: 'localhost',
protocol: 'http:'
}, {
socketPath: '/var/tmp/test3.sock'
})
t.teardown(client.close.bind(client))

client.request({ path: '/', method: 'GET' }, (err, data) => {
t.error(err)
p.ifError(err)
const { statusCode, headers, body } = data
t.equal(statusCode, 200)
t.equal(headers['content-type'], 'text/plain')
p.equal(statusCode, 200)
p.equal(headers['content-type'], 'text/plain')
const bufs = []
body.on('data', (buf) => {
bufs.push(buf)
})
body.on('end', () => {
t.equal('hello', Buffer.concat(bufs).toString('utf8'))
p.equal('hello', Buffer.concat(bufs).toString('utf8'))
})
})
})

await p.completed
})

test('http unix get pool', (t) => {
t.plan(7)
test('http unix get pool', async (t) => {
let client
const p = tspl(t, { plan: 7 })

const server = http.createServer((req, res) => {
t.equal('/', req.url)
t.equal('GET', req.method)
t.equal('localhost', req.headers.host)
p.equal('/', req.url)
p.equal('GET', req.method)
p.equal('localhost', req.headers.host)
res.setHeader('Content-Type', 'text/plain')
res.end('hello')
})
t.teardown(server.close.bind(server))

t.after(() => {
server.close()
client.close()
})

try {
fs.unlinkSync('/var/tmp/test3.sock')
Expand All @@ -70,72 +82,78 @@ if (process.platform !== 'win32') {
}

server.listen('/var/tmp/test3.sock', () => {
const client = new Pool({
client = new Pool({
hostname: 'localhost',
protocol: 'http:'
}, {
socketPath: '/var/tmp/test3.sock'
})
t.teardown(client.close.bind(client))

client.request({ path: '/', method: 'GET' }, (err, data) => {
t.error(err)
p.ifError(err)
const { statusCode, headers, body } = data
t.equal(statusCode, 200)
t.equal(headers['content-type'], 'text/plain')
p.equal(statusCode, 200)
p.equal(headers['content-type'], 'text/plain')
const bufs = []
body.on('data', (buf) => {
bufs.push(buf)
})
body.on('end', () => {
t.equal('hello', Buffer.concat(bufs).toString('utf8'))
p.equal('hello', Buffer.concat(bufs).toString('utf8'))
})
})
})

await p.completed
})

test('https get with tls opts', (t) => {
t.plan(6)
test('https get with tls opts', async (t) => {
let client
const p = tspl(t, { plan: 6 })

const server = https.createServer(pem, (req, res) => {
t.equal('/', req.url)
t.equal('GET', req.method)
p.equal('/', req.url)
p.equal('GET', req.method)
res.setHeader('content-type', 'text/plain')
res.end('hello')
})
t.teardown(server.close.bind(server))

t.after(() => {
server.close()
client.close()
})

try {
fs.unlinkSync('/var/tmp/test3.sock')
} catch (err) {

}

server.listen('/var/tmp/test8.sock', () => {
const client = new Client({
server.listen('/var/tmp/test3.sock', () => {
client = new Client({
hostname: 'localhost',
protocol: 'https:'
}, {
socketPath: '/var/tmp/test8.sock',
socketPath: '/var/tmp/test3.sock',
tls: {
rejectUnauthorized: false
}
})
t.teardown(client.close.bind(client))

client.request({ path: '/', method: 'GET' }, (err, data) => {
t.error(err)
p.ifError(err)
const { statusCode, headers, body } = data
t.equal(statusCode, 200)
t.equal(headers['content-type'], 'text/plain')
p.equal(statusCode, 200)
p.equal(headers['content-type'], 'text/plain')
const bufs = []
body.on('data', (buf) => {
bufs.push(buf)
})
body.on('end', () => {
t.equal('hello', Buffer.concat(bufs).toString('utf8'))
p.equal('hello', Buffer.concat(bufs).toString('utf8'))
})
})
})
await p.completed
})
}
119 changes: 119 additions & 0 deletions test/node-test/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
'use strict'

const { test } = require('node:test')
const assert = require('node:assert')
const { Stream } = require('stream')
const { EventEmitter } = require('events')

const util = require('../../lib/core/util')
const { headerNameLowerCasedRecord } = require('../../lib/core/constants')
const { InvalidArgumentError } = require('../../lib/core/errors')

test('isStream', () => {
const stream = new Stream()
assert.ok(util.isStream(stream))

const buffer = Buffer.alloc(0)
assert.ok(util.isStream(buffer) === false)

const ee = new EventEmitter()
assert.ok(util.isStream(ee) === false)
})

test('getServerName', () => {
assert.equal(util.getServerName('1.1.1.1'), '')
assert.equal(util.getServerName('1.1.1.1:443'), '')
assert.equal(util.getServerName('example.com'), 'example.com')
assert.equal(util.getServerName('example.com:80'), 'example.com')
assert.equal(util.getServerName('[2606:4700:4700::1111]'), '')
assert.equal(util.getServerName('[2606:4700:4700::1111]:443'), '')
})

test('validateHandler', () => {
assert.throws(() => util.validateHandler(null), InvalidArgumentError, 'handler must be an object')
assert.throws(() => util.validateHandler({
onConnect: null
}), InvalidArgumentError, 'invalid onConnect method')
assert.throws(() => util.validateHandler({
onConnect: () => {},
onError: null
}), InvalidArgumentError, 'invalid onError method')
assert.throws(() => util.validateHandler({
onConnect: () => {},
onError: () => {},
onBodySent: null
}), InvalidArgumentError, 'invalid onBodySent method')
assert.throws(() => util.validateHandler({
onConnect: () => {},
onError: () => {},
onBodySent: () => {},
onHeaders: null
}), InvalidArgumentError, 'invalid onHeaders method')
assert.throws(() => util.validateHandler({
onConnect: () => {},
onError: () => {},
onBodySent: () => {},
onHeaders: () => {},
onData: null
}), InvalidArgumentError, 'invalid onData method')
assert.throws(() => util.validateHandler({
onConnect: () => {},
onError: () => {},
onBodySent: () => {},
onHeaders: () => {},
onData: () => {},
onComplete: null
}), InvalidArgumentError, 'invalid onComplete method')
assert.throws(() => util.validateHandler({
onConnect: () => {},
onError: () => {},
onBodySent: () => {},
onUpgrade: 'null'
}, 'CONNECT'), InvalidArgumentError, 'invalid onUpgrade method')
assert.throws(() => util.validateHandler({
onConnect: () => {},
onError: () => {},
onBodySent: () => {},
onUpgrade: 'null'
}, 'CONNECT', () => {}), InvalidArgumentError, 'invalid onUpgrade method')
})

test('parseHeaders', () => {
assert.deepEqual(util.parseHeaders(['key', 'value']), { key: 'value' })
assert.deepEqual(util.parseHeaders([Buffer.from('key'), Buffer.from('value')]), { key: 'value' })
assert.deepEqual(util.parseHeaders(['Key', 'Value']), { key: 'Value' })
assert.deepEqual(util.parseHeaders(['Key', 'value', 'key', 'Value']), { key: ['value', 'Value'] })
assert.deepEqual(util.parseHeaders(['key', ['value1', 'value2', 'value3']]), { key: ['value1', 'value2', 'value3'] })
assert.deepEqual(util.parseHeaders([Buffer.from('key'), [Buffer.from('value1'), Buffer.from('value2'), Buffer.from('value3')]]), { key: ['value1', 'value2', 'value3'] })
})

test('parseRawHeaders', () => {
assert.deepEqual(util.parseRawHeaders(['key', 'value', Buffer.from('key'), Buffer.from('value')]), ['key', 'value', 'key', 'value'])
})

test('buildURL', () => {
const tests = [
[{ id: BigInt(123456) }, 'id=123456'],
[{ date: new Date() }, 'date='],
[{ obj: { id: 1 } }, 'obj='],
[{ params: ['a', 'b', 'c'] }, 'params=a&params=b&params=c'],
[{ bool: true }, 'bool=true'],
[{ number: 123456 }, 'number=123456'],
[{ string: 'hello' }, 'string=hello'],
[{ null: null }, 'null='],
[{ void: undefined }, 'void='],
[{ fn: function () {} }, 'fn='],
[{}, '']
]

const base = 'https://www.google.com'

for (const [input, output] of tests) {
const expected = `${base}${output ? `?${output}` : output}`
assert.deepEqual(util.buildURL(base, input), expected)
}
})

test('headerNameLowerCasedRecord', () => {
assert.ok(typeof headerNameLowerCasedRecord.hasOwnProperty !== 'function')
})
60 changes: 60 additions & 0 deletions test/node-test/validations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
'use strict'

const { test } = require('node:test')
const { createServer } = require('http')
const { Client } = require('../../')
const { tspl } = require('@matteo.collina/tspl')

test('validations', async t => {
let client
const p = tspl(t, { plan: 10 })

const server = createServer((req, res) => {
res.setHeader('content-type', 'text/plain')
res.end('hello')
p.fail('server should never be called')
})

t.after(() => {
server.close()
client.close()
})

server.listen(0, async () => {
const url = `http://localhost:${server.address().port}`
client = new Client(url)

await t.test('path', () => {
client.request({ path: null, method: 'GET' }, (err, res) => {
p.equal(err.code, 'UND_ERR_INVALID_ARG')
p.equal(err.message, 'path must be a string')
})

client.request({ path: 'aaa', method: 'GET' }, (err, res) => {
p.equal(err.code, 'UND_ERR_INVALID_ARG')
p.equal(err.message, 'path must be an absolute URL or start with a slash')
})
})

await t.test('method', () => {
client.request({ path: '/', method: null }, (err, res) => {
p.equal(err.code, 'UND_ERR_INVALID_ARG')
p.equal(err.message, 'method must be a string')
})
})

await t.test('body', () => {
client.request({ path: '/', method: 'POST', body: 42 }, (err, res) => {
p.equal(err.code, 'UND_ERR_INVALID_ARG')
p.equal(err.message, 'body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable')
})

client.request({ path: '/', method: 'POST', body: { hello: 'world' } }, (err, res) => {
p.equal(err.code, 'UND_ERR_INVALID_ARG')
p.equal(err.message, 'body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable')
})
})
})

await p.completed
})