Skip to content

Commit 089deba

Browse files
fix: types and tests coverage (#110)
* chore: upgrade package dependencies * test: add one more test case * feat (types) !: add namespaced redis instances + explicit naming * refactor: fix a typo * refactor: initialize redis decorator with `Object.create(null)` * chore: add a `lint:fix` command * chore: add a `unit:report` and a `unit:verbose` command * refactor (test/types): actually test our types * test: add one more test case * refactor (types): revert `FastifyRedisPluginOptions` to `FastifyRedisPlugin` name * fix: apply @climba03003 suggestion Co-authored-by: KaKa <[email protected]> * fix: apply @climba03003 suggestion Co-authored-by: KaKa <[email protected]> * test: add 2 more tests to achieve 100% code coverage * chore: check coverage with tap * chore: add test tap report to .gitignore * refactor (types): deprecate `FastifyRedisPlugin` and use `FastifyRedisPluginOptions` instead Co-authored-by: KaKa <[email protected]>
1 parent 6ac0dac commit 089deba

File tree

7 files changed

+135
-44
lines changed

7 files changed

+135
-44
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,7 @@ yarn.lock
127127

128128
# editor files
129129
.vscode
130-
.idea
130+
.idea
131+
132+
# test tap report
133+
out.tap

.taprc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ jsx: false
33
flow: false
44
jobs: 1
55
coverage: true
6-
check-coverage: false
6+
check-coverage: true

index.d.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
11
import { FastifyPluginCallback } from 'fastify';
22
import { Redis, RedisOptions } from 'ioredis';
33

4+
export interface FastifyRedisNamespacedInstance {
5+
[namespace: string]: Redis;
6+
}
7+
8+
export type FastifyRedis = FastifyRedisNamespacedInstance & Redis;
9+
410
declare module 'fastify' {
511
interface FastifyInstance {
6-
redis: Redis;
12+
redis: FastifyRedis;
713
}
814
}
915

10-
export type FastifyRedisPlugin = RedisOptions &
16+
export type FastifyRedisPluginOptions = (RedisOptions &
1117
{
1218
url?: string;
1319
namespace?: string;
14-
} |
15-
{
20+
}) | {
1621
client: Redis;
1722
namespace?: string;
1823
closeClient?: boolean;
1924
}
2025

21-
declare const fastifyRedis: FastifyPluginCallback<FastifyRedisPlugin>;
26+
/**
27+
* @deprecated Use `FastifyRedisPluginOptions` instead
28+
*/
29+
export type FastifyRedisPlugin = FastifyRedisPluginOptions;
2230

31+
declare const fastifyRedis: FastifyPluginCallback<FastifyRedisPluginOptions>;
2332
export default fastifyRedis;

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function fastifyRedis (fastify, options, next) {
1010

1111
if (namespace) {
1212
if (!fastify.redis) {
13-
fastify.decorate('redis', {})
13+
fastify.decorate('redis', Object.create(null))
1414
}
1515

1616
if (fastify.redis[namespace]) {
@@ -84,7 +84,7 @@ function fastifyRedis (fastify, options, next) {
8484

8585
const onError = function (err) {
8686
// Swallow network errors to allow ioredis
87-
// to preform reconnection and emit 'end'
87+
// to perform reconnection and emit 'end'
8888
// event if reconnection eventually
8989
// fails.
9090
// Any other errors during startup will

package.json

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
"types": "index.d.ts",
77
"scripts": {
88
"lint": "standard",
9+
"lint:fix": "standard --fix",
910
"redis": "docker run -p 6379:6379 --rm redis:5",
1011
"test": "npm run lint && npm run unit && npm run typescript",
1112
"typescript": "tsd",
12-
"unit": "tap test/test.js"
13+
"unit": "tap test/test.js",
14+
"unit:report": "tap test/test.js --cov --coverage-report=html --coverage-report=cobertura",
15+
"unit:verbose": "tap test/test.js -Rspec"
1316
},
1417
"repository": {
1518
"type": "git",
@@ -30,18 +33,18 @@
3033
},
3134
"homepage": "https://github.com/fastify/fastify-redis#readme",
3235
"devDependencies": {
33-
"@types/ioredis": "^4.19.3",
34-
"@types/node": "^16.0.0",
35-
"fastify": "^3.11.0",
36+
"@types/ioredis": "^4.27.4",
37+
"@types/node": "^16.9.6",
38+
"fastify": "^3.21.6",
3639
"proxyquire": "^2.1.3",
37-
"redis": "^3.0.2",
38-
"standard": "^16.0.0",
39-
"tap": "^15.0.2",
40+
"redis": "^3.1.2",
41+
"standard": "^16.0.3",
42+
"tap": "^15.0.10",
4043
"tsd": "^0.17.0"
4144
},
4245
"dependencies": {
4346
"fastify-plugin": "^3.0.0",
44-
"ioredis": "^4.22.0"
47+
"ioredis": "^4.27.9"
4548
},
4649
"tsd": {
4750
"directory": "test/types"

test/test.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,3 +460,74 @@ test('Should throw authentication error when trying to connect on a valid host w
460460
})
461461
})
462462
})
463+
464+
test('Should successfully create a Redis client when registered with a `url` option and without a `client` option in a namespaced instance', async t => {
465+
t.plan(2)
466+
467+
const fastify = Fastify()
468+
t.teardown(fastify.close.bind(fastify))
469+
470+
await fastify.register(fastifyRedis, {
471+
url: 'redis://127.0.0.1',
472+
namespace: 'test'
473+
})
474+
475+
await fastify.ready()
476+
t.ok(fastify.redis)
477+
t.ok(fastify.redis.test)
478+
})
479+
480+
test('Should be able to register multiple namespaced fastify-redis instances', async t => {
481+
t.plan(3)
482+
483+
const fastify = Fastify()
484+
t.teardown(fastify.close.bind(fastify))
485+
486+
await fastify.register(fastifyRedis, {
487+
url: 'redis://127.0.0.1',
488+
namespace: 'one'
489+
})
490+
491+
await fastify.register(fastifyRedis, {
492+
url: 'redis://127.0.0.1',
493+
namespace: 'two'
494+
})
495+
496+
await fastify.ready()
497+
t.ok(fastify.redis)
498+
t.ok(fastify.redis.one)
499+
t.ok(fastify.redis.two)
500+
})
501+
502+
test('Should throw when fastify-redis is initialized with an option that makes Redis throw', (t) => {
503+
t.plan(1)
504+
505+
const fastify = Fastify()
506+
t.teardown(fastify.close.bind(fastify))
507+
508+
// This will throw a `TypeError: this.options.Connector is not a constructor`
509+
fastify.register(fastifyRedis, {
510+
Connector: 'should_fail'
511+
})
512+
513+
fastify.ready(err => {
514+
t.ok(err)
515+
})
516+
})
517+
518+
test('Should throw when fastify-redis is initialized with a namespace and an option that makes Redis throw', (t) => {
519+
t.plan(1)
520+
521+
const fastify = Fastify()
522+
t.teardown(fastify.close.bind(fastify))
523+
524+
// This will throw a `TypeError: this.options.Connector is not a constructor`
525+
fastify.register(fastifyRedis, {
526+
Connector: 'should_fail',
527+
namespace: 'fail'
528+
})
529+
530+
fastify.ready(err => {
531+
t.ok(err)
532+
})
533+
})

test/types/index.ts

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,36 @@
1-
import Fastify, { FastifyRequest } from 'fastify';
2-
import fastifyRedis from '../..';
3-
import IORedis from 'ioredis';
1+
import Fastify, { FastifyInstance } from 'fastify'
2+
import IORedis, { Redis } from 'ioredis'
3+
import { expectAssignable, expectError, expectType } from 'tsd'
4+
import fastifyRedis, { FastifyRedis, FastifyRedisNamespacedInstance } from '../..'
45

5-
const app = Fastify();
6-
const redis = new IORedis({ host: 'localhost', port: 6379 });
6+
const app: FastifyInstance = Fastify()
7+
const redis: Redis = new IORedis({ host: 'localhost', port: 6379 })
78

8-
app.register(fastifyRedis, { host: '127.0.0.1' });
9-
app.register(fastifyRedis, { client: redis, namespace: 'hello', closeClient: true });
10-
app.register(fastifyRedis, { url: 'redis://127.0.0.1:6379', keepAlive: 0 });
9+
app.register(fastifyRedis, { host: '127.0.0.1' })
1110

12-
app.get('/foo', (req: FastifyRequest, reply) => {
13-
const { redis } = app;
14-
const query = req.query as {
15-
key: string
16-
}
17-
redis.get(query.key, (err, val) => {
18-
reply.send(err || val);
19-
});
20-
});
11+
app.register(fastifyRedis, {
12+
client: redis,
13+
closeClient: true,
14+
namespace: 'one'
15+
})
2116

22-
app.post('/foo', (req, reply) => {
23-
const { redis } = app;
24-
const body = req.body as {
25-
key: string,
26-
value: string
27-
}
28-
redis.set(body.key, body.value, err => {
29-
reply.send(err || { status: 'ok' });
30-
});
31-
});
17+
app.register(fastifyRedis, {
18+
keepAlive: 0,
19+
namespace: 'two',
20+
url: 'redis://127.0.0.1:6379'
21+
})
22+
23+
expectError(app.register(fastifyRedis, {
24+
namespace: 'three',
25+
unknownOption: 'this should trigger a typescript error'
26+
}))
27+
28+
// Plugin property available
29+
app.after(() => {
30+
expectAssignable<Redis>(app.redis)
31+
expectType<FastifyRedis>(app.redis)
32+
33+
expectAssignable<FastifyRedisNamespacedInstance>(app.redis)
34+
expectType<Redis>(app.redis.one)
35+
expectType<Redis>(app.redis.two)
36+
})

0 commit comments

Comments
 (0)