refactor closet command

This commit is contained in:
Pig Fang 2020-03-22 12:21:17 +08:00
parent ce297f66f9
commit c50f265b8e
6 changed files with 54 additions and 72 deletions

View File

@ -22,6 +22,7 @@
"@tweenjs/tween.js": "^18.4.2",
"admin-lte": "^3.0.1",
"blessing-skin-shell": "^0.2.0",
"commander": "^5.0.0",
"echarts": "^4.6.0",
"jquery": "^3.4.1",
"lodash.debounce": "^4.0.8",

View File

@ -1,36 +1,25 @@
import type { Stdio } from 'blessing-skin-shell'
import { Command } from 'commander'
import * as fetch from '../net'
import { User, Texture } from '../types'
type SubCommand = 'add' | 'remove'
import { hackStdout, overrideExit } from './configureStdio'
type Response = fetch.ResponseBody<{ user: User; texture: Texture }>
export default async function closet(stdio: Stdio, args: string[]) {
if (args.includes('-h') || args.includes('--help')) {
stdio.println('Usage: closet <add|remove> <uid> <tid>')
return
const program = new Command()
/* istanbul ignore next */
if (process.env.NODE_ENV !== 'test') {
process.stdout = hackStdout(stdio)
overrideExit(program, stdio)
}
const command = args[0] as SubCommand | undefined
const uid = args[1]
const tid = args[2]
if (!command) {
stdio.println('Supported subcommand: add, remove.')
return
}
if (!uid) {
stdio.println('User ID must be provided.')
return
}
if (!tid) {
stdio.println('Texture ID must be provided.')
return
}
switch (command) {
case 'add': {
program.name('closet').version('0.1.0')
program
.command('add <uid> <tid>')
.description("add texture to someone's closet")
.action(async (uid: string, tid: string) => {
const { code, data } = await fetch.post<Response>(
`/admin/closet/${uid}`,
{ tid },
@ -43,9 +32,11 @@ export default async function closet(stdio: Stdio, args: string[]) {
} else {
stdio.println('Error occurred.')
}
break
}
case 'remove': {
})
program
.command('remove <uid> <tid>')
.description("remove texture from someone's closet")
.action(async (uid: string, tid: string) => {
const { code, data } = await fetch.del<Response>(`/admin/closet/${uid}`, {
tid,
})
@ -57,7 +48,7 @@ export default async function closet(stdio: Stdio, args: string[]) {
} else {
stdio.println('Error occurred.')
}
break
}
}
})
await program.parseAsync(args, { from: 'user' })
}

View File

@ -0,0 +1,22 @@
import { Stdio } from 'blessing-skin-shell'
import type Commander from 'commander'
/* istanbul ignore next */
export function hackStdout(stdio: Stdio) {
return {
write(msg: string) {
stdio.print(msg.replace(/\n/g, '\r\n'))
},
} as NodeJS.WriteStream
}
/* istanbul ignore next */
export function overrideExit(program: Commander.Command, stdio: Stdio) {
Error.captureStackTrace = () => {}
return program.exitOverride(error => {
if (!error.message.startsWith('(')) {
stdio.print(error.message.replace(/\n/g, '\r\n'))
}
})
}

View File

@ -4,46 +4,6 @@ import { Stdio } from './stdio'
jest.mock('@/scripts/net')
test('help message', async () => {
let stdio = new Stdio()
await runCommand(stdio, ['-h'])
expect(stdio.getStdout()).toInclude('Usage')
stdio = new Stdio()
await runCommand(stdio, ['--help'])
expect(stdio.getStdout()).toInclude('Usage')
})
test('missing subcommand', async () => {
const stdio = new Stdio()
await runCommand(stdio, [])
expect(fetch.post).not.toBeCalled()
expect(fetch.del).not.toBeCalled()
})
test('unsupported subcommand', async () => {
const stdio = new Stdio()
await runCommand(stdio, ['abc'])
expect(fetch.post).not.toBeCalled()
expect(fetch.del).not.toBeCalled()
})
test('missing uid', async () => {
const stdio = new Stdio()
await runCommand(stdio, ['add'])
expect(stdio.getStdout()).toInclude('User ID')
expect(fetch.post).not.toBeCalled()
expect(fetch.del).not.toBeCalled()
})
test('missing tid', async () => {
const stdio = new Stdio()
await runCommand(stdio, ['add', '1'])
expect(stdio.getStdout()).toInclude('Texture ID')
expect(fetch.post).not.toBeCalled()
expect(fetch.del).not.toBeCalled()
})
describe('add texture', () => {
it('succeeded', async () => {
fetch.post.mockResolvedValue({

View File

@ -150,7 +150,10 @@ const config = {
hotOnly: true,
stats: 'errors-only',
},
stats: 'errors-only',
node: {
child_process: 'empty',
fs: 'empty',
},
}
if (devMode) {

View File

@ -2934,6 +2934,11 @@ commander@^2.20.0, commander@~2.20.0:
resolved "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==
commander@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-5.0.0.tgz#dbf1909b49e5044f8fdaf0adc809f0c0722bdfd0"
integrity sha512-JrDGPAKjMGSP1G0DUoaceEJ3DZgAfr/q6X7FVk4+U5KxUSKviYGM2k6zWkfyyBHy5rAtzgYJFa1ro2O9PtoxwQ==
commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
@ -7114,7 +7119,7 @@ node-int64@^0.4.0:
node-libs-browser@^2.2.1:
version "2.2.1"
resolved "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==
dependencies:
assert "^1.1.1"