@esgettext/tools 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/dist/command.js +0 -1
- package/dist/commands/convert.js +16 -14
- package/dist/commands/install.js +12 -4
- package/dist/commands/msgfmt-all.js +65 -46
- package/dist/commands/msgmerge-all.js +64 -46
- package/dist/commands/xgettext/file-resolver.js +0 -1
- package/dist/commands/xgettext/files-collector.js +1 -1
- package/dist/commands/xgettext.js +16 -7
- package/dist/configuration.js +172 -156
- package/dist/esgettext-package-json.js +0 -1
- package/dist/index.js +75 -24
- package/dist/package.js +1 -2
- package/dist/parser/javascript.js +2 -1
- package/dist/parser/parser.js +17 -2
- package/dist/parser/po.js +34 -1
- package/dist/parser/typescript.js +2 -1
- package/dist/pot/catalog.js +36 -1
- package/dist/pot/entry.js +71 -1
- package/dist/pot/keyword.js +10 -5
- package/package.json +5 -4
- package/dist/command.d.ts +0 -11
- package/dist/command.js.map +0 -1
- package/dist/commands/convert.d.ts +0 -24
- package/dist/commands/convert.js.map +0 -1
- package/dist/commands/install.d.ts +0 -22
- package/dist/commands/install.js.map +0 -1
- package/dist/commands/msgfmt-all.d.ts +0 -20
- package/dist/commands/msgfmt-all.js.map +0 -1
- package/dist/commands/msgmerge-all.d.ts +0 -21
- package/dist/commands/msgmerge-all.js.map +0 -1
- package/dist/commands/xgettext/file-resolver.d.ts +0 -5
- package/dist/commands/xgettext/file-resolver.js.map +0 -1
- package/dist/commands/xgettext/file-resolver.spec.d.ts +0 -1
- package/dist/commands/xgettext/file-resolver.spec.js +0 -22
- package/dist/commands/xgettext/file-resolver.spec.js.map +0 -1
- package/dist/commands/xgettext/files-collector.d.ts +0 -5
- package/dist/commands/xgettext/files-collector.js.map +0 -1
- package/dist/commands/xgettext/files-collector.spec.d.ts +0 -1
- package/dist/commands/xgettext/files-collector.spec.js +0 -96
- package/dist/commands/xgettext/files-collector.spec.js.map +0 -1
- package/dist/commands/xgettext.d.ts +0 -29
- package/dist/commands/xgettext.js.map +0 -1
- package/dist/commands/xgettext.spec.d.ts +0 -1
- package/dist/commands/xgettext.spec.js +0 -897
- package/dist/commands/xgettext.spec.js.map +0 -1
- package/dist/configuration.d.ts +0 -36
- package/dist/configuration.js.map +0 -1
- package/dist/esgettext-package-json.d.ts +0 -15
- package/dist/esgettext-package-json.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js.map +0 -1
- package/dist/package.d.ts +0 -5
- package/dist/package.js.map +0 -1
- package/dist/parser/javascript.d.ts +0 -4
- package/dist/parser/javascript.js.map +0 -1
- package/dist/parser/javascript.spec.d.ts +0 -1
- package/dist/parser/javascript.spec.js +0 -535
- package/dist/parser/javascript.spec.js.map +0 -1
- package/dist/parser/parser.d.ts +0 -45
- package/dist/parser/parser.js.map +0 -1
- package/dist/parser/po.d.ts +0 -22
- package/dist/parser/po.js.map +0 -1
- package/dist/parser/po.spec.d.ts +0 -1
- package/dist/parser/po.spec.js +0 -486
- package/dist/parser/po.spec.js.map +0 -1
- package/dist/parser/typescript.d.ts +0 -4
- package/dist/parser/typescript.js.map +0 -1
- package/dist/parser/typescript.spec.d.ts +0 -1
- package/dist/parser/typescript.spec.js +0 -121
- package/dist/parser/typescript.spec.js.map +0 -1
- package/dist/pot/catalog.d.ts +0 -26
- package/dist/pot/catalog.js.map +0 -1
- package/dist/pot/catalog.spec.d.ts +0 -1
- package/dist/pot/catalog.spec.js +0 -244
- package/dist/pot/catalog.spec.js.map +0 -1
- package/dist/pot/entry.d.ts +0 -35
- package/dist/pot/entry.js.map +0 -1
- package/dist/pot/entry.spec.d.ts +0 -1
- package/dist/pot/entry.spec.js +0 -433
- package/dist/pot/entry.spec.js.map +0 -1
- package/dist/pot/keyword.d.ts +0 -17
- package/dist/pot/keyword.js.map +0 -1
- package/dist/pot/keyword.spec.d.ts +0 -1
- package/dist/pot/keyword.spec.js +0 -54
- package/dist/pot/keyword.spec.js.map +0 -1
|
@@ -1,897 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
const fs = __importStar(require("fs"));
|
|
27
|
-
const xgettext_1 = require("./xgettext");
|
|
28
|
-
jest.mock('fs');
|
|
29
|
-
const date = '2020-04-23 08:50+0300';
|
|
30
|
-
const readFileSync = fs.readFileSync;
|
|
31
|
-
const writeFileSync = fs.writeFileSync;
|
|
32
|
-
const warnSpy = jest.spyOn(global.console, 'warn').mockImplementation(() => {
|
|
33
|
-
});
|
|
34
|
-
const errorSpy = jest.spyOn(global.console, 'error').mockImplementation(() => {
|
|
35
|
-
});
|
|
36
|
-
const baseArgv = {
|
|
37
|
-
$0: 'esgettext',
|
|
38
|
-
};
|
|
39
|
-
const baseConfig = {
|
|
40
|
-
files: [],
|
|
41
|
-
};
|
|
42
|
-
function resetMocks() {
|
|
43
|
-
readFileSync.mockReset();
|
|
44
|
-
writeFileSync.mockReset();
|
|
45
|
-
warnSpy.mockReset();
|
|
46
|
-
errorSpy.mockReset();
|
|
47
|
-
}
|
|
48
|
-
describe('xgettext', () => {
|
|
49
|
-
describe('defaults', () => {
|
|
50
|
-
beforeEach(() => {
|
|
51
|
-
resetMocks();
|
|
52
|
-
});
|
|
53
|
-
it('should extract strings from javascript files', async () => {
|
|
54
|
-
const hello = `
|
|
55
|
-
console.log(gtx._('Hello, world!'));
|
|
56
|
-
`;
|
|
57
|
-
const goodbye = `
|
|
58
|
-
console.log(gtx._('Goodbye, world!'));
|
|
59
|
-
`;
|
|
60
|
-
readFileSync
|
|
61
|
-
.mockReturnValueOnce(Buffer.from(hello))
|
|
62
|
-
.mockReturnValueOnce(Buffer.from(goodbye));
|
|
63
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['hello1.js', 'goodbye.js'] });
|
|
64
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
65
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
66
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
67
|
-
const call = writeFileSync.mock.calls[0];
|
|
68
|
-
expect(call[0]).toEqual('messages.po');
|
|
69
|
-
expect(call[1]).toMatchSnapshot();
|
|
70
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
71
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
72
|
-
});
|
|
73
|
-
it('should extract strings from typescript files', async () => {
|
|
74
|
-
const hello = `
|
|
75
|
-
const hello: string = gtx._('Hello, world!');
|
|
76
|
-
`;
|
|
77
|
-
const goodbye = `
|
|
78
|
-
const goodbye: string = gtx._('Goodbye, world!');
|
|
79
|
-
`;
|
|
80
|
-
readFileSync
|
|
81
|
-
.mockReturnValueOnce(Buffer.from(hello))
|
|
82
|
-
.mockReturnValueOnce(Buffer.from(goodbye));
|
|
83
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['hello2.ts', 'goodbye.ts'] });
|
|
84
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
85
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
86
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
87
|
-
const call = writeFileSync.mock.calls[0];
|
|
88
|
-
expect(call[0]).toEqual('messages.po');
|
|
89
|
-
expect(call[1]).toMatchSnapshot();
|
|
90
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
91
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
92
|
-
});
|
|
93
|
-
it('should parse po files', async () => {
|
|
94
|
-
const po = `# SOME DESCRIPTIVE TITLE
|
|
95
|
-
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
96
|
-
# This file is distributed under the same license as the PACKAGE package.
|
|
97
|
-
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
98
|
-
#
|
|
99
|
-
#, fuzzy
|
|
100
|
-
msgid ""
|
|
101
|
-
msgstr ""
|
|
102
|
-
"Project-Id-Version: PACKAGE VERSION\\n"
|
|
103
|
-
"Report-Msgid-Bugs-To: MSGID_BUGS_ADDRESS\\n"
|
|
104
|
-
"POT-Creation-Date: 2020-05-25 11:50+0300\\n"
|
|
105
|
-
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
|
|
106
|
-
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
|
|
107
|
-
"Language-Team: German <de@li.org>\\n"
|
|
108
|
-
"Language: \\n"
|
|
109
|
-
"MIME-Version: 1.0\\n"
|
|
110
|
-
"Content-Type: text/plain; charset=utf-8\\n"
|
|
111
|
-
"Content-Transfer-Encoding: 8bit\\n"
|
|
112
|
-
"Plural-Forms: Plural-Forms: nplurals=2; plural=(n != 1);\\n"
|
|
113
|
-
|
|
114
|
-
#: src/cli/getopt.ts:122
|
|
115
|
-
#, perl-brace-format
|
|
116
|
-
msgid "'{programName}': unrecognized option '--{option}'"
|
|
117
|
-
msgstr ""
|
|
118
|
-
`;
|
|
119
|
-
readFileSync.mockReturnValueOnce(Buffer.from(po));
|
|
120
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['de.po'] });
|
|
121
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
122
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
123
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
124
|
-
const call = writeFileSync.mock.calls[0];
|
|
125
|
-
expect(call[0]).toEqual('messages.po');
|
|
126
|
-
expect(call[1]).toMatchSnapshot();
|
|
127
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
128
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
129
|
-
});
|
|
130
|
-
it('should parse pot files', async () => {
|
|
131
|
-
const pot = `# SOME DESCRIPTIVE TITLE
|
|
132
|
-
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
133
|
-
# This file is distributed under the same license as the PACKAGE package.
|
|
134
|
-
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
135
|
-
#
|
|
136
|
-
#, fuzzy
|
|
137
|
-
msgid ""
|
|
138
|
-
msgstr ""
|
|
139
|
-
"Project-Id-Version: PACKAGE VERSION\\n"
|
|
140
|
-
"Report-Msgid-Bugs-To: MSGID_BUGS_ADDRESS\\n"
|
|
141
|
-
"POT-Creation-Date: 2020-05-25 11:50+0300\\n"
|
|
142
|
-
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
|
|
143
|
-
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
|
|
144
|
-
"Language-Team: LANGUAGE <LL@li.org>\\n"
|
|
145
|
-
"Language: \\n"
|
|
146
|
-
"MIME-Version: 1.0\\n"
|
|
147
|
-
"Content-Type: text/plain; charset=utf-8\\n"
|
|
148
|
-
"Content-Transfer-Encoding: 8bit\\n"
|
|
149
|
-
|
|
150
|
-
#: src/cli/getopt.ts:122
|
|
151
|
-
#, perl-brace-format
|
|
152
|
-
msgid "'{programName}': unrecognized option '--{option}'"
|
|
153
|
-
msgstr ""
|
|
154
|
-
`;
|
|
155
|
-
readFileSync.mockReturnValueOnce(Buffer.from(pot));
|
|
156
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['package.pot'] });
|
|
157
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
158
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
159
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
160
|
-
const call = writeFileSync.mock.calls[0];
|
|
161
|
-
expect(call[0]).toEqual('messages.po');
|
|
162
|
-
expect(call[1]).toMatchSnapshot();
|
|
163
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
164
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
165
|
-
});
|
|
166
|
-
it('should fall back to the JavaScript parser', async () => {
|
|
167
|
-
const pot = `# SOME DESCRIPTIVE TITLE
|
|
168
|
-
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
169
|
-
# This file is distributed under the same license as the PACKAGE package.
|
|
170
|
-
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
171
|
-
#
|
|
172
|
-
#, fuzzy
|
|
173
|
-
msgid ""
|
|
174
|
-
msgstr ""
|
|
175
|
-
"Project-Id-Version: PACKAGE VERSION\\n"
|
|
176
|
-
"Report-Msgid-Bugs-To: MSGID_BUGS_ADDRESS\\n"
|
|
177
|
-
"POT-Creation-Date: 2020-05-25 11:50+0300\\n"
|
|
178
|
-
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
|
|
179
|
-
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
|
|
180
|
-
"Language-Team: LANGUAGE <LL@li.org>\\n"
|
|
181
|
-
"Language: \\n"
|
|
182
|
-
"MIME-Version: 1.0\\n"
|
|
183
|
-
"Content-Type: text/plain; charset=utf-8\\n"
|
|
184
|
-
"Content-Transfer-Encoding: 8bit\\n"
|
|
185
|
-
|
|
186
|
-
#: src/cli/getopt.ts:122
|
|
187
|
-
#, perl-brace-format
|
|
188
|
-
msgid "'{programName}': unrecognized option '--{option}'"
|
|
189
|
-
msgstr ""
|
|
190
|
-
`;
|
|
191
|
-
readFileSync.mockReturnValueOnce(Buffer.from(pot));
|
|
192
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['package.xyz'] });
|
|
193
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
194
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
195
|
-
expect(writeFileSync).toHaveBeenCalledTimes(0);
|
|
196
|
-
expect(warnSpy).toHaveBeenCalledTimes(1);
|
|
197
|
-
expect(errorSpy).toHaveBeenCalled();
|
|
198
|
-
});
|
|
199
|
-
it('should fail on errors', async () => {
|
|
200
|
-
const hello = 'console.log(gtx._(`Hello, ${name}!`));';
|
|
201
|
-
readFileSync.mockReturnValueOnce(Buffer.from(hello));
|
|
202
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['hello3.js'] });
|
|
203
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
204
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
205
|
-
expect(writeFileSync).not.toHaveBeenCalled();
|
|
206
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
207
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
208
|
-
expect(errorSpy).toHaveBeenNthCalledWith(1, 'hello3.js:1:18-1:35: Error: template literals with embedded expressions are not allowed as arguments to gettext functions because they are not constant');
|
|
209
|
-
});
|
|
210
|
-
it('should fail on exceptions', async () => {
|
|
211
|
-
readFileSync.mockImplementationOnce(() => {
|
|
212
|
-
throw new Error('no such file or directory');
|
|
213
|
-
});
|
|
214
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['hello4.js'] });
|
|
215
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
216
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
217
|
-
expect(writeFileSync).not.toHaveBeenCalled();
|
|
218
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
219
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
220
|
-
expect(errorSpy).toHaveBeenNthCalledWith(1, 'hello4.js: Error: no such file or directory');
|
|
221
|
-
});
|
|
222
|
-
it('should fail on output exceptions', async () => {
|
|
223
|
-
const code = 'gtx._("Hello, world!");';
|
|
224
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
225
|
-
writeFileSync.mockImplementationOnce(() => {
|
|
226
|
-
throw new Error('no such file or directory');
|
|
227
|
-
});
|
|
228
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['hello5.js'] });
|
|
229
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
230
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
231
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
232
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
233
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
234
|
-
expect(errorSpy).toHaveBeenNthCalledWith(1, 'esgettext: Error: no such file or directory');
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
describe('xgettext command-line options and arguments', () => {
|
|
239
|
-
describe('input file location', () => {
|
|
240
|
-
describe('input file arguments', () => {
|
|
241
|
-
beforeEach(() => {
|
|
242
|
-
resetMocks();
|
|
243
|
-
});
|
|
244
|
-
it('should treat non-options as input file names', async () => {
|
|
245
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { output: 'option-output.pot', _: ['here/option-output.js', 'there/option-output.js'] });
|
|
246
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
247
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
248
|
-
expect(writeFileSync).not.toHaveBeenCalled();
|
|
249
|
-
expect(readFileSync).toHaveBeenCalledTimes(2);
|
|
250
|
-
expect(readFileSync.mock.calls[0][0]).toEqual('here/option-output.js');
|
|
251
|
-
expect(readFileSync.mock.calls[1][0]).toEqual('there/option-output.js');
|
|
252
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
253
|
-
expect(errorSpy).toHaveBeenCalledTimes(2);
|
|
254
|
-
});
|
|
255
|
-
it('should interpret "-" as stdin', async () => {
|
|
256
|
-
const code = 'gtx._("Hello, world!")';
|
|
257
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { output: 'option-output.pot', _: ['-'] });
|
|
258
|
-
const stdinSpy = jest
|
|
259
|
-
.spyOn(global.process.stdin, 'read')
|
|
260
|
-
.mockReturnValueOnce(Buffer.from(code));
|
|
261
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
262
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
263
|
-
expect(stdinSpy).toHaveBeenCalledTimes(1);
|
|
264
|
-
stdinSpy.mockReset();
|
|
265
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
266
|
-
expect(writeFileSync.mock.calls[0][0]).toMatchSnapshot();
|
|
267
|
-
expect(readFileSync).not.toHaveBeenCalled();
|
|
268
|
-
expect(warnSpy).toHaveBeenCalledTimes(1);
|
|
269
|
-
expect(warnSpy).toHaveBeenNthCalledWith(1, 'esgettext: Warning: language for standard' +
|
|
270
|
-
' input is unknown without option "--language";' +
|
|
271
|
-
' will try JavaScript');
|
|
272
|
-
expect(errorSpy).toHaveBeenCalledTimes(0);
|
|
273
|
-
});
|
|
274
|
-
it('should catch errors on stdin', async () => {
|
|
275
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { language: 'JavaScript', _: ['-'] });
|
|
276
|
-
const stdinSpy = jest
|
|
277
|
-
.spyOn(global.process.stdin, 'read')
|
|
278
|
-
.mockImplementation(() => {
|
|
279
|
-
throw new Error('I/O error');
|
|
280
|
-
});
|
|
281
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
282
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
283
|
-
expect(stdinSpy).toHaveBeenCalledTimes(1);
|
|
284
|
-
stdinSpy.mockReset();
|
|
285
|
-
expect(writeFileSync).not.toHaveBeenCalled();
|
|
286
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
287
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
288
|
-
expect(errorSpy).toHaveBeenCalledWith('[standard input]: Error: I/O error');
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
describe('option --files-from', () => {
|
|
292
|
-
beforeEach(() => resetMocks());
|
|
293
|
-
it('should accept multiple --files-from options', async () => {
|
|
294
|
-
const potfiles1 = 'files-from1.js';
|
|
295
|
-
const filesFrom1 = 'gtx._("Hello, world!")';
|
|
296
|
-
const potfiles2 = 'files-from2.js';
|
|
297
|
-
const filesFrom2 = 'gtx._("Hello, world!")';
|
|
298
|
-
readFileSync
|
|
299
|
-
.mockReturnValueOnce(Buffer.from(potfiles1))
|
|
300
|
-
.mockReturnValueOnce(Buffer.from(potfiles2))
|
|
301
|
-
.mockReturnValueOnce(Buffer.from(filesFrom1))
|
|
302
|
-
.mockReturnValueOnce(Buffer.from(filesFrom2));
|
|
303
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { filesFrom: ['POTFILES-1', 'POTFILES-2'], _: [] });
|
|
304
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
305
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
306
|
-
expect(readFileSync).toHaveBeenCalledTimes(4);
|
|
307
|
-
expect(readFileSync.mock.calls[0][0]).toEqual('POTFILES-1');
|
|
308
|
-
expect(readFileSync.mock.calls[1][0]).toEqual('POTFILES-2');
|
|
309
|
-
expect(readFileSync.mock.calls[2][0]).toEqual('files-from1.js');
|
|
310
|
-
expect(readFileSync.mock.calls[3][0]).toEqual('files-from2.js');
|
|
311
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
312
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
313
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
314
|
-
});
|
|
315
|
-
it('should report errors for missing --files-from files', async () => {
|
|
316
|
-
readFileSync.mockImplementation(filename => {
|
|
317
|
-
throw new Error(`ENOENT: no such file or directory, open '${filename}'`);
|
|
318
|
-
});
|
|
319
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { filesFrom: ['POTFILES'], _: [] });
|
|
320
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
321
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
322
|
-
expect(readFileSync).toHaveBeenCalledTimes(1);
|
|
323
|
-
expect(readFileSync).toHaveBeenCalledWith('POTFILES');
|
|
324
|
-
expect(writeFileSync).not.toHaveBeenCalled();
|
|
325
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
326
|
-
expect(errorSpy).toHaveBeenCalledWith("esgettext: Error: ENOENT: no such file or directory, open 'POTFILES'");
|
|
327
|
-
});
|
|
328
|
-
it('should treat "-" as standard input', async () => {
|
|
329
|
-
const filesFrom1 = 'gtx._("Hello, world!")';
|
|
330
|
-
const filesFrom2 = 'gtx._("Hello, world!")';
|
|
331
|
-
readFileSync
|
|
332
|
-
.mockReturnValueOnce(Buffer.from(filesFrom1))
|
|
333
|
-
.mockReturnValueOnce(Buffer.from(filesFrom2));
|
|
334
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { filesFrom: ['-'], _: [] });
|
|
335
|
-
const stdinSpy = jest
|
|
336
|
-
.spyOn(global.process.stdin, 'read')
|
|
337
|
-
.mockReturnValueOnce(Buffer.from(`
|
|
338
|
-
files-from-1.js
|
|
339
|
-
files-from-2.js
|
|
340
|
-
`));
|
|
341
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
342
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
343
|
-
expect(stdinSpy).toHaveBeenCalledTimes(1);
|
|
344
|
-
stdinSpy.mockReset();
|
|
345
|
-
expect(readFileSync).toHaveBeenCalledTimes(2);
|
|
346
|
-
expect(readFileSync.mock.calls[0][0]).toEqual('files-from-1.js');
|
|
347
|
-
expect(readFileSync.mock.calls[1][0]).toEqual('files-from-2.js');
|
|
348
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
349
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
350
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
351
|
-
});
|
|
352
|
-
});
|
|
353
|
-
describe('option --directory', () => {
|
|
354
|
-
beforeEach(resetMocks);
|
|
355
|
-
it('should search for files in other directories', async () => {
|
|
356
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { directory: ['foo', 'bar', 'baz'], _: ['directory.js'] });
|
|
357
|
-
readFileSync.mockImplementation(filename => {
|
|
358
|
-
throw new Error(`ENOENT: no such file or directory, open '${filename}'`);
|
|
359
|
-
});
|
|
360
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
361
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
362
|
-
expect(readFileSync).toHaveBeenCalledTimes(3);
|
|
363
|
-
expect(readFileSync).toHaveBeenNthCalledWith(1, 'foo/directory.js');
|
|
364
|
-
expect(readFileSync).toHaveBeenNthCalledWith(2, 'bar/directory.js');
|
|
365
|
-
expect(readFileSync).toHaveBeenNthCalledWith(3, 'baz/directory.js');
|
|
366
|
-
expect(writeFileSync).not.toHaveBeenCalled();
|
|
367
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
368
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
369
|
-
expect(errorSpy).toHaveBeenNthCalledWith(1, "directory.js: Error: ENOENT: no such file or directory, open 'baz/directory.js'");
|
|
370
|
-
});
|
|
371
|
-
});
|
|
372
|
-
});
|
|
373
|
-
describe('output file location', () => {
|
|
374
|
-
describe('option --output', () => {
|
|
375
|
-
beforeEach(() => {
|
|
376
|
-
resetMocks();
|
|
377
|
-
});
|
|
378
|
-
it('should honor the option --output', async () => {
|
|
379
|
-
const code = 'console.log(gtx._("Hello, world!"))';
|
|
380
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
381
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { output: 'option-output.pot', _: ['option-output.js'] });
|
|
382
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
383
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
384
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
385
|
-
expect(writeFileSync.mock.calls[0][0]).toEqual('option-output.pot');
|
|
386
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
387
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
388
|
-
});
|
|
389
|
-
it('should write to stdout', async () => {
|
|
390
|
-
const code = 'console.log(gtx._("Hello, world!"))';
|
|
391
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
392
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { output: '-', _: ['option-output.js'] });
|
|
393
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
394
|
-
const stdoutSpy = jest
|
|
395
|
-
.spyOn(global.process.stdout, 'write')
|
|
396
|
-
.mockImplementation(() => {
|
|
397
|
-
return true;
|
|
398
|
-
});
|
|
399
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
400
|
-
expect(writeFileSync).toHaveBeenCalledTimes(0);
|
|
401
|
-
expect(stdoutSpy.mock.calls).toMatchSnapshot();
|
|
402
|
-
stdoutSpy.mockRestore();
|
|
403
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
404
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
405
|
-
});
|
|
406
|
-
});
|
|
407
|
-
describe('option --default-domain', () => {
|
|
408
|
-
beforeEach(() => {
|
|
409
|
-
resetMocks();
|
|
410
|
-
});
|
|
411
|
-
it('should default to "messages"', async () => {
|
|
412
|
-
const code = 'gtx._("Hello, world")';
|
|
413
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
414
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['option-output.js'] });
|
|
415
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
416
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
417
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
418
|
-
expect(writeFileSync.mock.calls[0][0]).toEqual('messages.po');
|
|
419
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
420
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
421
|
-
});
|
|
422
|
-
it('should be changed to "strings"', async () => {
|
|
423
|
-
const code = 'gtx._("Hello, world")';
|
|
424
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
425
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { defaultDomain: 'strings', _: ['option-output.js'] });
|
|
426
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
427
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
428
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
429
|
-
expect(writeFileSync.mock.calls[0][0]).toEqual('strings.po');
|
|
430
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
431
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
432
|
-
});
|
|
433
|
-
});
|
|
434
|
-
describe('option --output-dir', () => {
|
|
435
|
-
beforeEach(() => {
|
|
436
|
-
resetMocks();
|
|
437
|
-
});
|
|
438
|
-
it('should be changed to "po"', async () => {
|
|
439
|
-
const code = 'gtx._("Hello, world")';
|
|
440
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
441
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { outputDir: 'po', _: ['option-output.js'] });
|
|
442
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
443
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
444
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
445
|
-
expect(writeFileSync.mock.calls[0][0]).toEqual('po/messages.po');
|
|
446
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
447
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
448
|
-
});
|
|
449
|
-
});
|
|
450
|
-
});
|
|
451
|
-
describe('choice of input language', () => {
|
|
452
|
-
describe('option --language', () => {
|
|
453
|
-
afterEach(() => {
|
|
454
|
-
resetMocks();
|
|
455
|
-
});
|
|
456
|
-
it('should honor the --language option', async () => {
|
|
457
|
-
const code = `# SOME DESCRIPTIVE TITLE
|
|
458
|
-
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
459
|
-
# This file is distributed under the same license as the PACKAGE package.
|
|
460
|
-
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
461
|
-
#
|
|
462
|
-
#, fuzzy
|
|
463
|
-
msgid ""
|
|
464
|
-
msgstr ""
|
|
465
|
-
"Project-Id-Version: PACKAGE VERSION\\n"
|
|
466
|
-
"Report-Msgid-Bugs-To: MSGID_BUGS_ADDRESS\\n"
|
|
467
|
-
"POT-Creation-Date: 2020-05-25 11:50+0300\\n"
|
|
468
|
-
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
|
|
469
|
-
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
|
|
470
|
-
"Language-Team: LANGUAGE <LL@li.org>\\n"
|
|
471
|
-
"Language: \\n"
|
|
472
|
-
"MIME-Version: 1.0\\n"
|
|
473
|
-
"Content-Type: text/plain; charset=utf-8\\n"
|
|
474
|
-
"Content-Transfer-Encoding: 8bit\\n"
|
|
475
|
-
|
|
476
|
-
#: src/cli/getopt.ts:122
|
|
477
|
-
#, perl-brace-format
|
|
478
|
-
msgid "'{programName}': unrecognized option '--{option}'"
|
|
479
|
-
msgstr ""
|
|
480
|
-
`;
|
|
481
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
482
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { language: 'javascript', _: ['hello6.pot'] });
|
|
483
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
484
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
485
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
486
|
-
expect(errorSpy).toHaveBeenCalled();
|
|
487
|
-
});
|
|
488
|
-
it('should accept the language typescript', async () => {
|
|
489
|
-
const code = 'gtx._("Hello, world!");';
|
|
490
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
491
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { language: 'TypeScript', _: ['hello-language-typescript.ts'] });
|
|
492
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
493
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
494
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
495
|
-
expect(writeFileSync.mock.calls[0][1]).toMatchSnapshot();
|
|
496
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
497
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
498
|
-
});
|
|
499
|
-
});
|
|
500
|
-
});
|
|
501
|
-
describe('operation mode', () => {
|
|
502
|
-
describe('option --join-existing', () => {
|
|
503
|
-
beforeEach(resetMocks);
|
|
504
|
-
it('should merge into the output file regardless of language', async () => {
|
|
505
|
-
const existing = `
|
|
506
|
-
msgid "existing"
|
|
507
|
-
msgstr ""
|
|
508
|
-
`;
|
|
509
|
-
readFileSync.mockReturnValueOnce(Buffer.from(existing));
|
|
510
|
-
const code = 'gtx._("new")';
|
|
511
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
512
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { output: 'package.pot', language: 'javascript', joinExisting: true, _: ['join-existing1.js'] });
|
|
513
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
514
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
515
|
-
expect(readFileSync).toHaveBeenCalledTimes(2);
|
|
516
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
517
|
-
expect(writeFileSync.mock.calls[0][0]).toEqual('package.pot');
|
|
518
|
-
expect(writeFileSync.mock.calls[0][1]).toMatchSnapshot();
|
|
519
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
520
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
521
|
-
});
|
|
522
|
-
it('should bail out, when output is stdout', async () => {
|
|
523
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { output: '-', language: 'javascript', joinExisting: true, _: ['join-existing2.js'] });
|
|
524
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
525
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
526
|
-
expect(readFileSync).not.toHaveBeenCalled();
|
|
527
|
-
expect(writeFileSync).not.toHaveBeenCalled();
|
|
528
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
529
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
530
|
-
expect(errorSpy).toHaveBeenCalledWith('esgettext: Error: --join-existing cannot be used, when output is written to stdout');
|
|
531
|
-
});
|
|
532
|
-
it('should report exceptions', async () => {
|
|
533
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { output: 'package.pot', language: 'javascript', joinExisting: true, _: ['join-existing3.js'] });
|
|
534
|
-
readFileSync.mockImplementationOnce(() => {
|
|
535
|
-
throw new Error('no such file or directory');
|
|
536
|
-
});
|
|
537
|
-
readFileSync.mockReturnValueOnce(Buffer.from(''));
|
|
538
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
539
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
540
|
-
expect(readFileSync).toHaveBeenCalledTimes(2);
|
|
541
|
-
expect(readFileSync).toHaveBeenNthCalledWith(1, 'package.pot');
|
|
542
|
-
expect(readFileSync).toHaveBeenNthCalledWith(2, 'join-existing3.js');
|
|
543
|
-
expect(writeFileSync).not.toHaveBeenCalled();
|
|
544
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
545
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
546
|
-
expect(errorSpy).toHaveBeenCalledWith('package.pot: Error: no such file or directory');
|
|
547
|
-
});
|
|
548
|
-
it('should report parser errors', async () => {
|
|
549
|
-
const existing = `
|
|
550
|
-
msgidError "existing"
|
|
551
|
-
msgstr ""
|
|
552
|
-
`;
|
|
553
|
-
readFileSync.mockReturnValueOnce(Buffer.from(existing));
|
|
554
|
-
const code = 'gtx._("new")';
|
|
555
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
556
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { output: 'package.pot', language: 'javascript', joinExisting: true, _: ['join-existing1.js'] });
|
|
557
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
558
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
559
|
-
expect(readFileSync).toHaveBeenCalledTimes(2);
|
|
560
|
-
expect(writeFileSync).not.toHaveBeenCalled();
|
|
561
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
562
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
563
|
-
expect(errorSpy).toHaveBeenCalledWith('package.pot:2:1: Error: keyword "msgidError" unknown');
|
|
564
|
-
});
|
|
565
|
-
});
|
|
566
|
-
describe('option --exclude-file', () => {
|
|
567
|
-
beforeEach(resetMocks);
|
|
568
|
-
it('should exclude entries from the reference pots', async () => {
|
|
569
|
-
const exclude1 = `
|
|
570
|
-
msgid "exclude 1"
|
|
571
|
-
msgstr ""
|
|
572
|
-
`;
|
|
573
|
-
const exclude2 = `
|
|
574
|
-
msgid "exclude 2"
|
|
575
|
-
msgstr ""
|
|
576
|
-
`;
|
|
577
|
-
const code = `
|
|
578
|
-
gtx._("exclude 1");
|
|
579
|
-
gtx._("exclude 2");
|
|
580
|
-
gtx._("catch me!");
|
|
581
|
-
`;
|
|
582
|
-
readFileSync.mockReturnValueOnce(Buffer.from(exclude1));
|
|
583
|
-
readFileSync.mockReturnValueOnce(Buffer.from(exclude2));
|
|
584
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
585
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { excludeFile: ['exclude1.pot', 'exclude2.pot'], _: ['exclude-file1.js'] });
|
|
586
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
587
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
588
|
-
expect(readFileSync).toHaveBeenCalledTimes(3);
|
|
589
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
590
|
-
expect(writeFileSync.mock.calls[0][1]).toMatchSnapshot();
|
|
591
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
592
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
593
|
-
});
|
|
594
|
-
it('should report i/o errors for the reference pots', async () => {
|
|
595
|
-
readFileSync.mockImplementation(() => {
|
|
596
|
-
throw new Error('ouch!');
|
|
597
|
-
});
|
|
598
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { excludeFile: ['exclude1.pot', 'exclude2.pot'], _: ['exclude-file1.js'] });
|
|
599
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
600
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
601
|
-
expect(readFileSync).toHaveBeenCalledTimes(1);
|
|
602
|
-
expect(writeFileSync).toHaveBeenCalledTimes(0);
|
|
603
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
604
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
605
|
-
expect(errorSpy).toHaveBeenNthCalledWith(1, 'esgettext: Error: ouch!');
|
|
606
|
-
});
|
|
607
|
-
it('should report parsing errors for the reference pots', async () => {
|
|
608
|
-
readFileSync.mockReturnValue(Buffer.from('invalid'));
|
|
609
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { excludeFile: ['exclude1.pot', 'exclude2.pot'], _: ['exclude-file1.js'] });
|
|
610
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
611
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
612
|
-
expect(readFileSync).toHaveBeenCalledTimes(2);
|
|
613
|
-
expect(writeFileSync).toHaveBeenCalledTimes(0);
|
|
614
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
615
|
-
expect(errorSpy).toHaveBeenCalledTimes(4);
|
|
616
|
-
expect(errorSpy).toHaveBeenNthCalledWith(1, 'exclude1.pot:1:1: Error: keyword "invalid" unknown');
|
|
617
|
-
expect(errorSpy).toHaveBeenNthCalledWith(2, 'exclude1.pot:1:8: Error: syntax error');
|
|
618
|
-
expect(errorSpy).toHaveBeenNthCalledWith(3, 'exclude2.pot:1:1: Error: keyword "invalid" unknown');
|
|
619
|
-
expect(errorSpy).toHaveBeenNthCalledWith(4, 'exclude2.pot:1:8: Error: syntax error');
|
|
620
|
-
});
|
|
621
|
-
});
|
|
622
|
-
describe('add-comments', () => {
|
|
623
|
-
beforeEach(resetMocks);
|
|
624
|
-
it('should add selected comments', async () => {
|
|
625
|
-
const code = `
|
|
626
|
-
// TRANSLATORS: The abbreviated day of the week, not our star.
|
|
627
|
-
gtx._("Sun");
|
|
628
|
-
|
|
629
|
-
// TESTERS: This must be translated!
|
|
630
|
-
gtx._("Hello, world!");
|
|
631
|
-
|
|
632
|
-
// DEVELOPERS: Don't repeat yourself.
|
|
633
|
-
gtx._("Copy & Paste");
|
|
634
|
-
`;
|
|
635
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
636
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { addComments: ['TRANSLATORS:', 'TESTERS:'], _: ['add-comments.js'] });
|
|
637
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
638
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
639
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
640
|
-
expect(writeFileSync.mock.calls[0][1]).toMatchSnapshot();
|
|
641
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
642
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
643
|
-
});
|
|
644
|
-
});
|
|
645
|
-
describe('add-all-comments', () => {
|
|
646
|
-
beforeEach(resetMocks);
|
|
647
|
-
it('should add all comments', async () => {
|
|
648
|
-
const code = `
|
|
649
|
-
// TRANSLATORS: The abbreviated day of the week, not our star.
|
|
650
|
-
gtx._("Sun");
|
|
651
|
-
|
|
652
|
-
// TESTERS: This must be translated!
|
|
653
|
-
gtx._("Hello, world!");
|
|
654
|
-
|
|
655
|
-
// DEVELOPERS: Don't repeat yourself.
|
|
656
|
-
gtx._("Copy & Paste");
|
|
657
|
-
`;
|
|
658
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
659
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { addAllComments: true, _: ['add-comments.js'] });
|
|
660
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
661
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
662
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
663
|
-
expect(writeFileSync.mock.calls[0][1]).toMatchSnapshot();
|
|
664
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
665
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
666
|
-
});
|
|
667
|
-
});
|
|
668
|
-
});
|
|
669
|
-
describe('language specific options', () => {
|
|
670
|
-
describe('--extract-all', () => {
|
|
671
|
-
beforeEach(resetMocks);
|
|
672
|
-
it('should extract all strings', async () => {
|
|
673
|
-
const code = `
|
|
674
|
-
gtx._("gettext function");
|
|
675
|
-
console.log("non-gettext-function");
|
|
676
|
-
`;
|
|
677
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
678
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { extractAll: true, _: ['extract-all.js'] });
|
|
679
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
680
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
681
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
682
|
-
expect(writeFileSync.mock.calls[0][1]).toMatchSnapshot();
|
|
683
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
684
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
685
|
-
});
|
|
686
|
-
});
|
|
687
|
-
describe('--keyword', () => {
|
|
688
|
-
beforeEach(resetMocks);
|
|
689
|
-
it('should extract the selected keywords', async () => {
|
|
690
|
-
const code = `
|
|
691
|
-
gtx._("ignore");
|
|
692
|
-
gettext("catch");
|
|
693
|
-
npgettext("context", "one file", "multiple files", 2304);
|
|
694
|
-
`;
|
|
695
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
696
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { keyword: ['', 'gettext', 'npgettext:1c,2,3'], _: ['keyword.js'] });
|
|
697
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
698
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
699
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
700
|
-
expect(writeFileSync.mock.calls[0][1]).toMatchSnapshot();
|
|
701
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
702
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
703
|
-
});
|
|
704
|
-
});
|
|
705
|
-
});
|
|
706
|
-
describe('output details', () => {
|
|
707
|
-
describe('option --force-po', () => {
|
|
708
|
-
beforeEach(resetMocks);
|
|
709
|
-
it('should not write empty catalogs', async () => {
|
|
710
|
-
const code = 'console.log("Hello, world!")';
|
|
711
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
712
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['force-po1.js'] });
|
|
713
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
714
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
715
|
-
expect(writeFileSync).not.toHaveBeenCalled();
|
|
716
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
717
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
718
|
-
});
|
|
719
|
-
it('should write empty catalogs with option --force-po', async () => {
|
|
720
|
-
const code = 'console.log("Hello, world!")';
|
|
721
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
722
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { forcePo: true, _: ['force-po1.js'] });
|
|
723
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
724
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
725
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
726
|
-
expect(writeFileSync.mock.calls[0][1]).toMatchSnapshot();
|
|
727
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
728
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
729
|
-
});
|
|
730
|
-
});
|
|
731
|
-
describe('option --width', () => {
|
|
732
|
-
beforeEach(resetMocks);
|
|
733
|
-
it('should honor the option --width', async () => {
|
|
734
|
-
const code = 'gtx._("For a very long time! For a very long time!")';
|
|
735
|
-
readFileSync.mockReturnValue(Buffer.from(code));
|
|
736
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { width: 25, _: ['width.js'] });
|
|
737
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
738
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
739
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
740
|
-
expect(writeFileSync.mock.calls[0][1]).toMatchSnapshot();
|
|
741
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
742
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
743
|
-
});
|
|
744
|
-
});
|
|
745
|
-
});
|
|
746
|
-
});
|
|
747
|
-
describe('xgettext encodings', () => {
|
|
748
|
-
describe('ascii', () => {
|
|
749
|
-
beforeEach(resetMocks);
|
|
750
|
-
it('should accept plain ascii by default', async () => {
|
|
751
|
-
const code = 'gtx._("Hello, world!");';
|
|
752
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
753
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['hello-ascii.js'] });
|
|
754
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
755
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
756
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
757
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
758
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
759
|
-
});
|
|
760
|
-
it('should complain about 8 bit characters', async () => {
|
|
761
|
-
const code = `
|
|
762
|
-
gtx._("Hello, world!");
|
|
763
|
-
`;
|
|
764
|
-
const buf = Buffer.from(code).map(c => (c === 0x6f ? 0xf6 : c));
|
|
765
|
-
readFileSync.mockReturnValueOnce(buf);
|
|
766
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['hello-ascii.js'] });
|
|
767
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
768
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
769
|
-
expect(writeFileSync).toHaveBeenCalledTimes(0);
|
|
770
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
771
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
772
|
-
expect(errorSpy)
|
|
773
|
-
.toHaveBeenCalledWith(`hello-ascii.js:2:12: Error: Non-ASCII character.
|
|
774
|
-
Please specify the encoding through "--from-code".`);
|
|
775
|
-
});
|
|
776
|
-
it('should accept 8 bit characters with iso-8859-1', async () => {
|
|
777
|
-
const code = `
|
|
778
|
-
gtx._("Hello, world!");
|
|
779
|
-
`;
|
|
780
|
-
const buf = Buffer.from(code).map(c => (c === 0x6f ? 0xf6 : c));
|
|
781
|
-
readFileSync.mockReturnValueOnce(buf);
|
|
782
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { fromCode: 'iso-8859-1', _: ['hello-ascii.js'] });
|
|
783
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
784
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
785
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
786
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
787
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
788
|
-
expect(writeFileSync.mock.calls[0]).toMatchSnapshot();
|
|
789
|
-
});
|
|
790
|
-
it('should accept ASCII-8bit as an alias for ASCII', async () => {
|
|
791
|
-
const code = `gtx._("Hyvää yötä!")`;
|
|
792
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
793
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { _: ['hyvää-yötä.js'] });
|
|
794
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
795
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
796
|
-
expect(writeFileSync).toHaveBeenCalledTimes(0);
|
|
797
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
798
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
799
|
-
expect(errorSpy)
|
|
800
|
-
.toHaveBeenCalledWith(`hyvää-yötä.js:1:11: Error: Non-ASCII character.
|
|
801
|
-
Please specify the encoding through "--from-code".`);
|
|
802
|
-
});
|
|
803
|
-
it('should accept US-ASCII as an alias for ASCII', async () => {
|
|
804
|
-
const code = `gtx._("Hyvää yötä!")`;
|
|
805
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
806
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { fromCode: 'US-ASCII', _: ['hyvää-yötä.js'] });
|
|
807
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
808
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
809
|
-
expect(writeFileSync).toHaveBeenCalledTimes(0);
|
|
810
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
811
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
812
|
-
expect(errorSpy)
|
|
813
|
-
.toHaveBeenCalledWith(`hyvää-yötä.js:1:11: Error: Non-ASCII character.
|
|
814
|
-
Please specify the encoding through "--from-code".`);
|
|
815
|
-
});
|
|
816
|
-
it('should accept ANSI_X3.4-1968 as an alias for ASCII', async () => {
|
|
817
|
-
const code = `gtx._("Hyvää yötä!")`;
|
|
818
|
-
readFileSync.mockReturnValueOnce(Buffer.from(code));
|
|
819
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { fromCode: 'ANSI_X3.4-1968', _: ['hyvää-yötä.js'] });
|
|
820
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
821
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
822
|
-
expect(writeFileSync).toHaveBeenCalledTimes(0);
|
|
823
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
824
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
825
|
-
expect(errorSpy)
|
|
826
|
-
.toHaveBeenCalledWith(`hyvää-yötä.js:1:11: Error: Non-ASCII character.
|
|
827
|
-
Please specify the encoding through "--from-code".`);
|
|
828
|
-
});
|
|
829
|
-
});
|
|
830
|
-
describe('utf-8', () => {
|
|
831
|
-
beforeEach(resetMocks);
|
|
832
|
-
it('should accept valid utf-8', async () => {
|
|
833
|
-
const code = `
|
|
834
|
-
gtx._('Hyvää, yötä!');
|
|
835
|
-
gtx._('Добро, утро!');
|
|
836
|
-
gtx._('😀');
|
|
837
|
-
gtx._('좋은 아침!');
|
|
838
|
-
// Some random chars for better test coverage.
|
|
839
|
-
gtx._('પ툈');
|
|
840
|
-
gtx._('');
|
|
841
|
-
`;
|
|
842
|
-
const buf = Buffer.from(code);
|
|
843
|
-
readFileSync.mockReturnValueOnce(buf);
|
|
844
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { fromCode: 'utf-8', _: ['hello-ascii.js'] });
|
|
845
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
846
|
-
expect(await xgettext.run(argv)).toEqual(0);
|
|
847
|
-
expect(writeFileSync).toHaveBeenCalledTimes(1);
|
|
848
|
-
expect(writeFileSync.mock.calls[0][1]).toMatchSnapshot();
|
|
849
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
850
|
-
expect(errorSpy).not.toHaveBeenCalled();
|
|
851
|
-
});
|
|
852
|
-
it('should complain about a lone 8-bit byte', async () => {
|
|
853
|
-
const code = `
|
|
854
|
-
gtx._("Hello, world!");
|
|
855
|
-
`;
|
|
856
|
-
const buf = Buffer.from(code).map(c => (c === 0x6f ? 0xf6 : c));
|
|
857
|
-
readFileSync.mockReturnValueOnce(buf);
|
|
858
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { fromCode: 'utf-8', _: ['hello-ascii.js'] });
|
|
859
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
860
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
861
|
-
expect(writeFileSync).toHaveBeenCalledTimes(0);
|
|
862
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
863
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
864
|
-
expect(errorSpy).toHaveBeenCalledWith('hello-ascii.js:2:12: Error: invalid multibyte sequence');
|
|
865
|
-
});
|
|
866
|
-
it('should complain about invalid charsets', async () => {
|
|
867
|
-
const code = `
|
|
868
|
-
gtx._("Hello, world!");
|
|
869
|
-
`;
|
|
870
|
-
const buf = Buffer.from(code);
|
|
871
|
-
readFileSync.mockReturnValueOnce(buf);
|
|
872
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { fromCode: 'no-such-charset', _: ['hello-ascii.js'] });
|
|
873
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
874
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
875
|
-
expect(writeFileSync).toHaveBeenCalledTimes(0);
|
|
876
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
877
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
878
|
-
});
|
|
879
|
-
it('should complain about invalid charsets converting stanard input', async () => {
|
|
880
|
-
const code = `
|
|
881
|
-
gtx._("Hello, world!");
|
|
882
|
-
`;
|
|
883
|
-
const argv = Object.assign(Object.assign({}, baseArgv), { fromCode: 'no-such-charset', language: 'javascript', _: ['-'] });
|
|
884
|
-
const stdinSpy = jest
|
|
885
|
-
.spyOn(global.process.stdin, 'read')
|
|
886
|
-
.mockReturnValueOnce(Buffer.from(code));
|
|
887
|
-
const xgettext = new xgettext_1.XGettext(baseConfig, date);
|
|
888
|
-
expect(await xgettext.run(argv)).toEqual(1);
|
|
889
|
-
expect(stdinSpy).toHaveBeenCalledTimes(1);
|
|
890
|
-
stdinSpy.mockReset();
|
|
891
|
-
expect(writeFileSync).toHaveBeenCalledTimes(0);
|
|
892
|
-
expect(warnSpy).not.toHaveBeenCalled();
|
|
893
|
-
expect(errorSpy).toHaveBeenCalledTimes(1);
|
|
894
|
-
});
|
|
895
|
-
});
|
|
896
|
-
});
|
|
897
|
-
//# sourceMappingURL=xgettext.spec.js.map
|