Skip to content

Commit

Permalink
fix: types and tests coverage (#110)
Browse files Browse the repository at this point in the history
* 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 <climba03003@gmail.com>

* fix: apply @climba03003 suggestion

Co-authored-by: KaKa <climba03003@gmail.com>

* 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 <climba03003@gmail.com>
  • Loading branch information
darkgl0w and climba03003 authored Sep 26, 2021
1 parent 6ac0dac commit 089deba
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 44 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,7 @@ yarn.lock

# editor files
.vscode
.idea
.idea

# test tap report
out.tap
2 changes: 1 addition & 1 deletion .taprc
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ jsx: false
flow: false
jobs: 1
coverage: true
check-coverage: false
check-coverage: true
19 changes: 14 additions & 5 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import { FastifyPluginCallback } from 'fastify';
import { Redis, RedisOptions } from 'ioredis';

export interface FastifyRedisNamespacedInstance {
[namespace: string]: Redis;
}

export type FastifyRedis = FastifyRedisNamespacedInstance & Redis;

declare module 'fastify' {
interface FastifyInstance {
redis: Redis;
redis: FastifyRedis;
}
}

export type FastifyRedisPlugin = RedisOptions &
export type FastifyRedisPluginOptions = (RedisOptions &
{
url?: string;
namespace?: string;
} |
{
}) | {
client: Redis;
namespace?: string;
closeClient?: boolean;
}

declare const fastifyRedis: FastifyPluginCallback<FastifyRedisPlugin>;
/**
* @deprecated Use `FastifyRedisPluginOptions` instead
*/
export type FastifyRedisPlugin = FastifyRedisPluginOptions;

declare const fastifyRedis: FastifyPluginCallback<FastifyRedisPluginOptions>;
export default fastifyRedis;
4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function fastifyRedis (fastify, options, next) {

if (namespace) {
if (!fastify.redis) {
fastify.decorate('redis', {})
fastify.decorate('redis', Object.create(null))
}

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

const onError = function (err) {
// Swallow network errors to allow ioredis
// to preform reconnection and emit 'end'
// to perform reconnection and emit 'end'
// event if reconnection eventually
// fails.
// Any other errors during startup will
Expand Down
19 changes: 11 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
"types": "index.d.ts",
"scripts": {
"lint": "standard",
"lint:fix": "standard --fix",
"redis": "docker run -p 6379:6379 --rm redis:5",
"test": "npm run lint && npm run unit && npm run typescript",
"typescript": "tsd",
"unit": "tap test/test.js"
"unit": "tap test/test.js",
"unit:report": "tap test/test.js --cov --coverage-report=html --coverage-report=cobertura",
"unit:verbose": "tap test/test.js -Rspec"
},
"repository": {
"type": "git",
Expand All @@ -30,18 +33,18 @@
},
"homepage": "https://github.com/fastify/fastify-redis#readme",
"devDependencies": {
"@types/ioredis": "^4.19.3",
"@types/node": "^16.0.0",
"fastify": "^3.11.0",
"@types/ioredis": "^4.27.4",
"@types/node": "^16.9.6",
"fastify": "^3.21.6",
"proxyquire": "^2.1.3",
"redis": "^3.0.2",
"standard": "^16.0.0",
"tap": "^15.0.2",
"redis": "^3.1.2",
"standard": "^16.0.3",
"tap": "^15.0.10",
"tsd": "^0.17.0"
},
"dependencies": {
"fastify-plugin": "^3.0.0",
"ioredis": "^4.22.0"
"ioredis": "^4.27.9"
},
"tsd": {
"directory": "test/types"
Expand Down
71 changes: 71 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -460,3 +460,74 @@ test('Should throw authentication error when trying to connect on a valid host w
})
})
})

test('Should successfully create a Redis client when registered with a `url` option and without a `client` option in a namespaced instance', async t => {
t.plan(2)

const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))

await fastify.register(fastifyRedis, {
url: 'redis://127.0.0.1',
namespace: 'test'
})

await fastify.ready()
t.ok(fastify.redis)
t.ok(fastify.redis.test)
})

test('Should be able to register multiple namespaced fastify-redis instances', async t => {
t.plan(3)

const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))

await fastify.register(fastifyRedis, {
url: 'redis://127.0.0.1',
namespace: 'one'
})

await fastify.register(fastifyRedis, {
url: 'redis://127.0.0.1',
namespace: 'two'
})

await fastify.ready()
t.ok(fastify.redis)
t.ok(fastify.redis.one)
t.ok(fastify.redis.two)
})

test('Should throw when fastify-redis is initialized with an option that makes Redis throw', (t) => {
t.plan(1)

const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))

// This will throw a `TypeError: this.options.Connector is not a constructor`
fastify.register(fastifyRedis, {
Connector: 'should_fail'
})

fastify.ready(err => {
t.ok(err)
})
})

test('Should throw when fastify-redis is initialized with a namespace and an option that makes Redis throw', (t) => {
t.plan(1)

const fastify = Fastify()
t.teardown(fastify.close.bind(fastify))

// This will throw a `TypeError: this.options.Connector is not a constructor`
fastify.register(fastifyRedis, {
Connector: 'should_fail',
namespace: 'fail'
})

fastify.ready(err => {
t.ok(err)
})
})
59 changes: 32 additions & 27 deletions test/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
import Fastify, { FastifyRequest } from 'fastify';
import fastifyRedis from '../..';
import IORedis from 'ioredis';
import Fastify, { FastifyInstance } from 'fastify'
import IORedis, { Redis } from 'ioredis'
import { expectAssignable, expectError, expectType } from 'tsd'
import fastifyRedis, { FastifyRedis, FastifyRedisNamespacedInstance } from '../..'

const app = Fastify();
const redis = new IORedis({ host: 'localhost', port: 6379 });
const app: FastifyInstance = Fastify()
const redis: Redis = new IORedis({ host: 'localhost', port: 6379 })

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

app.get('/foo', (req: FastifyRequest, reply) => {
const { redis } = app;
const query = req.query as {
key: string
}
redis.get(query.key, (err, val) => {
reply.send(err || val);
});
});
app.register(fastifyRedis, {
client: redis,
closeClient: true,
namespace: 'one'
})

app.post('/foo', (req, reply) => {
const { redis } = app;
const body = req.body as {
key: string,
value: string
}
redis.set(body.key, body.value, err => {
reply.send(err || { status: 'ok' });
});
});
app.register(fastifyRedis, {
keepAlive: 0,
namespace: 'two',
url: 'redis://127.0.0.1:6379'
})

expectError(app.register(fastifyRedis, {
namespace: 'three',
unknownOption: 'this should trigger a typescript error'
}))

// Plugin property available
app.after(() => {
expectAssignable<Redis>(app.redis)
expectType<FastifyRedis>(app.redis)

expectAssignable<FastifyRedisNamespacedInstance>(app.redis)
expectType<Redis>(app.redis.one)
expectType<Redis>(app.redis.two)
})

0 comments on commit 089deba

Please sign in to comment.