Merge pull request #716 from ldapjs/dependabot/npm_and_yarn/tap-15.0.1

This commit is contained in:
Tony Brix 2021-04-05 08:15:51 -05:00 committed by GitHub
commit 50ab06f50f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 430 additions and 422 deletions

4
.taprc
View File

@ -1,6 +1,4 @@
esm: false
jsx: false
ts: false
check-coverage: false
files:
- 'test/**/*.test.js'

View File

@ -37,7 +37,7 @@
"highlight.js": "^10.6.0",
"husky": "^4.2.5",
"marked": "^2.0.0",
"tap": "14.11.0"
"tap": "15.0.1"
},
"scripts": {
"test": "tap --no-cov",

View File

@ -154,11 +154,11 @@ test('apply - replace', function (t) {
// plain
res = Change.apply(single, { cn: ['old'] })
t.deepEqual(res.cn, ['new'])
t.same(res.cn, ['new'])
// multiple
res = Change.apply(single, { cn: ['old', 'also'] })
t.deepEqual(res.cn, ['new'])
t.same(res.cn, ['new'])
// empty
res = Change.apply(empty, { cn: ['existing'] })
@ -167,7 +167,7 @@ test('apply - replace', function (t) {
// absent
res = Change.apply(single, { dn: ['otherjunk'] })
t.deepEqual(res.cn, ['new'])
t.same(res.cn, ['new'])
// scalar formatting "success"
res = Change.apply(single, { cn: 'old' }, true)
@ -175,7 +175,7 @@ test('apply - replace', function (t) {
// scalar formatting "failure"
res = Change.apply(twin, { cn: 'old' }, true)
t.deepEqual(res.cn, ['new', 'two'])
t.same(res.cn, ['new', 'two'])
t.end()
})
@ -192,15 +192,15 @@ test('apply - add', function (t) {
// plain
res = Change.apply(single, { cn: ['old'] })
t.deepEqual(res.cn, ['old', 'new'])
t.same(res.cn, ['old', 'new'])
// multiple
res = Change.apply(single, { cn: ['old', 'also'] })
t.deepEqual(res.cn, ['old', 'also', 'new'])
t.same(res.cn, ['old', 'also', 'new'])
// absent
res = Change.apply(single, { dn: ['otherjunk'] })
t.deepEqual(res.cn, ['new'])
t.same(res.cn, ['new'])
// scalar formatting "success"
res = Change.apply(single, { }, true)
@ -208,11 +208,11 @@ test('apply - add', function (t) {
// scalar formatting "failure"
res = Change.apply(single, { cn: 'old' }, true)
t.deepEqual(res.cn, ['old', 'new'])
t.same(res.cn, ['old', 'new'])
// duplicate add
res = Change.apply(single, { cn: 'new' })
t.deepEqual(res.cn, ['new'])
t.same(res.cn, ['new'])
t.end()
})
@ -229,7 +229,7 @@ test('apply - delete', function (t) {
// plain
res = Change.apply(single, { cn: ['old', 'new'] })
t.deepEqual(res.cn, ['new'])
t.same(res.cn, ['new'])
// empty
res = Change.apply(single, { cn: ['old'] })
@ -242,7 +242,7 @@ test('apply - delete', function (t) {
// scalar formatting "failure"
res = Change.apply(single, { cn: ['old', 'several', 'items'] }, true)
t.deepEqual(res.cn, ['several', 'items'])
t.same(res.cn, ['several', 'items'])
// absent
res = Change.apply(single, { dn: ['otherjunk'] })

View File

@ -14,320 +14,324 @@ const LDAP_CONNECT_TIMEOUT = process.env.LDAP_CONNECT_TIMEOUT || 0
const BIND_DN = 'cn=root'
const BIND_PW = 'secret'
tap.beforeEach((done, t) => {
t.context.socketPath = getSock()
t.context.server = ldap.createServer()
tap.beforeEach((t) => {
return new Promise(resolve => {
t.context.socketPath = getSock()
t.context.server = ldap.createServer()
const server = t.context.server
server.bind(BIND_DN, function (req, res, next) {
if (req.credentials !== BIND_PW) { return next(new ldap.InvalidCredentialsError('Invalid password')) }
const server = t.context.server
server.bind(BIND_DN, function (req, res, next) {
if (req.credentials !== BIND_PW) { return next(new ldap.InvalidCredentialsError('Invalid password')) }
res.end()
return next()
})
server.add(SUFFIX, function (req, res, next) {
res.end()
return next()
})
server.compare(SUFFIX, function (req, res, next) {
res.end(req.value === 'test')
return next()
})
server.del(SUFFIX, function (req, res, next) {
res.end()
return next()
})
// LDAP whoami
server.exop('1.3.6.1.4.1.4203.1.11.3', function (req, res, next) {
res.value = 'u:xxyyz@EXAMPLE.NET'
res.end()
return next()
})
server.modify(SUFFIX, function (req, res, next) {
res.end()
return next()
})
server.modifyDN(SUFFIX, function (req, res, next) {
res.end()
return next()
})
server.modifyDN('cn=issue-480', function (req, res, next) {
assert(req.newRdn.toString().length > 132)
res.end()
return next()
})
server.search('dc=slow', function (req, res, next) {
res.send({
dn: 'dc=slow',
attributes: {
you: 'wish',
this: 'was',
faster: '.'
}
})
setTimeout(function () {
res.end()
next()
}, 250)
})
return next()
})
server.search('dc=timeout', function () {
// Cause the client to timeout by not sending a response.
})
server.add(SUFFIX, function (req, res, next) {
res.end()
return next()
})
server.search(SUFFIX, function (req, res, next) {
if (req.dn.equals('cn=ref,' + SUFFIX)) {
res.send(res.createSearchReference('ldap://localhost'))
} else if (req.dn.equals('cn=bin,' + SUFFIX)) {
res.send(res.createSearchEntry({
objectName: req.dn,
attributes: {
'foo;binary': 'wr0gKyDCvCA9IMK+',
gb18030: Buffer.from([0xB5, 0xE7, 0xCA, 0xD3, 0xBB, 0xFA]),
objectclass: 'binary'
}
}))
} else {
const e = res.createSearchEntry({
objectName: req.dn,
attributes: {
cn: ['unit', 'test'],
SN: 'testy'
}
})
res.send(e)
res.send(e)
}
server.compare(SUFFIX, function (req, res, next) {
res.end(req.value === 'test')
return next()
})
res.end()
return next()
})
server.del(SUFFIX, function (req, res, next) {
res.end()
return next()
})
server.search('cn=sizelimit', function (req, res, next) {
const sizeLimit = 200
for (let i = 0; i < 1000; i++) {
if (req.sizeLimit > 0 && i >= req.sizeLimit) {
break
} else if (i > sizeLimit) {
res.end(ldap.LDAP_SIZE_LIMIT_EXCEEDED)
return next()
}
// LDAP whoami
server.exop('1.3.6.1.4.1.4203.1.11.3', function (req, res, next) {
res.value = 'u:xxyyz@EXAMPLE.NET'
res.end()
return next()
})
server.modify(SUFFIX, function (req, res, next) {
res.end()
return next()
})
server.modifyDN(SUFFIX, function (req, res, next) {
res.end()
return next()
})
server.modifyDN('cn=issue-480', function (req, res, next) {
assert(req.newRdn.toString().length > 132)
res.end()
return next()
})
server.search('dc=slow', function (req, res, next) {
res.send({
dn: util.format('o=%d, cn=sizelimit', i),
dn: 'dc=slow',
attributes: {
o: [i],
objectclass: ['pagedResult']
you: 'wish',
this: 'was',
faster: '.'
}
})
}
res.end()
return next()
})
setTimeout(function () {
res.end()
next()
}, 250)
})
server.search('cn=paged', function (req, res, next) {
const min = 0
const max = 1000
server.search('dc=timeout', function () {
// Cause the client to timeout by not sending a response.
})
function sendResults (start, end) {
start = (start < min) ? min : start
end = (end > max || end < min) ? max : end
let i
for (i = start; i < end; i++) {
server.search(SUFFIX, function (req, res, next) {
if (req.dn.equals('cn=ref,' + SUFFIX)) {
res.send(res.createSearchReference('ldap://localhost'))
} else if (req.dn.equals('cn=bin,' + SUFFIX)) {
res.send(res.createSearchEntry({
objectName: req.dn,
attributes: {
'foo;binary': 'wr0gKyDCvCA9IMK+',
gb18030: Buffer.from([0xB5, 0xE7, 0xCA, 0xD3, 0xBB, 0xFA]),
objectclass: 'binary'
}
}))
} else {
const e = res.createSearchEntry({
objectName: req.dn,
attributes: {
cn: ['unit', 'test'],
SN: 'testy'
}
})
res.send(e)
res.send(e)
}
res.end()
return next()
})
server.search('cn=sizelimit', function (req, res, next) {
const sizeLimit = 200
for (let i = 0; i < 1000; i++) {
if (req.sizeLimit > 0 && i >= req.sizeLimit) {
break
} else if (i > sizeLimit) {
res.end(ldap.LDAP_SIZE_LIMIT_EXCEEDED)
return next()
}
res.send({
dn: util.format('o=%d, cn=paged', i),
dn: util.format('o=%d, cn=sizelimit', i),
attributes: {
o: [i],
objectclass: ['pagedResult']
}
})
}
return i
}
let cookie = null
let pageSize = 0
req.controls.forEach(function (control) {
if (control.type === ldap.PagedResultsControl.OID) {
pageSize = control.value.size
cookie = control.value.cookie
}
})
if (cookie && Buffer.isBuffer(cookie)) {
// Do simple paging
let first = min
if (cookie.length !== 0) {
first = parseInt(cookie.toString(), 10)
}
const last = sendResults(first, first + pageSize)
let resultCookie
if (last < max) {
resultCookie = Buffer.from(last.toString())
} else {
resultCookie = Buffer.from('')
}
res.controls.push(new ldap.PagedResultsControl({
value: {
size: pageSize, // correctness not required here
cookie: resultCookie
}
}))
res.end()
next()
} else {
// don't allow non-paged searches for this test endpoint
next(new ldap.UnwillingToPerformError())
}
})
server.search('cn=sssvlv', function (req, res, next) {
const min = 0
const max = 100
const results = []
let o = 'aa'
for (let i = min; i < max; i++) {
results.push({
dn: util.format('o=%s, cn=sssvlv', o),
attributes: {
o: [o],
objectclass: ['sssvlvResult']
}
})
o = ((parseInt(o, 36) + 1).toString(36)).replace(/0/g, 'a')
}
function sendResults (start, end, sortBy, sortDesc) {
start = (start < min) ? min : start
end = (end > max || end < min) ? max : end
const sorted = results.sort((a, b) => {
if (a.attributes[sortBy][0] < b.attributes[sortBy][0]) {
return sortDesc ? 1 : -1
} else if (a.attributes[sortBy][0] > b.attributes[sortBy][0]) {
return sortDesc ? -1 : 1
}
return 0
})
for (let i = start; i < end; i++) {
res.send(sorted[i])
}
}
let sortBy = null
let sortDesc = null
let afterCount = null
let targetOffset = null
req.controls.forEach(function (control) {
if (control.type === ldap.ServerSideSortingRequestControl.OID) {
sortBy = control.value[0].attributeType
sortDesc = control.value[0].reverseOrder
}
if (control.type === ldap.VirtualListViewRequestControl.OID) {
afterCount = control.value.afterCount
targetOffset = control.value.targetOffset
}
})
if (sortBy) {
if (afterCount && targetOffset) {
sendResults(targetOffset - 1, (targetOffset + afterCount), sortBy, sortDesc)
} else {
sendResults(min, max, sortBy, sortDesc)
}
res.end()
next()
} else {
next(new ldap.UnwillingToPerformError())
}
})
server.search('cn=pagederr', function (req, res, next) {
let cookie = null
req.controls.forEach(function (control) {
if (control.type === ldap.PagedResultsControl.OID) {
cookie = control.value.cookie
}
})
if (cookie && Buffer.isBuffer(cookie) && cookie.length === 0) {
// send first "page"
res.send({
dn: util.format('o=result, cn=pagederr'),
attributes: {
o: 'result',
objectclass: ['pagedResult']
}
})
res.controls.push(new ldap.PagedResultsControl({
value: {
size: 2,
cookie: Buffer.from('a')
}
}))
res.end()
return next()
} else {
// send error instead of second page
res.end(ldap.LDAP_SIZE_LIMIT_EXCEEDED)
return next()
}
})
})
server.search('dc=empty', function (req, res, next) {
res.send({
dn: 'dc=empty',
attributes: {
member: [],
'member;range=0-1': ['cn=user1, dc=empty', 'cn=user2, dc=empty']
server.search('cn=paged', function (req, res, next) {
const min = 0
const max = 1000
function sendResults (start, end) {
start = (start < min) ? min : start
end = (end > max || end < min) ? max : end
let i
for (i = start; i < end; i++) {
res.send({
dn: util.format('o=%d, cn=paged', i),
attributes: {
o: [i],
objectclass: ['pagedResult']
}
})
}
return i
}
let cookie = null
let pageSize = 0
req.controls.forEach(function (control) {
if (control.type === ldap.PagedResultsControl.OID) {
pageSize = control.value.size
cookie = control.value.cookie
}
})
if (cookie && Buffer.isBuffer(cookie)) {
// Do simple paging
let first = min
if (cookie.length !== 0) {
first = parseInt(cookie.toString(), 10)
}
const last = sendResults(first, first + pageSize)
let resultCookie
if (last < max) {
resultCookie = Buffer.from(last.toString())
} else {
resultCookie = Buffer.from('')
}
res.controls.push(new ldap.PagedResultsControl({
value: {
size: pageSize, // correctness not required here
cookie: resultCookie
}
}))
res.end()
next()
} else {
// don't allow non-paged searches for this test endpoint
next(new ldap.UnwillingToPerformError())
}
})
server.search('cn=sssvlv', function (req, res, next) {
const min = 0
const max = 100
const results = []
let o = 'aa'
for (let i = min; i < max; i++) {
results.push({
dn: util.format('o=%s, cn=sssvlv', o),
attributes: {
o: [o],
objectclass: ['sssvlvResult']
}
})
o = ((parseInt(o, 36) + 1).toString(36)).replace(/0/g, 'a')
}
function sendResults (start, end, sortBy, sortDesc) {
start = (start < min) ? min : start
end = (end > max || end < min) ? max : end
const sorted = results.sort((a, b) => {
if (a.attributes[sortBy][0] < b.attributes[sortBy][0]) {
return sortDesc ? 1 : -1
} else if (a.attributes[sortBy][0] > b.attributes[sortBy][0]) {
return sortDesc ? -1 : 1
}
return 0
})
for (let i = start; i < end; i++) {
res.send(sorted[i])
}
}
let sortBy = null
let sortDesc = null
let afterCount = null
let targetOffset = null
req.controls.forEach(function (control) {
if (control.type === ldap.ServerSideSortingRequestControl.OID) {
sortBy = control.value[0].attributeType
sortDesc = control.value[0].reverseOrder
}
if (control.type === ldap.VirtualListViewRequestControl.OID) {
afterCount = control.value.afterCount
targetOffset = control.value.targetOffset
}
})
if (sortBy) {
if (afterCount && targetOffset) {
sendResults(targetOffset - 1, (targetOffset + afterCount), sortBy, sortDesc)
} else {
sendResults(min, max, sortBy, sortDesc)
}
res.end()
next()
} else {
next(new ldap.UnwillingToPerformError())
}
})
res.end()
return next()
})
server.search('cn=busy', function (req, res, next) {
next(new ldap.BusyError('too much to do'))
})
server.search('cn=pagederr', function (req, res, next) {
let cookie = null
req.controls.forEach(function (control) {
if (control.type === ldap.PagedResultsControl.OID) {
cookie = control.value.cookie
}
})
if (cookie && Buffer.isBuffer(cookie) && cookie.length === 0) {
// send first "page"
res.send({
dn: util.format('o=result, cn=pagederr'),
attributes: {
o: 'result',
objectclass: ['pagedResult']
}
})
res.controls.push(new ldap.PagedResultsControl({
value: {
size: 2,
cookie: Buffer.from('a')
}
}))
res.end()
return next()
} else {
// send error instead of second page
res.end(ldap.LDAP_SIZE_LIMIT_EXCEEDED)
return next()
}
})
server.search('', function (req, res, next) {
if (req.dn.toString() === '') {
server.search('dc=empty', function (req, res, next) {
res.send({
dn: '',
dn: 'dc=empty',
attributes: {
objectclass: ['RootDSE', 'top']
member: [],
'member;range=0-1': ['cn=user1, dc=empty', 'cn=user2, dc=empty']
}
})
res.end()
} else {
// Turn away any other requests (since '' is the fallthrough route)
res.errorMessage = 'No tree found for: ' + req.dn.toString()
res.end(ldap.LDAP_NO_SUCH_OBJECT)
}
return next()
})
server.unbind(function (req, res, next) {
res.end()
return next()
})
server.listen(t.context.socketPath, function () {
const client = ldap.createClient({
connectTimeout: parseInt(LDAP_CONNECT_TIMEOUT, 10),
socketPath: t.context.socketPath
return next()
})
server.search('cn=busy', function (req, res, next) {
next(new ldap.BusyError('too much to do'))
})
server.search('', function (req, res, next) {
if (req.dn.toString() === '') {
res.send({
dn: '',
attributes: {
objectclass: ['RootDSE', 'top']
}
})
res.end()
} else {
// Turn away any other requests (since '' is the fallthrough route)
res.errorMessage = 'No tree found for: ' + req.dn.toString()
res.end(ldap.LDAP_NO_SUCH_OBJECT)
}
return next()
})
server.unbind(function (req, res, next) {
res.end()
return next()
})
server.listen(t.context.socketPath, function () {
const client = ldap.createClient({
connectTimeout: parseInt(LDAP_CONNECT_TIMEOUT, 10),
socketPath: t.context.socketPath
})
t.context.client = client
client.on('connect', () => resolve())
})
t.context.client = client
client.on('connect', () => done())
})
})
tap.afterEach((done, t) => {
t.context.client.unbind((err) => {
t.error(err)
t.context.server.close(() => done())
tap.afterEach((t) => {
return new Promise(resolve => {
t.context.client.unbind((err) => {
t.error(err)
t.context.server.close(() => resolve())
})
})
})
@ -404,13 +408,13 @@ tap.test('createClient', t => {
// const socketPath = getSock()
// const server = ldap.createServer()
// server.listen(socketPath, () => {})
// t.tearDown(() => {
// t.teardown(() => {
// client.unbind(() => server.close())
// })
// client = ldap.createClient({ socketPath, log: logger })
// t.ok(logger.child)
// t.true(typeof client.log.child === 'function')
// t.ok(typeof client.log.child === 'function')
// })
t.end()
@ -784,7 +788,7 @@ tap.test('search paged', { timeout: 10000 }, function (t) {
t2.end()
})
t2.tearDown(() => {
t2.teardown(() => {
res.removeListener('searchEntry', entryListener)
res.removeListener('page', pageListener)
})
@ -995,7 +999,7 @@ tap.test('search - sssvlv', { timeout: 10000 }, function (t) {
})
res.on('error', (err) => t2.error(err))
res.on('end', function () {
t2.equals(count, 10)
t2.equal(count, 10)
t2.end()
})
})
@ -1037,7 +1041,7 @@ tap.test('search - sssvlv', { timeout: 10000 }, function (t) {
})
res.on('error', (err) => t2.error(err))
res.on('end', function () {
t2.equals(count, 10)
t2.equal(count, 10)
t2.end()
})
})
@ -1519,10 +1523,10 @@ tap.test('connection refused', function (t) {
client.on('connectRefused', () => {})
client.bind('cn=root', 'secret', function (err, res) {
t.true(err)
t.ok(err)
t.type(err, Error)
t.equals(err.code, 'ECONNREFUSED')
t.false(res)
t.equal(err.code, 'ECONNREFUSED')
t.notOk(res)
t.end()
})
})
@ -1547,11 +1551,11 @@ tap.test('connection timeout', function (t) {
}, 2000)
client.bind('cn=root', 'secret', function (err, res) {
t.true(err)
t.ok(err)
t.type(err, Error)
t.equals(err.message, 'connection timeout')
t.equal(err.message, 'connection timeout')
done = true
t.false(res)
t.notOk(res)
t.end()
})
})
@ -1574,9 +1578,9 @@ tap.only('emitError', function (t) {
t.fail(err)
})
client.on('connectTimeout', (err) => {
t.true(err)
t.ok(err)
t.type(err, Error)
t.equals(err.message, 'connection timeout')
t.equal(err.message, 'connection timeout')
clearTimeout(timeout)
t.end()
})
@ -1598,9 +1602,9 @@ tap.only('emitError', function (t) {
}, 2000)
client.on('error', (err) => {
t.true(err)
t.ok(err)
t.type(err, Error)
t.equals(err.message, 'connectTimeout: connection timeout')
t.equal(err.message, 'connectTimeout: connection timeout')
clearTimeout(timeout)
t.end()
})
@ -1619,10 +1623,10 @@ tap.only('emitError', function (t) {
t.fail(err)
})
client.on('connectRefused', (err) => {
t.true(err)
t.ok(err)
t.type(err, Error)
t.equals(err.message, `connect ECONNREFUSED 0.0.0.0:${unusedPortNumber}`)
t.equals(err.code, 'ECONNREFUSED')
t.equal(err.message, `connect ECONNREFUSED 0.0.0.0:${unusedPortNumber}`)
t.equal(err.code, 'ECONNREFUSED')
t.end()
})
@ -1637,10 +1641,10 @@ tap.only('emitError', function (t) {
})
client.on('error', (err) => {
t.true(err)
t.ok(err)
t.type(err, Error)
t.equals(err.message, `connectRefused: connect ECONNREFUSED 0.0.0.0:${unusedPortNumber}`)
t.equals(err.code, 'ECONNREFUSED')
t.equal(err.message, `connectRefused: connect ECONNREFUSED 0.0.0.0:${unusedPortNumber}`)
t.equal(err.code, 'ECONNREFUSED')
t.end()
})

View File

@ -22,7 +22,7 @@ test('new with args', function (t) {
t.equal(c.type, '1.2.840.113556.1.4.319')
t.ok(c.criticality)
t.equal(c.value.size, 1000)
t.is(Buffer.compare(c.value.cookie, Buffer.from([1, 2, 3])), 0)
t.equal(Buffer.compare(c.value.cookie, Buffer.from([1, 2, 3])), 0)
const writer = new BerWriter()
c.toBer(writer)
@ -32,7 +32,7 @@ test('new with args', function (t) {
t.equal(psc.type, '1.2.840.113556.1.4.319')
t.ok(psc.criticality)
t.equal(psc.value.size, 1000)
t.is(Buffer.compare(psc.value.cookie, Buffer.from([1, 2, 3])), 0)
t.equal(Buffer.compare(psc.value.cookie, Buffer.from([1, 2, 3])), 0)
t.end()
})
@ -55,7 +55,7 @@ test('tober', function (t) {
t.equal(c.type, '1.2.840.113556.1.4.319')
t.ok(c.criticality)
t.equal(c.value.size, 20)
t.is(Buffer.compare(c.value.cookie, Buffer.alloc(0)), 0)
t.equal(Buffer.compare(c.value.cookie, Buffer.alloc(0)), 0)
t.end()
})

View File

@ -171,15 +171,15 @@ test('format persists across clone', function (t) {
const OUT = 'UID="user", CN=foo+SN=bar, DC=test, DC=com'
_dn.setFormat({ keepQuote: true, upperName: true })
const clone = _dn.clone()
t.equals(_dn.toString(), OUT)
t.equals(clone.toString(), OUT)
t.equal(_dn.toString(), OUT)
t.equal(clone.toString(), OUT)
t.end()
})
test('initialization', function (t) {
const dn1 = new dn.DN()
t.ok(dn1)
t.equals(dn1.toString(), '')
t.equal(dn1.toString(), '')
t.ok(dn1.isEmpty(), 'DN with no initializer defaults to null DN')
const data = [
@ -188,7 +188,7 @@ test('initialization', function (t) {
]
const dn2 = new dn.DN(data)
t.ok(dn2)
t.equals(dn2.toString(), 'foo=bar, o=base')
t.equal(dn2.toString(), 'foo=bar, o=base')
t.ok(!dn2.isEmpty())
t.end()

View File

@ -14,62 +14,69 @@ function search (t, options, callback) {
found = true
})
res.on('end', function () {
t.true(found)
t.ok(found)
if (callback) return callback()
return t.end()
})
})
}
tap.beforeEach((done, t) => {
const suffix = `dc=${uuid()}`
const server = ldap.createServer()
tap.beforeEach((t) => {
return new Promise((resolve, reject) => {
const suffix = `dc=${uuid()}`
const server = ldap.createServer()
t.context.server = server
t.context.socketPath = getSock()
t.context.suffix = suffix
t.context.server = server
t.context.socketPath = getSock()
t.context.suffix = suffix
server.bind('cn=root', function (req, res, next) {
res.end()
return next()
})
server.bind('cn=root', function (req, res, next) {
res.end()
return next()
})
server.search(suffix, function (req, res) {
const entry = {
dn: 'cn=foo, ' + suffix,
attributes: {
objectclass: ['person', 'top'],
cn: 'Pogo Stick',
sn: 'Stick',
givenname: 'ogo',
mail: uuid() + '@pogostick.org'
server.search(suffix, function (req, res) {
const entry = {
dn: 'cn=foo, ' + suffix,
attributes: {
objectclass: ['person', 'top'],
cn: 'Pogo Stick',
sn: 'Stick',
givenname: 'ogo',
mail: uuid() + '@pogostick.org'
}
}
}
if (req.filter.matches(entry.attributes)) { res.send(entry) }
if (req.filter.matches(entry.attributes)) { res.send(entry) }
res.end()
})
server.listen(t.context.socketPath, function () {
t.context.client = ldap.createClient({
socketPath: t.context.socketPath
res.end()
})
t.context.client.on('connectError', (err) => {
t.context.server.close(() => done(err))
})
t.context.client.on('connect', (socket) => {
t.context.socket = socket
done()
server.listen(t.context.socketPath, function () {
t.context.client = ldap.createClient({
socketPath: t.context.socketPath
})
t.context.client.on('connectError', (err) => {
t.context.server.close(() => reject(err))
})
t.context.client.on('connect', (socket) => {
t.context.socket = socket
resolve()
})
})
})
})
tap.afterEach((done, t) => {
if (!t.context.client) return done()
t.context.client.unbind(() => {
t.context.server.close(done)
tap.afterEach((t) => {
return new Promise((resolve, reject) => {
if (!t.context.client) return resolve()
t.context.client.unbind(() => {
t.context.server.close((err) => {
if (err) return reject(err)
resolve()
})
})
})
})

View File

@ -8,40 +8,40 @@ test('comp > (ref in upper window) => true', async t => {
const ref = Math.floor(MAX_MSGID / 2) + 10
const comp = ref + 10
const result = geWindow(ref, comp)
t.is(result, true)
t.equal(result, true)
})
test('comp < (ref in upper window) => false', async t => {
const ref = Math.floor(MAX_MSGID / 2) + 10
const comp = ref - 5
const result = geWindow(ref, comp)
t.is(result, false)
t.equal(result, false)
})
test('comp > (ref in lower window) => true', async t => {
const ref = Math.floor(MAX_MSGID / 2) - 10
const comp = ref + 20
const result = geWindow(ref, comp)
t.is(result, true)
t.equal(result, true)
})
test('comp < (ref in lower window) => false', async t => {
const ref = Math.floor(MAX_MSGID / 2) - 10
const comp = ref - 5
const result = geWindow(ref, comp)
t.is(result, false)
t.equal(result, false)
})
test('(max === MAX_MSGID) && (comp > ref) => true', async t => {
const ref = MAX_MSGID - Math.floor(MAX_MSGID / 2)
const comp = ref + 1
const result = geWindow(ref, comp)
t.is(result, true)
t.equal(result, true)
})
test('(max === MAX_MSGID) && (comp < ref) => false', async t => {
const ref = MAX_MSGID - Math.floor(MAX_MSGID / 2)
const comp = ref - 1
const result = geWindow(ref, comp)
t.is(result, false)
t.equal(result, false)
})

View File

@ -7,15 +7,15 @@ const idGeneratorFactory = require('../../../../lib/client/message-tracker/id-ge
test('starts at 0', async t => {
const nextID = idGeneratorFactory()
const currentID = nextID()
t.is(currentID, 1)
t.equal(currentID, 1)
})
test('handles wrapping around', async t => {
const nextID = idGeneratorFactory(MAX_MSGID - 2)
let currentID = nextID()
t.is(currentID, MAX_MSGID - 1)
t.equal(currentID, MAX_MSGID - 1)
currentID = nextID()
t.is(currentID, 1)
t.equal(currentID, 1)
})

View File

@ -76,13 +76,13 @@ tap.test('options', t => {
tap.test('.pending', t => {
t.test('returns 0 for no messages', async t => {
const tracker = messageTrackerFactory({ id: 'foo', parser: {} })
t.is(tracker.pending, 0)
t.equal(tracker.pending, 0)
})
t.test('returns 1 for 1 message', async t => {
const tracker = messageTrackerFactory({ id: 'foo', parser: {} })
tracker.track({}, () => {})
t.is(tracker.pending, 1)
t.equal(tracker.pending, 1)
})
t.end()
@ -92,14 +92,14 @@ tap.test('#abandon', t => {
t.test('returns false if message does not exist', async t => {
const tracker = messageTrackerFactory({ id: 'foo', parser: {} })
const result = tracker.abandon(1)
t.is(result, false)
t.equal(result, false)
})
t.test('returns true if message is abandoned', async t => {
const tracker = messageTrackerFactory({ id: 'foo', parser: {} })
tracker.track({}, {})
const result = tracker.abandon(1)
t.is(result, true)
t.equal(result, true)
})
t.end()
@ -110,7 +110,7 @@ tap.test('#fetch', t => {
const tracker = messageTrackerFactory({ id: 'foo', parser: {} })
tracker.track({}, handler)
const fetched = tracker.fetch(1)
t.is(fetched, handler)
t.equal(fetched, handler)
function handler () {}
})
@ -121,7 +121,7 @@ tap.test('#fetch', t => {
tracker.track({ abandon: 'message' }, () => {})
tracker.abandon(1)
const fetched = tracker.fetch(1)
t.is(fetched, handler)
t.equal(fetched, handler)
function handler () {}
})
@ -129,7 +129,7 @@ tap.test('#fetch', t => {
t.test('returns null when message does not exist', async t => {
const tracker = messageTrackerFactory({ id: 'foo', parser: {} })
const fetched = tracker.fetch(1)
t.is(fetched, null)
t.equal(fetched, null)
})
t.end()
@ -146,13 +146,13 @@ tap.test('#purge', t => {
function cb (msgID, handler) {
if (count === 0) {
t.is(msgID, 1)
t.is(handler, handler1)
t.equal(msgID, 1)
t.equal(handler, handler1)
count += 1
return
}
t.is(msgID, 2)
t.is(handler, handler2)
t.equal(msgID, 2)
t.equal(handler, handler2)
}
function handler1 () {}
@ -167,7 +167,7 @@ tap.test('#remove', t => {
const tracker = messageTrackerFactory({ id: 'foo', parser: {} })
tracker.track({}, () => {})
tracker.remove(1)
t.is(tracker.pending, 0)
t.equal(tracker.pending, 0)
})
// Not a great test. It exercises the desired code path, but we probably
@ -178,7 +178,7 @@ tap.test('#remove', t => {
tracker.track({ abandon: 'message' }, () => {})
tracker.abandon(1)
tracker.remove(1)
t.is(tracker.pending, 1)
t.equal(tracker.pending, 1)
})
t.end()
@ -190,9 +190,9 @@ tap.test('#track', t => {
const msg = {}
tracker.track(msg, handler)
t.deepEqual(msg, { messageID: 1 })
t.same(msg, { messageID: 1 })
const cb = tracker.fetch(1)
t.is(cb, handler)
t.equal(cb, handler)
function handler () {}
})

View File

@ -10,11 +10,11 @@ test('clears queue if only one message present', async t => {
abandoned.set(1, { age: 2, cb })
purgeAbandoned(2, abandoned)
t.is(abandoned.size, 0)
t.equal(abandoned.size, 0)
function cb (err) {
t.is(err.name, 'AbandonedError')
t.is(err.message, 'client request abandoned')
t.equal(err.name, 'AbandonedError')
t.equal(err.message, 'client request abandoned')
}
})
@ -25,11 +25,11 @@ test('clears queue if multiple messages present', async t => {
abandoned.set(2, { age: 3, cb })
purgeAbandoned(4, abandoned)
t.is(abandoned.size, 0)
t.equal(abandoned.size, 0)
function cb (err) {
t.is(err.name, 'AbandonedError')
t.is(err.message, 'client request abandoned')
t.equal(err.name, 'AbandonedError')
t.equal(err.message, 'client request abandoned')
}
})
@ -42,11 +42,11 @@ test('message id has wrappred around', async t => {
// that is triggering the purge was the "first" message in the new sequence
// of message identifiers.
purgeAbandoned(1, abandoned)
t.is(abandoned.size, 0)
t.equal(abandoned.size, 0)
function cb (err) {
t.is(err.name, 'AbandonedError')
t.is(err.message, 'client request abandoned')
t.equal(err.name, 'AbandonedError')
t.equal(err.message, 'client request abandoned')
}
})
@ -56,7 +56,7 @@ test('does not clear if window not met', async t => {
abandoned.set(1, { age: 2, cb })
purgeAbandoned(1, abandoned)
t.is(abandoned.size, 1)
t.equal(abandoned.size, 1)
function cb () {
t.fail('should not be invoked')

View File

@ -6,13 +6,13 @@ const enqueue = require('../../../../lib/client/request-queue/enqueue')
test('rejects new requests if size is exceeded', async t => {
const q = { _queue: { length: 5 }, size: 5 }
const result = enqueue.call(q, 'foo', 'bar', {}, {})
t.false(result)
t.notOk(result)
})
test('rejects new requests if queue is frozen', async t => {
const q = { _queue: { length: 0 }, size: 5, _frozen: true }
const result = enqueue.call(q, 'foo', 'bar', {}, {})
t.false(result)
t.notOk(result)
})
test('adds a request and returns if no timeout', async t => {
@ -20,7 +20,7 @@ test('adds a request and returns if no timeout', async t => {
_queue: {
length: 0,
add (obj) {
t.deepEqual(obj, {
t.same(obj, {
message: 'foo',
expect: 'bar',
emitter: 'baz',
@ -32,7 +32,7 @@ test('adds a request and returns if no timeout', async t => {
timeout: 0
}
const result = enqueue.call(q, 'foo', 'bar', 'baz', 'bif')
t.true(result)
t.ok(result)
})
test('adds a request and returns timer not set', async t => {
@ -40,7 +40,7 @@ test('adds a request and returns timer not set', async t => {
_queue: {
length: 0,
add (obj) {
t.deepEqual(obj, {
t.same(obj, {
message: 'foo',
expect: 'bar',
emitter: 'baz',
@ -53,7 +53,7 @@ test('adds a request and returns timer not set', async t => {
_timer: null
}
const result = enqueue.call(q, 'foo', 'bar', 'baz', 'bif')
t.true(result)
t.ok(result)
})
test('adds a request, returns true, and clears queue', t => {
@ -63,7 +63,7 @@ test('adds a request, returns true, and clears queue', t => {
_queue: {
length: 0,
add (obj) {
t.deepEqual(obj, {
t.same(obj, {
message: 'foo',
expect: 'bar',
emitter: 'baz',
@ -78,5 +78,5 @@ test('adds a request, returns true, and clears queue', t => {
purge () { t.pass() }
}
const result = enqueue.call(q, 'foo', 'bar', 'baz', 'bif')
t.true(result)
t.ok(result)
})

View File

@ -17,7 +17,7 @@ test('clears timer', async t => {
}
}
flush.call(q)
t.is(q._timer, null)
t.equal(q._timer, null)
})
test('invokes callback with parameters', async t => {
@ -40,12 +40,12 @@ test('invokes callback with parameters', async t => {
}
}
flush.call(q, (message, expect, emitter, cb) => {
t.is(message, 'foo')
t.is(expect, 'bar')
t.is(emitter, 'baz')
t.is(cb, theCB)
t.equal(message, 'foo')
t.equal(expect, 'bar')
t.equal(emitter, 'baz')
t.equal(cb, theCB)
})
t.is(q._timer, null)
t.equal(q._timer, null)
function theCB () {}
})

View File

@ -9,8 +9,8 @@ test('flushes the queue with timeout errors', async t => {
flush (func) {
func('a', 'b', 'c', (err) => {
t.ok(err)
t.is(err.name, 'TimeoutError')
t.is(err.message, 'request queue timeout')
t.equal(err.name, 'TimeoutError')
t.equal(err.message, 'request queue timeout')
})
}
}

View File

@ -17,9 +17,9 @@ test('new with args', function (t) {
t.ok(req)
t.equal(req.requestName, '1.2.3.4')
t.equal(req.requestValue, 'test')
t.is(Buffer.compare(req.requestValueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(Buffer.compare(req.requestValueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(req.value, 'test')
t.is(Buffer.compare(req.valueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(Buffer.compare(req.valueBuffer, Buffer.from('test', 'utf8')), 0)
t.end()
})
@ -31,9 +31,9 @@ test('new with buffer args', function (t) {
t.ok(req)
t.equal(req.requestName, '1.2.3.4')
t.equal(req.requestValue, req.requestValueBuffer)
t.is(Buffer.compare(req.requestValueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(Buffer.compare(req.requestValueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(req.value, req.valueBuffer)
t.is(Buffer.compare(req.valueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(Buffer.compare(req.valueBuffer, Buffer.from('test', 'utf8')), 0)
t.end()
})
@ -46,9 +46,9 @@ test('new no args set args', function (t) {
req.value = 'test'
t.equal(req.requestValue, 'test')
t.is(Buffer.compare(req.requestValueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(Buffer.compare(req.requestValueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(req.value, 'test')
t.is(Buffer.compare(req.valueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(Buffer.compare(req.valueBuffer, Buffer.from('test', 'utf8')), 0)
t.end()
})
@ -62,9 +62,9 @@ test('new no args set args buffer', function (t) {
req.value = Buffer.from('test', 'utf8')
t.equal(req.requestValue, req.requestValueBuffer)
t.is(Buffer.compare(req.requestValueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(Buffer.compare(req.requestValueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(req.value, req.valueBuffer)
t.is(Buffer.compare(req.valueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(Buffer.compare(req.valueBuffer, Buffer.from('test', 'utf8')), 0)
t.end()
})
@ -78,9 +78,9 @@ test('parse', function (t) {
t.ok(req._parse(new BerReader(ber.buffer)))
t.equal(req.requestName, '1.2.3.4')
t.equal(req.requestValue, 'test')
t.is(Buffer.compare(req.requestValueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(Buffer.compare(req.requestValueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(req.value, 'test')
t.is(Buffer.compare(req.valueBuffer, Buffer.from('test', 'utf8')), 0)
t.equal(Buffer.compare(req.valueBuffer, Buffer.from('test', 'utf8')), 0)
t.end()
})

View File

@ -8,11 +8,10 @@ const ldap = require('../lib')
const SERVER_PORT = process.env.SERVER_PORT || 1389
const SUFFIX = 'dc=test'
tap.beforeEach(function (done, t) {
tap.beforeEach(function (t) {
// We do not need a `.afterEach` to clean up the sock files because that
// is done when the server is destroyed.
t.context.sock = getSock()
done()
})
tap.test('basic create', function (t) {
@ -76,7 +75,7 @@ tap.test('listen on static port', function (t) {
server.listen(SERVER_PORT, '127.0.0.1', function () {
const addr = server.address()
t.equal(addr.port, parseInt(SERVER_PORT, 10))
t.equals(server.url, `ldap://127.0.0.1:${SERVER_PORT}`)
t.equal(server.url, `ldap://127.0.0.1:${SERVER_PORT}`)
server.close(() => t.end())
})
})