From 374641c6945311df9973c9af0493d2379de85b51 Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Sun, 21 Apr 2024 11:39:48 +0800 Subject: [PATCH 1/3] test: improve coverage --- package.json | 2 - test/scripts/hexo.ts | 261 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 237 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 5f454c62..13e904dd 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,6 @@ "@types/minimist": "^1.2.5", "@types/mocha": "^10.0.6", "@types/node": "^18.11.8", - "@types/proxyquire": "^1.3.31", "@types/rewire": "^2.5.30", "@types/sinon": "^17.0.3", "chai": "^4.3.4", @@ -70,7 +69,6 @@ "hexo-renderer-marked": "^6.0.0", "mocha": "^10.0.0", "nyc": "^15.1.0", - "proxyquire": "^2.1.3", "rewire": "^6.0.0", "sinon": "^17.0.1", "ts-node": "^10.9.1", diff --git a/test/scripts/hexo.ts b/test/scripts/hexo.ts index 2b4b1f04..812450fd 100644 --- a/test/scripts/hexo.ts +++ b/test/scripts/hexo.ts @@ -1,8 +1,7 @@ import chai from 'chai'; import sinon from 'sinon'; -import proxyquire from 'proxyquire'; -import { writeFile, unlink, rmdir } from 'hexo-fs'; -import { join } from 'path'; +import rewire from 'rewire'; +import ConsoleExtend from '../../lib/extend/console'; chai.should(); require('chai').should(); @@ -12,47 +11,261 @@ describe('hexo', () => { it('run help if no specified command', async () => { const spy = sinon.spy(); - const hexo = proxyquire('../../dist/hexo', { - './console'(ctx) { - ctx.extend.console.register('help', spy); + const hexo = rewire('../../dist/hexo'); + return hexo.__with__({ + console_1: { + default: ctx => { + ctx.extend.console.register('help', spy); + } } + })(async () => { + // @ts-ignore + await hexo(cwd, {_: []}); + spy.calledOnce.should.be.true; }); - - await hexo(cwd, {_: []}); - spy.calledOnce.should.be.true; }); it('run specified command', async () => { const spy = sinon.spy(); - const hexo = proxyquire('../../dist/hexo', { - './console'(ctx) { - ctx.extend.console.register('test', spy); + const hexo = rewire('../../dist/hexo'); + return hexo.__with__({ + console_1: { + default: ctx => { + ctx.extend.console.register('test', spy); + } } + })(async () => { + // @ts-ignore + await hexo(cwd, {_: ['test']}); + spy.calledOnce.should.be.true; }); - - await hexo(cwd, {_: ['test']}); - spy.calledOnce.should.be.true; }); it('run help if specified command not found', async () => { const spy = sinon.spy(); - const hexo = proxyquire('../../dist/hexo', { - './console'(ctx) { - ctx.extend.console.register('help', spy); + const hexo = rewire('../../dist/hexo'); + return hexo.__with__({ + console_1: { + default: ctx => { + ctx.extend.console.register('help', spy); + } + } + })(async () => { + // @ts-ignore + await hexo(cwd, {_: ['test']}); + spy.calledOnce.should.be.true; + }); + }); + + it('path - number (issue hexo#4334)', async () => { + let args; + const hexo = rewire('../../dist/hexo'); + return hexo.__with__({ + find_pkg_1: { + default: (_cwd, _args) => { + args = _args; + return Promise.resolve(); + } + } + })(async () => { + process.argv = ['hexo', 'new', '--path', '123', 'test']; + // @ts-ignore + hexo(null, null); + args.path.should.eql('123'); + process.argv = []; + }); + }); + + it('p - number (issue hexo#4334)', async () => { + let args; + const hexo = rewire('../../dist/hexo'); + return hexo.__with__({ + find_pkg_1: { + default: (_cwd, _args) => { + args = _args; + return Promise.resolve(); + } } + })(async () => { + process.argv = ['hexo', 'new', '-p', '123', 'test']; + // @ts-ignore + hexo(null, null); + args.p.should.eql('123'); + process.argv = []; }); + }); - await hexo(cwd, {_: ['test']}); - spy.calledOnce.should.be.true; + it('slug - number (issue hexo#4334)', async () => { + let args; + const hexo = rewire('../../dist/hexo'); + return hexo.__with__({ + find_pkg_1: { + default: (_cwd, _args) => { + args = _args; + return Promise.resolve(); + } + } + })(async () => { + process.argv = ['hexo', 'new', '--slug', '123', 'test']; + // @ts-ignore + hexo(null, null); + args.slug.should.eql('123'); + process.argv = []; + }); + }); + + it('s - number (issue hexo#4334)', async () => { + let args; + const hexo = rewire('../../dist/hexo'); + return hexo.__with__({ + find_pkg_1: { + default: (_cwd, _args) => { + args = _args; + return Promise.resolve(); + } + } + })(async () => { + process.argv = ['hexo', 'new', '-s', '123', 'test']; + // @ts-ignore + hexo(null, null); + args.s.should.eql('123'); + process.argv = []; + }); }); it('should call init() method'); - it('should handle error properly'); + it('should handle HexoNotFoundError properly', () => { + const spy = sinon.spy(); + const hexo = rewire('../../dist/hexo'); + const dummyPath = 'dummy'; + const dummyError = 'test'; + return hexo.__with__({ + find_pkg_1: { + default: () => Promise.resolve(dummyPath) + }, + loadModule: () => Promise.reject(new Error(dummyError)), + context_1: { + default: class Context { + log: { error: typeof spy }; + constructor() { + this.log = { + error: spy + }; + } + } + } + })(async () => { + // @ts-ignore + await hexo(cwd, {_: ['test']}); + spy.args[0][0].should.eql(dummyError); + spy.args[1][0].should.eql('Local hexo loading failed in %s'); + spy.args[1][1].should.eql(`\x1B[35m${dummyPath}\x1B[39m`); + spy.args[2][0].should.eql('Try running: \'rm -rf node_modules && npm install --force\''); + process.exitCode?.should.eql(2); + }); + }); - it('should watch SIGINT signal'); + it('should handle other Error properly', () => { + const spy = sinon.spy(); + const hexo = rewire('../../dist/hexo'); + const dummyPath = 'dummy'; + const dummyError = 'error'; + return hexo.__with__({ + find_pkg_1: { + default: () => Promise.resolve(dummyPath) + }, + loadModule: () => Promise.resolve(), + console_1: { + default: () => { /* empty */ } + }, + context_1: { + default: class Context { + log: { error: typeof spy, fatal: typeof spy }; + constructor() { + this.log = { + error: spy, + fatal: spy + }; + } + init() { + throw new Error(dummyError); + } + } + } + })(async () => { + // @ts-ignore + await hexo(cwd, {_: ['test']}); + spy.args[0][0].message.should.eql(dummyError); + process.exitCode?.should.eql(2); + }); + }); - it('load hexo module in parent folder recursively'); + it('should watch SIGINT signal', () => { + const spy = sinon.spy(); + const watchSpy = sinon.spy(); + const exitSpy = sinon.spy(); + const dummyPath = 'dummy'; + const hexo = rewire('../../dist/hexo'); + const processSpy = { + on: process.on, + emit: process.emit, + exit: exitSpy + }; + return hexo.__with__({ + find_pkg_1: { + default: () => Promise.resolve(dummyPath) + }, + loadModule: () => Promise.resolve(), + console_1: { + default: () => { /* empty */ } + }, + process: processSpy, + context_1: { + default: class Context { + log: { error: typeof spy, fatal: typeof spy, info: typeof spy }; + extend: { + console: ConsoleExtend; + }; + constructor() { + this.log = { + error: spy, + fatal: spy, + info: spy + }; + this.extend = { + console: new ConsoleExtend() + }; + } + init() { + return Promise.resolve(); + } + call() { + return Promise.resolve(processSpy.emit('SIGINT')); + } + unwatch() { + watchSpy(); + } + exit() { + return Promise.resolve(); + } + } + } + })(async () => { + // @ts-ignore + await hexo(cwd, {_: ['help']}); + [ + 'Good bye', + 'See you again', + 'Farewell', + 'Have a nice day', + 'Bye!', + 'Catch you later' + ].includes(spy.args[0][0]).should.be.true; + watchSpy.calledOnce.should.be.true; + exitSpy.calledOnce.should.be.true; + }); + }); - it('display error message if failed to load hexo module'); + it('load hexo module in parent folder recursively'); }); From 818fef8d5a9a137d206f476bc1cafa6c2ce2e166 Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Sun, 21 Apr 2024 13:21:37 +0800 Subject: [PATCH 2/3] test(console): improve coverage --- test/scripts/console.ts | 71 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 test/scripts/console.ts diff --git a/test/scripts/console.ts b/test/scripts/console.ts new file mode 100644 index 00000000..fa5b9bd7 --- /dev/null +++ b/test/scripts/console.ts @@ -0,0 +1,71 @@ +import chai from 'chai'; +import sinon from 'sinon'; +import Console from '../../lib/extend/console'; +chai.should(); + +describe('console', () => { + it('register - name required', () => { + const consoleExtend = new Console(); + try { + // @ts-expect-error + consoleExtend.register(); + } catch (err) { + err.should.have.property('message', 'name is required'); + } + }); + + it('register - name, invalid fn', () => { + const consoleExtend = new Console(); + try { + // @ts-expect-error + consoleExtend.register('test', 'fn'); + } catch (err) { + err.should.have.property('message', 'fn must be a function'); + } + }); + + it('register - name, desc, invalid fn', () => { + const consoleExtend = new Console(); + try { + // @ts-expect-error + consoleExtend.register('test', 'desc', 'fn'); + } catch (err) { + err.should.have.property('message', 'fn must be a function'); + } + }); + + it('register - name, options, fn', () => { + const consoleExtend = new Console(); + const options = {}; + const fn = sinon.spy(); + consoleExtend.register('test', options, fn); + const storeFn = consoleExtend.get('test'); + storeFn(); + fn.calledOnce.should.be.true; + storeFn.options?.should.eql(options); + storeFn.desc?.should.eql(''); + }); + + it('register - name, desc, fn', () => { + const consoleExtend = new Console(); + const desc = 'desc'; + const fn = sinon.spy(); + consoleExtend.register('test', desc, fn); + const storeFn = consoleExtend.get('test'); + storeFn(); + fn.calledOnce.should.be.true; + storeFn.options?.should.deep.equal({}); + storeFn.desc?.should.eql(desc); + }); + + it('register - name, fn', () => { + const consoleExtend = new Console(); + const fn = sinon.spy(); + consoleExtend.register('test', fn); + const storeFn = consoleExtend.get('test'); + storeFn(); + fn.calledOnce.should.be.true; + storeFn.options?.should.deep.equal({}); + storeFn.desc?.should.eql(''); + }); +}); From f816096b802e9bf1eba4003dbfa9b2f368d9c3fa Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Mon, 29 Apr 2024 21:52:55 +0800 Subject: [PATCH 3/3] fix: ts-expect-error --- test/scripts/hexo.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/scripts/hexo.ts b/test/scripts/hexo.ts index 812450fd..11e5ceae 100644 --- a/test/scripts/hexo.ts +++ b/test/scripts/hexo.ts @@ -19,7 +19,7 @@ describe('hexo', () => { } } })(async () => { - // @ts-ignore + // @ts-expect-error await hexo(cwd, {_: []}); spy.calledOnce.should.be.true; }); @@ -35,7 +35,7 @@ describe('hexo', () => { } } })(async () => { - // @ts-ignore + // @ts-expect-error await hexo(cwd, {_: ['test']}); spy.calledOnce.should.be.true; }); @@ -51,7 +51,7 @@ describe('hexo', () => { } } })(async () => { - // @ts-ignore + // @ts-expect-error await hexo(cwd, {_: ['test']}); spy.calledOnce.should.be.true; }); @@ -69,7 +69,7 @@ describe('hexo', () => { } })(async () => { process.argv = ['hexo', 'new', '--path', '123', 'test']; - // @ts-ignore + // @ts-expect-error hexo(null, null); args.path.should.eql('123'); process.argv = []; @@ -88,7 +88,7 @@ describe('hexo', () => { } })(async () => { process.argv = ['hexo', 'new', '-p', '123', 'test']; - // @ts-ignore + // @ts-expect-error hexo(null, null); args.p.should.eql('123'); process.argv = []; @@ -107,7 +107,7 @@ describe('hexo', () => { } })(async () => { process.argv = ['hexo', 'new', '--slug', '123', 'test']; - // @ts-ignore + // @ts-expect-error hexo(null, null); args.slug.should.eql('123'); process.argv = []; @@ -126,7 +126,7 @@ describe('hexo', () => { } })(async () => { process.argv = ['hexo', 'new', '-s', '123', 'test']; - // @ts-ignore + // @ts-expect-error hexo(null, null); args.s.should.eql('123'); process.argv = []; @@ -156,7 +156,7 @@ describe('hexo', () => { } } })(async () => { - // @ts-ignore + // @ts-expect-error await hexo(cwd, {_: ['test']}); spy.args[0][0].should.eql(dummyError); spy.args[1][0].should.eql('Local hexo loading failed in %s'); @@ -194,7 +194,7 @@ describe('hexo', () => { } } })(async () => { - // @ts-ignore + // @ts-expect-error await hexo(cwd, {_: ['test']}); spy.args[0][0].message.should.eql(dummyError); process.exitCode?.should.eql(2); @@ -252,7 +252,7 @@ describe('hexo', () => { } } })(async () => { - // @ts-ignore + // @ts-expect-error await hexo(cwd, {_: ['help']}); [ 'Good bye',