Skip to content

Commit c040826

Browse files
authored
improve process.exit(1) when the translation is not finished yet (#63)
1 parent ee16d55 commit c040826

File tree

2 files changed

+70
-24
lines changed

2 files changed

+70
-24
lines changed

src/commands/status.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export const command = 'status'
1212
export const aliases = 'st'
1313
export const describe = 'indicate translation status from localization service'
1414

15+
class TranslationStatusError extends Error {}
16+
1517
export const builder = (args: Argv): Argv<StatusOptions> => {
1618
return args
1719
.option('provider', {
@@ -31,22 +33,34 @@ export const builder = (args: Argv): Argv<StatusOptions> => {
3133
default: '',
3234
describe: `option for some locales of translation status, you can also be specified multi locale with comma delimiter. if it's not specified indicate all locale translation status`
3335
})
36+
.fail((msg, err) => {
37+
if (msg) {
38+
console.error(msg)
39+
process.exit(1)
40+
} else {
41+
if (err instanceof TranslationStatusError) {
42+
console.warn(err.message)
43+
process.exit(1)
44+
} else {
45+
if (err) throw err
46+
}
47+
}
48+
})
3449
}
3550

3651
export const handler = async (args: Arguments<StatusOptions>): Promise<unknown> => {
37-
try {
38-
const { provider, conf, locales } = args
39-
const status = await getTranslationStatus({ provider, conf, locales })
40-
debug('raw status', status)
41-
// TODO: should be refactored console outputing!
42-
status.forEach(st => {
43-
console.log(`${st.locale}: ${st.percentage} %`)
44-
})
45-
} catch (e) {
46-
console.error('status fail', e)
47-
}
52+
// try {
53+
const { provider, conf, locales } = args
54+
debug(`status args: provider=${provider}, conf=${conf}, locales=${locales}`)
55+
const status = await getTranslationStatus({ provider, conf, locales })
56+
debug('raw status', status)
57+
console.table(status)
58+
59+
const completes = status.filter(st => st.percentage < 100)
4860

49-
return Promise.resolve()
61+
return completes.length > 0
62+
? Promise.reject(new TranslationStatusError('Translation work in progress'))
63+
: Promise.resolve('Translation done')
5064
}
5165

5266
export default {

test/commands/status.test.ts

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,47 +18,75 @@ import L10nServiceProvider from '@scope/l10n-service-provider'
1818
const PROCESS_CWD_TARGET_PATH = path.resolve(__dirname)
1919

2020
let orgCwd // for process.cwd mock
21+
let orgExit // for process.exit mock
2122
let spyLog
2223
let spyError
2324
beforeEach(() => {
2425
spyLog = jest.spyOn(global.console, 'log')
2526
spyError = jest.spyOn(global.console, 'error')
2627
orgCwd = process.cwd
2728
process.cwd = jest.fn(() => PROCESS_CWD_TARGET_PATH) // mock: process.cwd
29+
process.exit = jest.fn((code => { return 'exit!' as never })) // mock: process.exit
2830
})
2931

3032
afterEach(() => {
3133
spyError.mockRestore()
3234
spyLog.mockRestore()
3335
jest.clearAllMocks()
36+
process.exit = orgExit
3437
process.cwd = orgCwd
3538
})
3639

3740
// -----------
3841
// test cases
3942

4043
test('require options', async () => {
44+
// run
45+
const status = await import('../../src/commands/status')
46+
const cmd = yargs.command(status)
47+
await new Promise((resolve, reject) => {
48+
cmd.parse(`status`, (err, argv, output) => {
49+
err ? reject(err) : resolve(output)
50+
})
51+
})
52+
53+
// verify
54+
expect(spyError).toBeCalled()
55+
expect(process.exit).toHaveBeenCalledWith(1)
56+
})
57+
58+
test('getTranslationStatus: done', async () => {
59+
// setup mocking ...
60+
const mockStatusValue = [{
61+
locale: 'en',
62+
percentage: 100
63+
}, {
64+
locale: 'ja',
65+
percentage: 100
66+
}]
67+
mockStatus.mockImplementation(({ locales }) => Promise.resolve(mockStatusValue))
68+
69+
// run
4170
const status = await import('../../src/commands/status')
4271
const cmd = yargs.command(status)
43-
try {
44-
await new Promise((resolve, reject) => {
45-
cmd.parse(`status`, (err, argv, output) => {
46-
err ? reject(err) : resolve(output)
47-
})
72+
await new Promise((resolve, reject) => {
73+
cmd.parse(`status --provider=@scope/l10n-service-provider`, (err, argv, output) => {
74+
err ? reject(err) : resolve(output)
4875
})
49-
} catch (e) {
50-
expect(e).toMatchObject({ name: 'YError' })
51-
}
76+
})
77+
78+
// verify
79+
expect(process.exit).not.toBeCalled()
5280
})
5381

54-
test('getTranslationStatus: success', async () => {
55-
// setup mocks
82+
test('getTranslationStatus: wip', async () => {
83+
// setup mocking ...
5684
const mockStatusValue = [{
5785
locale: 'en',
58-
percentage: 24.2
86+
percentage: 72.4
5987
}, {
6088
locale: 'ja',
61-
percentage: 100.0
89+
percentage: 100
6290
}]
6391
mockStatus.mockImplementation(({ locales }) => Promise.resolve(mockStatusValue))
6492

@@ -70,4 +98,8 @@ test('getTranslationStatus: success', async () => {
7098
err ? reject(err) : resolve(output)
7199
})
72100
})
101+
102+
// verify
103+
// NOTE: cannot detect process.exit calling ...
104+
// expect(process.exit).toHaveBeenCalledWith(1)
73105
})

0 commit comments

Comments
 (0)