diff --git a/__mocks__/filesystem.js b/__mocks__/filesystem.js
index a358976..2e177a9 100644
--- a/__mocks__/filesystem.js
+++ b/__mocks__/filesystem.js
@@ -20,8 +20,7 @@ export default class SearchPage extends Component {
}
static get template() {
- return '{{__('invalid''string')}}
} stack The current code stack
@@ -50,31 +62,42 @@ function continueUntilStackLengthIs(text, state, length) {
*/
module.exports = function parseLocalizationFunction(text, {index, stack, lineNumber}) {
const functionStart = {index, stack, lineNumber};
+ let plural = false;
+ let particular = false;
index += 1;
if (text.charAt(index + 1) === 'n') {
+ plural = true;
index += 1;
}
- if (text.charAt(index + 1) === '(') {
+ if (text.charAt(index + 1) === 'p') {
+ particular = true;
index += 1;
+ }
+ if (text.charAt(index + 1) === '(') {
+ index += 1;
}
- const keyStart = continueToQuoteStart(text, {index, stack, lineNumber});
- const keyEnd = continueUntilStackLengthIs(text, {...keyStart}, keyStart.stack.length - 1);
+ const metadata = {plural, particular};
+ let state = {index, stack, lineNumber};
- if (keyStart.index === keyEnd.index - 1) {
- throw new SyntaxError('empty localization key');
+ if (particular) {
+ let context;
+ [state, context] = readStringArgument(text, state, 'context');
+ metadata.context = context;
}
- const functionEnd = (keyEnd.stack[0] === '(') ?
- continueUntilStackLengthIs(text, {...keyEnd}, keyEnd.stack.length - 1) : keyEnd;
+ let key;
+ [state, key] = readStringArgument(text, state, 'key');
+ metadata.key = key;
+
+ const functionEnd = (state.stack[0] === '(') ?
+ continueUntilStackLengthIs(text, {...state}, state.stack.length - 1) : state;
+ const fn = text.substring(functionStart.index, functionEnd.index);
+ metadata.fn = fn;
- return {
- ...functionEnd,
- key: text.substring(keyStart.index, keyEnd.index - 1),
- fn: text.substring(functionStart.index, functionEnd.index),
- };
+ return Object.assign({}, functionEnd, metadata);
}
diff --git a/src/readCharacter.test.js b/src/readCharacter.test.js
index ac43499..dc9dd0d 100644
--- a/src/readCharacter.test.js
+++ b/src/readCharacter.test.js
@@ -221,6 +221,8 @@ describe('plugins/readCharacter', () => {
localization: {
key: 'a',
fn: '__("a")',
+ plural: false,
+ particular: false,
}
}, {
index: 8,
@@ -229,6 +231,33 @@ describe('plugins/readCharacter', () => {
}]);
});
+ it('parses basic translation function with context', () => {
+ let state = {index: 0, stack: [], lineNumber: 0}
+ const text = '__p("a", "b")c';
+ const actual = [];
+
+ while ((state = readCharacter(text, state)) !== null) {
+ actual.push(state);
+ }
+
+ expect(actual).toEqual([{
+ index: 13,
+ stack: [],
+ lineNumber: 0,
+ localization: {
+ context: 'a',
+ key: 'b',
+ fn: '__p("a", "b")',
+ plural: false,
+ particular: true,
+ }
+ }, {
+ index: 14,
+ stack: [],
+ lineNumber: 0,
+ }]);
+ });
+
it('parses basic plural translation function', () => {
let state = {index: 0, stack: [], lineNumber: 0}
const text = '__n("%d cat", "%d cats", 1)b';
@@ -245,6 +274,8 @@ describe('plugins/readCharacter', () => {
localization: {
key: '%d cat',
fn: '__n("%d cat", "%d cats", 1)',
+ plural: true,
+ particular: false,
}
}, {
index: 28,
@@ -253,6 +284,33 @@ describe('plugins/readCharacter', () => {
}]);
});
+ it('parses basic plural translation function with context', () => {
+ let state = {index: 0, stack: [], lineNumber: 0}
+ const text = '__np("a", "%d cat", "%d cats", 1)b';
+ const actual = [];
+
+ while ((state = readCharacter(text, state)) !== null) {
+ actual.push(state);
+ }
+
+ expect(actual).toEqual([{
+ index: 33,
+ stack: [],
+ lineNumber: 0,
+ localization: {
+ key: '%d cat',
+ context: 'a',
+ fn: '__np("a", "%d cat", "%d cats", 1)',
+ plural: true,
+ particular: true,
+ }
+ }, {
+ index: 34,
+ stack: [],
+ lineNumber: 0,
+ }]);
+ });
+
describe('polymer-style template strings', () => {
it('parses basic translation function in [[]] interpolation string', () => {
let state = {index: 0, stack: [], lineNumber: 0}
@@ -285,7 +343,9 @@ describe('plugins/readCharacter', () => {
lineNumber: 0,
localization: {
"key": "a",
- "fn": "__(\"a\")"
+ "fn": "__(\"a\")",
+ particular: false,
+ plural: false,
}
}, {
index: 12,
@@ -390,7 +450,9 @@ describe('plugins/readCharacter', () => {
lineNumber: 0,
localization: {
"key": "a",
- "fn": "__(\"a\")"
+ "fn": "__(\"a\")",
+ particular: false,
+ plural: false,
}
}, {
index: 12,
@@ -495,7 +557,9 @@ describe('plugins/readCharacter', () => {
lineNumber: 0,
localization: {
"key": "a",
- "fn": "__(\"a\")"
+ "fn": "__(\"a\")",
+ particular: false,
+ plural: false
}
}, {
index: 11,
@@ -579,7 +643,9 @@ describe('plugins/readCharacter', () => {
lineNumber: 0,
localization: {
"key": "a",
- "fn": "__(\"a\")"
+ "fn": "__(\"a\")",
+ plural: false,
+ particular: false,
}
}, {
index: 13,
@@ -664,6 +730,8 @@ describe('plugins/readCharacter', () => {
localization: {
key: 'a',
fn: '__`a`',
+ particular: false,
+ plural: false,
}
}, {
index: 6,
@@ -764,7 +832,7 @@ describe('plugins/readCharacter', () => {
while ((state = readCharacter(text, state)) !== null) {
actual.push(state);
}
- }).toThrow(new SyntaxError('empty localization key'));
+ }).toThrow(new SyntaxError('key string argument is empty'));
expect(actual).toEqual([]);
diff --git a/src/readString.test.js b/src/readString.test.js
index bf98530..4b5cf26 100644
--- a/src/readString.test.js
+++ b/src/readString.test.js
@@ -19,6 +19,16 @@ describe('readString', () => {
});
});
+ describe('singular with context', () => {
+ it('create key and value when contains translation', () => {
+ expect(readString(`a __p('b', 'c') d`)).toEqual({c: {fn: `__p('b', 'c')`, lineNumber: 0, index: 15}});
+ });
+
+ it('adds nothing when no translation', () => {
+ expect(readString(`a c`)).toEqual({});
+ });
+ });
+
describe('plural', () => {
it('create key and value when contains plural translation', () => {
expect(readString("a __n('%d cat', '%d cats', 1) c")).toEqual({
@@ -26,4 +36,12 @@ describe('readString', () => {
});
});
});
+
+ describe('plural with context', () => {
+ it('create key and value when contains plural translation', () => {
+ expect(readString("a __np('a', '%d cat', '%d cats', 1) c")).toEqual({
+ '%d cat': {fn: "__np('a', '%d cat', '%d cats', 1)", lineNumber: 0, index: 35}
+ });
+ });
+ });
});
diff --git a/src/test.js b/src/test.js
index d8fdaed..e6f9301 100644
--- a/src/test.js
+++ b/src/test.js
@@ -1,20 +1,21 @@
+/*eslint max-len: ["error", {"ignoreStrings": true}]*/
+
const TranslationStaticAnalyzer = require('.');
const fs = require('fs-extra');
-const console = require('console');
+//const console = require('console');
jest.mock('path');
jest.mock('glob');
jest.mock('fs-extra');
-jest.mock('console');
+//jest.mock('console');
const mocks = {};
-
const path = require('path');
describe('TranslationStaticAnalyzer', () => {
beforeEach(() => {
mocks.processOn = jest.spyOn(process, 'on');
- mocks.consoleLog = jest.spyOn(console, 'log');
+ //mocks.consoleLog = jest.spyOn(console, 'log');
path.relative.mockImplementation((from, to) => {
return to;
});
@@ -40,7 +41,7 @@ describe('TranslationStaticAnalyzer', () => {
target: 'test directory targets',
});
- delete analyzer.instance.cache.template;
+ delete analyzer.referenceTemplate;
fs.actions.length = 0;
analyzer.write();
@@ -48,40 +49,6 @@ describe('TranslationStaticAnalyzer', () => {
expect(fs.actions).toEqual([]);
});
- it('handles write gracefully when cache object is missing', () => {
- const analyzer = new TranslationStaticAnalyzer({
- files: 'test files',
- locales: ['existing'],
- target: 'test directory targets',
- });
-
- delete analyzer.instance.cache;
- fs.actions.length = 0;
-
- analyzer.write();
-
- expect(fs.actions).toEqual([]);
- });
-
- it('calls cleanup on exit', () => {
- const analyzer = new TranslationStaticAnalyzer({
- files: 'test files',
- locales: ['existing'],
- target: 'test directory targets',
- });
-
- const exitCallback = mocks.processOn.mock.calls[0];
- const sigIntCallback = mocks.processOn.mock.calls[1];
-
- expect(exitCallback[0]).toEqual('exit');
- expect(sigIntCallback[0]).toEqual('SIGINT');
-
- exitCallback[1]();
- sigIntCallback[1]();
-
- expect(fs.removeSync.mock.calls).toEqual([["/test/tmp/0"], ["/test/tmp/0"]]);
- });
-
it('works with defaults for language with some prefilled data', () => {
const analyzer = new TranslationStaticAnalyzer({
files: 'test files',
@@ -92,123 +59,122 @@ describe('TranslationStaticAnalyzer', () => {
analyzer.update();
expect(fs.actions).toEqual([
- {
- "action": "read",
- "filename": "src/pages/Search/index.js",
- "data": "export default class SearchPage extends Component {\n static get title() {\n return __('Search');\n }\n\n static get template() {\n return '{{__('invalid''string')}} {{__n('%d result', '%d results', 2)}}
';\n\n }\n};"
- },
- {
- "action": "read",
- "filename": "src/pages/About/index.js",
- "data": "export default class AboutPage extends Component {\n static get title() {\n return __('About');\n }\n\n static get template() {\n return {{__('Search')}} Welcome to the about page!
';\n\n }\n};"
- },
- {
- "action": "read",
- "filename": "src/index.js",
- "data": "export default class Application extends Component {\n static get title() {\n return __('Application');\n }\n};"
- },
- {
- "action": "read",
- "filename": "src/test.js",
- "data": null
- },
- {
- "action": "read",
- "filename": "./locales/existing.json",
- "data": "{\"Search\":\"検索\",\"test unused key\":\"test value\",\"Application\":\"アプリケーション\"}"
- },
- {
- "action": "write",
- "filename": "./locales/existing.json",
- "data": "{\n // NEW\n // src/pages/Search/index.js:6\n \"%d result\": {\"one\":\"\",\"other\":\"\"},\n // NEW\n // src/pages/About/index.js:2\n \"About\": \"\",\n // src/index.js:2\n \"Application\": \"アプリケーション\",\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"Search\": \"検索\",\n // UNUSED\n \"test unused key\": \"test value\"\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/.locales/existing.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/.locales/existing.json",
- "data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/.locales/index.json",
- "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n }\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/Search/.locales/existing.json",
- "data": "{\"Search\":\"\"}"
- },
- {
- "action": "write",
- "filename": "src/pages/Search/.locales/existing.json",
- "data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/Search/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/Search/.locales/index.json",
- "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n }\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/About/.locales/existing.json",
- "data": "{}"
- },
- {
- "action": "write",
- "filename": "src/pages/About/.locales/existing.json",
- "data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/About/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/About/.locales/index.json",
- "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n }\n}"
- },
- {
- "action": "read",
- "filename": "src/application/.locales/existing.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/application/.locales/existing.json",
- "data": "{\n \"Application\": \"アプリケーション\"\n}"
- },
- {
- "action": "read",
- "filename": "src/application/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/application/.locales/index.json",
- "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\"\n }\n}"
- }
+ {
+ "action": "read",
+ "filename": "src/pages/Search/index.js",
+ "data": "export default class SearchPage extends Component {\n static get title() {\n return __('Search');\n }\n\n static get template() {\n return '{{__('invalid''string')}} {{__n('%d result', '%d results', 2)}}
';\n\n }\n};"
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/About/index.js",
+ "data": "export default class AboutPage extends Component {\n static get title() {\n return __('About');\n }\n\n static get template() {\n return {{__('Search')}} Welcome to the about page!
';\n\n }\n};"
+ },
+ {
+ "action": "read",
+ "filename": "src/index.js",
+ "data": "export default class Application extends Component {\n static get title() {\n return __('Application');\n }\n};"
+ },
+ {
+ "action": "read",
+ "filename": "src/test.js",
+ "data": null
+ },
+ {
+ "action": "read",
+ "filename": "./locales/existing.json",
+ "data": "{\"Search\":{\"default\":\"検索\"},\"test unused key\":{\"default\":\"test value\"},\"Application\":{\"default\":\"アプリケーション\"}}"
+ },
+ {
+ "action": "write",
+ "filename": "./locales/existing.json",
+ "data": "{\n \"%d result\": {\n // NEW\n // src/pages/Search/index.js:6\n \"default\": {\"one\":\"\",\"other\":\"\"}\n },\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // src/index.js:2\n \"default\": \"アプリケーション\"\n },\n \"Search\": {\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"default\": \"検索\"\n },\n \"test unused key\": {\n // UNUSED\n \"default\": \"test value\"\n }\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/.locales/existing.json",
+ "data": null
+ },
+ {
+ "action": "write",
+ "filename": "src/pages/.locales/existing.json",
+ "data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/.locales/index.json",
+ "data": null
+ },
+ {
+ "action": "write",
+ "filename": "src/pages/.locales/index.json",
+ "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n }\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/Search/.locales/existing.json",
+ "data": "{\"Search\":\"\"}"
+ },
+ {
+ "action": "write",
+ "filename": "src/pages/Search/.locales/existing.json",
+ "data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/Search/.locales/index.json",
+ "data": null
+ },
+ {
+ "action": "write",
+ "filename": "src/pages/Search/.locales/index.json",
+ "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n }\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/About/.locales/existing.json",
+ "data": "{}"
+ },
+ {
+ "action": "write",
+ "filename": "src/pages/About/.locales/existing.json",
+ "data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/About/.locales/index.json",
+ "data": null
+ },
+ {
+ "action": "write",
+ "filename": "src/pages/About/.locales/index.json",
+ "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n }\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/application/.locales/existing.json",
+ "data": null
+ },
+ {
+ "action": "write",
+ "filename": "src/application/.locales/existing.json",
+ "data": "{\n \"Application\": \"アプリケーション\"\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/application/.locales/index.json",
+ "data": null
+ },
+ {
+ "action": "write",
+ "filename": "src/application/.locales/index.json",
+ "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\"\n }\n}"
+ }
]);
fs.actions.length = 0;
analyzer.update();
-
- expect(fs.actions).toEqual([
+ expect(fs.actions).toEqual([
{
"action": "read",
"filename": "src/pages/Search/index.js",
@@ -232,9 +198,9 @@ describe('TranslationStaticAnalyzer', () => {
{
"action": "read",
"filename": "./locales/existing.json",
- "data": "{\n // NEW\n // src/pages/Search/index.js:6\n \"%d result\": {\"one\":\"\",\"other\":\"\"},\n // NEW\n // src/pages/About/index.js:2\n \"About\": \"\",\n // src/index.js:2\n \"Application\": \"アプリケーション\",\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"Search\": \"検索\",\n // UNUSED\n \"test unused key\": \"test value\"\n}"
+ "data": "{\n \"%d result\": {\n // NEW\n // src/pages/Search/index.js:6\n \"default\": {\"one\":\"\",\"other\":\"\"}\n },\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // src/index.js:2\n \"default\": \"アプリケーション\"\n },\n \"Search\": {\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"default\": \"検索\"\n },\n \"test unused key\": {\n // UNUSED\n \"default\": \"test value\"\n }\n}"
}
- ]);
+ ]);
});
describe('read', () => {
@@ -307,91 +273,6 @@ describe('TranslationStaticAnalyzer', () => {
expect(fs.actions).toEqual(
[
- {
- "action": "read",
- "filename": "./locales/existing.json",
- "data": "{\"Search\":\"検索\",\"test unused key\":\"test value\",\"Application\":\"アプリケーション\"}"
- },
- {
- "action": "write",
- "filename": "./locales/existing.json",
- "data": "{\n // NEW\n \"%s result\": {\"one\":\"\",\"other\":\"\"},\n // NEW\n \"About\": \"\",\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\",\n // UNUSED\n \"test unused key\": \"test value\"\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/.locales/existing.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/.locales/existing.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/pages/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/.locales/index.json",
- "data": "{\n \"existing\": {}\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/Search/.locales/existing.json",
- "data": "{\"Search\":\"\"}"
- },
- {
- "action": "write",
- "filename": "src/pages/Search/.locales/existing.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/pages/Search/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/Search/.locales/index.json",
- "data": "{\n \"existing\": {}\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/About/.locales/existing.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/pages/About/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/About/.locales/index.json",
- "data": "{\n \"existing\": {}\n}"
- },
- {
- "action": "read",
- "filename": "src/application/.locales/existing.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/application/.locales/existing.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/application/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/application/.locales/index.json",
- "data": "{\n \"existing\": {}\n}"
- }
]
);
});
@@ -415,46 +296,31 @@ describe('TranslationStaticAnalyzer', () => {
analyzer.update(['src/pages/Search/index.js']);
expect(fs.actions).toEqual([
- {
- "action": "read",
- "filename": "./locales/existing.json",
- "data": "{\n // NEW\n // src/pages/Search/index.js:6\n \"%d result\": {\"one\":\"\",\"other\":\"\"},\n // NEW\n // src/pages/About/index.js:2\n \"About\": \"\",\n // src/index.js:2\n \"Application\": \"アプリケーション\",\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"Search\": \"検索\",\n // UNUSED\n \"test unused key\": \"test value\"\n}"
- },
- {
- "action": "write",
- "filename": "./locales/existing.json",
- "data": "{\n // NEW\n // src/pages/About/index.js:2\n \"About\": \"\",\n // src/index.js:2\n \"Application\": \"アプリケーション\",\n // src/pages/About/index.js:6\n \"Search\": \"検索\",\n // UNUSED\n \"test unused key\": \"test value\"\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/.locales/existing.json",
- "data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/.locales/index.json",
- "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n }\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/About/.locales/existing.json",
- "data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/About/.locales/index.json",
- "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n }\n}"
- },
- {
- "action": "read",
- "filename": "src/application/.locales/existing.json",
- "data": "{\n \"Application\": \"アプリケーション\"\n}"
- },
- {
- "action": "read",
- "filename": "src/application/.locales/index.json",
- "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\"\n }\n}"
- }
+ {
+ "action": "read",
+ "filename": "./locales/existing.json",
+ "data": "{\n \"%d result\": {\n // NEW\n // src/pages/Search/index.js:6\n \"default\": {\"one\":\"\",\"other\":\"\"}\n },\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // src/index.js:2\n \"default\": \"アプリケーション\"\n },\n \"Search\": {\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"default\": \"検索\"\n },\n \"test unused key\": {\n // UNUSED\n \"default\": \"test value\"\n }\n}"
+ },
+ {
+ "action": "write",
+ "filename": "./locales/existing.json",
+ "data": "{\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // src/index.js:2\n \"default\": \"アプリケーション\"\n },\n \"Search\": {\n // src/pages/About/index.js:6\n \"default\": \"検索\"\n },\n \"test unused key\": {\n // UNUSED\n \"default\": \"test value\"\n }\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/.locales/existing.json",
+ "data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/About/.locales/existing.json",
+ "data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/application/.locales/existing.json",
+ "data": "{\n \"Application\": \"アプリケーション\"\n}"
+ }
]);
});
@@ -469,19 +335,36 @@ describe('TranslationStaticAnalyzer', () => {
expect(fs.readFileSync('./locales/existing.json')).toEqual(
`{
- // NEW
- // src/pages/Search/index.js:6
- "%d result": {"one":"","other":""},
- // NEW
- // src/pages/About/index.js:2
- "About": "",
- // src/index.js:2
- "Application": "アプリケーション",
- // src/pages/About/index.js:6
- // src/pages/Search/index.js:2
- "Search": "検索",
- // UNUSED
- "test unused key": "test value"
+ "%d result": {
+ // NEW
+ // src/pages/Search/index.js:6
+ "default": {"one":"","other":""}
+ },
+ "%d view": {
+ // NEW
+ // src/pages/Search/index.js:6
+ "footer": {"one":"","other":""}
+ },
+ "About": {
+ // NEW
+ // src/pages/About/index.js:2
+ "default": ""
+ },
+ "Application": {
+ // src/index.js:2
+ "default": "アプリケーション"
+ },
+ "Search": {
+ // src/pages/About/index.js:6
+ "default": "検索",
+ // NEW
+ // src/pages/Search/index.js:6
+ "menuitem": ""
+ },
+ "test unused key": {
+ // UNUSED
+ "default": "test value"
+ }
}`
);
@@ -494,30 +377,37 @@ describe('TranslationStaticAnalyzer', () => {
expect(fs.readFileSync('./locales/existing.json')).toEqual(
`{
- // NEW
- // src/pages/About/index.js:2
- "About": "",
- // src/index.js:2
- "Application": "アプリケーション",
- // src/pages/About/index.js:6
- "Search": "検索",
- // UNUSED
- "test unused key": "test value"
+ "About": {
+ // NEW
+ // src/pages/About/index.js:2
+ "default": ""
+ },
+ "Application": {
+ // src/index.js:2
+ "default": "アプリケーション"
+ },
+ "Search": {
+ // src/pages/About/index.js:6
+ "default": "検索"
+ },
+ "test unused key": {
+ // UNUSED
+ "default": "test value"
+ }
}`
);
- /*
-
+ console.log(JSON.stringify(fs.actions, null, 4));
expect(fs.actions).toEqual([
{
"action": "read",
"filename": "./locales/existing.json",
- "data": "{\n // NEW\n // \n \"%d result\": {\"one\":\"\",\"other\":\"\"},\n // NEW\n // \n \"About\": \"\",\n // \n \"Application\": \"アプリケーション\",\n // \n // \n \"Search\": \"検索\",\n // UNUSED\n \"test unused key\": \"test value\"\n}"
+ "data": "{\n \"%d result\": {\n // NEW\n // src/pages/Search/index.js:6\n \"default\": {\"one\":\"\",\"other\":\"\"}\n },\n \"%d view\": {\n // NEW\n // src/pages/Search/index.js:6\n \"footer\": {\"one\":\"\",\"other\":\"\"}\n },\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // src/index.js:2\n \"default\": \"アプリケーション\"\n },\n \"Search\": {\n // src/pages/About/index.js:6\n \"default\": \"検索\",\n // NEW\n // src/pages/Search/index.js:6\n \"menuitem\": \"\"\n },\n \"test unused key\": {\n // UNUSED\n \"default\": \"test value\"\n }\n}"
},
{
"action": "write",
"filename": "./locales/existing.json",
- "data": "{\n // NEW\n // \n \"About\": \"\",\n // \n \"Application\": \"アプリケーション\",\n // \n \"Search\": \"検索\",\n // UNUSED\n \"test unused key\": \"test value\"\n}"
+ "data": "{\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // src/index.js:2\n \"default\": \"アプリケーション\"\n },\n \"Search\": {\n // src/pages/About/index.js:6\n \"default\": \"検索\"\n },\n \"test unused key\": {\n // UNUSED\n \"default\": \"test value\"\n }\n}"
},
{
"action": "read",
@@ -533,9 +423,13 @@ describe('TranslationStaticAnalyzer', () => {
"action": "read",
"filename": "src/application/.locales/existing.json",
"data": "{\n \"Application\": \"アプリケーション\"\n}"
+ },
+ {
+ "action": "read",
+ "filename": "./locales/existing.json",
+ "data": "{\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // src/index.js:2\n \"default\": \"アプリケーション\"\n },\n \"Search\": {\n // src/pages/About/index.js:6\n \"default\": \"検索\"\n },\n \"test unused key\": {\n // UNUSED\n \"default\": \"test value\"\n }\n}"
}
- ]);
- */
+ ]);
});
it('removes unreadable source file', () => {
@@ -570,23 +464,18 @@ describe('TranslationStaticAnalyzer', () => {
{
"action": "read",
"filename": "./locales/existing.json",
- "data": "{\n // NEW\n // src/pages/Search/index.js:6\n \"%d result\": {\"one\":\"\",\"other\":\"\"},\n // NEW\n // src/pages/About/index.js:2\n \"About\": \"\",\n // src/index.js:2\n \"Application\": \"アプリケーション\",\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"Search\": \"検索\",\n // UNUSED\n \"test unused key\": \"test value\"\n}"
+ "data": "{\n \"%d result\": {\n // NEW\n // src/pages/Search/index.js:6\n \"default\": {\"one\":\"\",\"other\":\"\"}\n },\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // src/index.js:2\n \"default\": \"アプリケーション\"\n },\n \"Search\": {\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"default\": \"検索\"\n },\n \"test unused key\": {\n // UNUSED\n \"default\": \"test value\"\n }\n}"
},
{
"action": "write",
"filename": "./locales/existing.json",
- "data": "{\n // NEW\n // src/pages/About/index.js:2\n \"About\": \"\",\n // src/index.js:2\n \"Application\": \"アプリケーション\",\n // src/pages/About/index.js:6\n \"Search\": \"検索\",\n // UNUSED\n \"test unused key\": \"test value\"\n}"
+ "data": "{\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // src/index.js:2\n \"default\": \"アプリケーション\"\n },\n \"Search\": {\n // src/pages/About/index.js:6\n \"default\": \"検索\"\n },\n \"test unused key\": {\n // UNUSED\n \"default\": \"test value\"\n }\n}"
},
{
"action": "read",
"filename": "src/pages/.locales/existing.json",
"data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
},
- {
- "action": "read",
- "filename": "src/pages/.locales/index.json",
- "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n }\n}"
- },
{
"action": "read",
"filename": "src/pages/Search/.locales/existing.json",
@@ -655,43 +544,28 @@ describe('TranslationStaticAnalyzer', () => {
{
"action": "read",
"filename": "./locales/existing.json",
- "data": "{\n // NEW\n // src/pages/Search/index.js:6\n \"%d result\": {\"one\":\"\",\"other\":\"\"},\n // NEW\n // src/pages/About/index.js:2\n \"About\": \"\",\n // src/index.js:2\n \"Application\": \"アプリケーション\",\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"Search\": \"検索\",\n // UNUSED\n \"test unused key\": \"test value\"\n}"
+ "data": "{\n \"%d result\": {\n // NEW\n // src/pages/Search/index.js:6\n \"default\": {\"one\":\"\",\"other\":\"\"}\n },\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // src/index.js:2\n \"default\": \"アプリケーション\"\n },\n \"Search\": {\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"default\": \"検索\"\n },\n \"test unused key\": {\n // UNUSED\n \"default\": \"test value\"\n }\n}"
},
{
"action": "write",
"filename": "./locales/existing.json",
- "data": "{\n // NEW\n // src/pages/Search/index.js:6\n \"%d result\": {\"one\":\"\",\"other\":\"\"},\n // NEW\n // src/pages/About/index.js:2\n \"About\": \"\",\n // NEW\n // src/pages/Added/index.js:0\n \"Added\": \"\",\n // src/index.js:2\n \"Application\": \"アプリケーション\",\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"Search\": \"検索\",\n // UNUSED\n \"test unused key\": \"test value\"\n}"
+ "data": "{\n \"%d result\": {\n // NEW\n // src/pages/Search/index.js:6\n \"default\": {\"one\":\"\",\"other\":\"\"}\n },\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Added\": {\n // NEW\n // src/pages/Added/index.js:0\n \"default\": \"\"\n },\n \"Application\": {\n // src/index.js:2\n \"default\": \"アプリケーション\"\n },\n \"Search\": {\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"default\": \"検索\"\n },\n \"test unused key\": {\n // UNUSED\n \"default\": \"test value\"\n }\n}"
},
{
"action": "read",
"filename": "src/pages/.locales/existing.json",
"data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
},
- {
- "action": "read",
- "filename": "src/pages/.locales/index.json",
- "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n }\n}"
- },
{
"action": "read",
"filename": "src/pages/About/.locales/existing.json",
"data": "{\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n}"
},
- {
- "action": "read",
- "filename": "src/pages/About/.locales/index.json",
- "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\",\n \"Search\": \"検索\"\n }\n}"
- },
{
"action": "read",
"filename": "src/application/.locales/existing.json",
"data": "{\n \"Application\": \"アプリケーション\"\n}"
},
- {
- "action": "read",
- "filename": "src/application/.locales/index.json",
- "data": "{\n \"existing\": {\n \"Application\": \"アプリケーション\"\n }\n}"
- },
{
"action": "read",
"filename": "src/pages/Added/.locales/existing.json",
@@ -816,7 +690,7 @@ describe('TranslationStaticAnalyzer', () => {
target: 'test directory targets'
});
- fs.readFileSync.mockImplementation((filename) => {
+ fs.readFileSync = jest.fn().mockImplementation((filename) => {
if (filename.endsWith('.json')) {
const e = new Error("MockError: readFileSync issue");
e.code = 'TEST ERROR';
@@ -839,116 +713,56 @@ describe('TranslationStaticAnalyzer', () => {
analyzer.update();
expect(fs.actions).toEqual([
- {
- "action": "read",
- "filename": "src/pages/Search/index.js",
- "data": "export default class SearchPage extends Component {\n static get title() {\n return __('Search');\n }\n\n static get template() {\n return '{{__('invalid''string')}} {{__n('%d result', '%d results', 2)}}
';\n\n }\n};"
- },
- {
- "action": "read",
- "filename": "src/pages/About/index.js",
- "data": "export default class AboutPage extends Component {\n static get title() {\n return __('About');\n }\n\n static get template() {\n return {{__('Search')}} Welcome to the about page!
';\n\n }\n};"
- },
- {
- "action": "read",
- "filename": "src/index.js",
- "data": "export default class Application extends Component {\n static get title() {\n return __('Application');\n }\n};"
- },
- {
- "action": "read",
- "filename": "src/test.js",
- "data": null
- },
- {
- "action": "read",
- "filename": "./locales/new.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "./locales/new.json",
- "data": "{\n // NEW\n // src/pages/Search/index.js:6\n \"%d result\": {\"one\":\"\",\"other\":\"\"},\n // NEW\n // src/pages/About/index.js:2\n \"About\": \"\",\n // NEW\n // src/index.js:2\n \"Application\": \"\",\n // NEW\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"Search\": \"\"\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/.locales/new.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/.locales/new.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/pages/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/.locales/index.json",
- "data": "{\n \"new\": {}\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/Search/.locales/new.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/Search/.locales/new.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/pages/Search/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/Search/.locales/index.json",
- "data": "{\n \"new\": {}\n}"
- },
- {
- "action": "read",
- "filename": "src/pages/About/.locales/new.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/About/.locales/new.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/pages/About/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/About/.locales/index.json",
- "data": "{\n \"new\": {}\n}"
- },
- {
- "action": "read",
- "filename": "src/application/.locales/new.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/application/.locales/new.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/application/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/application/.locales/index.json",
- "data": "{\n \"new\": {}\n}"
- }
+ {
+ "action": "read",
+ "filename": "src/pages/Search/index.js",
+ "data": "export default class SearchPage extends Component {\n static get title() {\n return __('Search');\n }\n\n static get template() {\n return '{{__('invalid''string')}} {{__n('%d result', '%d results', 2)}}
';\n\n }\n};"
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/About/index.js",
+ "data": "export default class AboutPage extends Component {\n static get title() {\n return __('About');\n }\n\n static get template() {\n return {{__('Search')}} Welcome to the about page!
';\n\n }\n};"
+ },
+ {
+ "action": "read",
+ "filename": "src/index.js",
+ "data": "export default class Application extends Component {\n static get title() {\n return __('Application');\n }\n};"
+ },
+ {
+ "action": "read",
+ "filename": "src/test.js",
+ "data": null
+ },
+ {
+ "action": "read",
+ "filename": "./locales/new.json",
+ "data": null
+ },
+ {
+ "action": "write",
+ "filename": "./locales/new.json",
+ "data": "{\n \"%d result\": {\n // NEW\n // src/pages/Search/index.js:6\n \"default\": {\"one\":\"\",\"other\":\"\"}\n },\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // NEW\n // src/index.js:2\n \"default\": \"\"\n },\n \"Search\": {\n // NEW\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"default\": \"\"\n }\n}"
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/.locales/new.json",
+ "data": null
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/Search/.locales/new.json",
+ "data": null
+ },
+ {
+ "action": "read",
+ "filename": "src/pages/About/.locales/new.json",
+ "data": null
+ },
+ {
+ "action": "read",
+ "filename": "src/application/.locales/new.json",
+ "data": null
+ }
]);
});
@@ -969,7 +783,7 @@ describe('TranslationStaticAnalyzer', () => {
{
"action": "read",
"filename": "src/pages/Search/index.js",
- "data": "export default class SearchPage extends Component {\n static get title() {\n return __('Search');\n }\n\n static get template() {\n return '{{__('invalid''string')}} {{__n('%d result', '%d results', 2)}}
';\n\n }\n};"
+ "data": "export default class SearchPage extends Component {\n static get title() {\n return __('Search');\n }\n\n static get template() {\n return '{{__('invalid''string')}} {{__p('menuitem', 'Search')}} {{__n('%d result', '%d results', 2)}}
{{__np('footer', '%d view', '%d views', 23)}}';\n }\n};"
},
{
"action": "read",
@@ -994,87 +808,27 @@ describe('TranslationStaticAnalyzer', () => {
{
"action": "write",
"filename": "./locales/new.json",
- "data": "{\n // NEW\n // src/pages/Search/index.js:6\n \"%d result\": {\"one\":\"\",\"other\":\"\"},\n // NEW\n // src/pages/About/index.js:2\n \"About\": \"\",\n // NEW\n // src/index.js:2\n \"Application\": \"\",\n // NEW\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"Search\": \"\"\n}"
+ "data": "{\n \"%d result\": {\n // NEW\n // src/pages/Search/index.js:6\n \"default\": {\"one\":\"\",\"other\":\"\"}\n },\n \"%d view\": {\n // NEW\n // src/pages/Search/index.js:6\n \"footer\": {\"one\":\"\",\"other\":\"\"}\n },\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // NEW\n // src/index.js:2\n \"default\": \"\"\n },\n \"Search\": {\n // NEW\n // src/pages/About/index.js:6\n \"default\": \"\"\n // NEW\n // src/pages/Search/index.js:6\n \"menuitem\": \"\"\n }\n}"
},
{
"action": "read",
"filename": "src/pages/.locales/new.json",
"data": null
},
- {
- "action": "write",
- "filename": "src/pages/.locales/new.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/pages/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/.locales/index.json",
- "data": "{\n \"new\": {}\n}"
- },
{
"action": "read",
"filename": "src/pages/Search/.locales/new.json",
"data": null
},
- {
- "action": "write",
- "filename": "src/pages/Search/.locales/new.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/pages/Search/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/Search/.locales/index.json",
- "data": "{\n \"new\": {}\n}"
- },
{
"action": "read",
"filename": "src/pages/About/.locales/new.json",
"data": null
},
- {
- "action": "write",
- "filename": "src/pages/About/.locales/new.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/pages/About/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/About/.locales/index.json",
- "data": "{\n \"new\": {}\n}"
- },
{
"action": "read",
"filename": "src/application/.locales/new.json",
"data": null
- },
- {
- "action": "write",
- "filename": "src/application/.locales/new.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/application/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/application/.locales/index.json",
- "data": "{\n \"new\": {}\n}"
}
]);
});
@@ -1116,7 +870,7 @@ describe('TranslationStaticAnalyzer', () => {
{
"action": "read",
"filename": "src/pages/Search/index.js",
- "data": "export default class SearchPage extends Component {\n static get title() {\n return __('Search');\n }\n\n static get template() {\n return '{{__('invalid''string')}} {{__n('%d result', '%d results', 2)}}
';\n\n }\n};"
+ "data": "export default class SearchPage extends Component {\n static get title() {\n return __('Search');\n }\n\n static get template() {\n return '{{__('invalid''string')}} {{__p('menuitem', 'Search')}} {{__n('%d result', '%d results', 2)}}
{{__np('footer', '%d view', '%d views', 23)}}';\n }\n};"
},
{
"action": "read",
@@ -1141,28 +895,13 @@ describe('TranslationStaticAnalyzer', () => {
{
"action": "write",
"filename": "testtemplatespath/locales/existing.json",
- "data": "{\n // NEW\n // src/pages/Search/index.js:6\n \"%d result\": {\"one\":\"\",\"other\":\"\"},\n // NEW\n // src/pages/About/index.js:2\n \"About\": \"\",\n // NEW\n // src/index.js:2\n \"Application\": \"\",\n // NEW\n // src/pages/About/index.js:6\n // src/pages/Search/index.js:2\n \"Search\": \"\"\n}"
+ "data": "{\n \"%d result\": {\n // NEW\n // src/pages/Search/index.js:6\n \"default\": {\"one\":\"\",\"other\":\"\"}\n },\n \"%d view\": {\n // NEW\n // src/pages/Search/index.js:6\n \"footer\": {\"one\":\"\",\"other\":\"\"}\n },\n \"About\": {\n // NEW\n // src/pages/About/index.js:2\n \"default\": \"\"\n },\n \"Application\": {\n // NEW\n // src/index.js:2\n \"default\": \"\"\n },\n \"Search\": {\n // NEW\n // src/pages/About/index.js:6\n \"default\": \"\"\n // NEW\n // src/pages/Search/index.js:6\n \"menuitem\": \"\"\n }\n}"
},
{
"action": "read",
"filename": "src/pages/.locales/existing.json",
"data": null
},
- {
- "action": "write",
- "filename": "src/pages/.locales/existing.json",
- "data": "{}"
- },
- {
- "action": "read",
- "filename": "src/pages/.locales/index.json",
- "data": null
- },
- {
- "action": "write",
- "filename": "src/pages/.locales/index.json",
- "data": "{\n \"existing\": {}\n}"
- },
{
"action": "read",
"filename": "src/pages/Search/.locales/existing.json",
@@ -1203,11 +942,6 @@ describe('TranslationStaticAnalyzer', () => {
"filename": "src/application/.locales/existing.json",
"data": null
},
- {
- "action": "write",
- "filename": "src/application/.locales/existing.json",
- "data": "{}"
- },
{
"action": "read",
"filename": "src/application/.locales/index.json",
diff --git a/yarn.lock b/yarn.lock
index f898088..1998a0c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3662,6 +3662,10 @@ pretty-format@^23.5.0:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
+printf@^0.5.1:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/printf/-/printf-0.5.1.tgz#e0466788260859ed153006dc6867f09ddf240cf3"
+
private@^0.1.6, private@^0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
@@ -4729,10 +4733,6 @@ y18n@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
-y18n@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
-
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"