Skip to content

Commit

Permalink
Merge pull request #90 from mikeedwards/1.0.0-beta-3
Browse files Browse the repository at this point in the history
updated tests for beta-3 and rebuilt packages for node 10 and up
  • Loading branch information
mikeedwards authored Jul 19, 2020
2 parents b26a930 + 3d68df8 commit 47b1e91
Show file tree
Hide file tree
Showing 9 changed files with 4,044 additions and 1,435 deletions.
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
language: node_js
node_js:
- 9
- 8
- 7
- 6
- 14
- 13
- 12
- 10
35 changes: 20 additions & 15 deletions lib/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
* @param {Object} [options]
* @return {Object|String} Translation JSON
*/
var g2m = require('gettext-to-messageformat');
const g2m = require('gettext-to-messageformat');

module.exports = function (buffer, options) {

// Setup options and load in defaults
options = options || {};
var defaults = {
const defaults = {
pretty: false,
fuzzy: false,
stringify: false,
Expand All @@ -22,17 +22,23 @@ module.exports = function (buffer, options) {
mfOptions: {},
};

for (var property in defaults) {
for (const property in defaults) {
options[property] = 'undefined' !== typeof options[property] ? options[property] : defaults[property];
}

var mfTranslations = {};
var mf = {};
const mf = {};
let mfTranslations = {};
let result = {};

// defer to gettext-to-messageformat for the 'mf' format option
// use all g2m default replacements except for: pattern: /[\\{}#]/g, replacement: '\\$&'
if (options.format === 'mf') {
result = Object.keys(options.mfOptions).length > 0 ? g2m.parsePo(buffer, options.mfOptions) : g2m.parsePo(buffer);
const poString = buffer.toString();
// if the Plural-Forms header is missing, g2m needs a function or will throw an error
const mfOptions = (poString.includes('"Plural-Forms:')) ? options.mfOptions : Object.assign({}, {
pluralFunction: () => 0
}, options.mfOptions);
result = Object.keys(mfOptions).length > 0 ? g2m.parsePo(buffer, mfOptions) : g2m.parsePo(buffer);

if (options.fullMF) {
return options.stringify ? JSON.stringify(result, null, options.pretty ? ' ' : null) : result;
Expand Down Expand Up @@ -61,18 +67,17 @@ module.exports = function (buffer, options) {
}

// Parse the PO file
var parsed = require('gettext-parser').po.parse(buffer, defaults.charset);
const parsed = require('gettext-parser').po.parse(buffer, defaults.charset);

// Create gettext/Jed compatible JSON from parsed data
var result = {},
contexts = parsed.translations;
const contexts = parsed.translations;

Object.keys(contexts).forEach(function (context) {
var translations = parsed.translations[context];
var pluralForms = parsed.headers ? parsed.headers['plural-forms'] : '';
const translations = parsed.translations[context];
const pluralForms = parsed.headers ? parsed.headers['plural-forms'] : '';

Object.keys(translations).forEach(function (key, i) {
var t = translations[key],
const t = translations[key],
translationKey = context.length ? context + '\u0004' + key : key,
fuzzy = t.comments && t.comments.flag && t.comments.flag.match(/fuzzy/) !== null;

Expand Down Expand Up @@ -109,14 +114,14 @@ module.exports = function (buffer, options) {

// Make JSON fully Jed-compatible
if (options.format.indexOf('jed') === 0) {
var jed = {
const jed = {
domain: options.domain,
locale_data: {}
};
if (options.format === 'jed') {
for (var key in result) {
for (const key in result) {
if (result.hasOwnProperty(key) && key !== '') {
for (var i = 2; i < result[key].length; i++) {
for (let i = 2; i < result[key].length; i++) {
if ('' === result[key][i]) {
result[key][i] = result[key][0];
}
Expand Down
198 changes: 198 additions & 0 deletions lib/parse.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
const Jed = require("jed");
const MessageFormat = require("messageformat");
const po2json = require("../index");
const fs = require("fs");
const { promisify } = require("util");
const readFile = promisify(fs.readFile);

describe("parse", () => {

it("parse", async () => {
const po = await readFile(__dirname + "/../test/fixtures/pl.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/pl.json", "utf-8"));
const parsed = po2json.parse(po);
expect(parsed).toEqual(json);
});

it("parse with old Jed format", async () => {
const po = await readFile(__dirname + "/../test/fixtures/pl.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/pl-jedold.json", "utf-8"));
const parsed = po2json.parse(po, {format: 'jedold'});
expect(parsed).toEqual(json);
expect(() => {
new Jed(parsed)
}).not.toThrowError(Error);
});

it("parse with current Jed format", async () => {
const po = await readFile(__dirname + "/../test/fixtures/pl.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/pl-jed.json", "utf-8"));
const parsed = po2json.parse(po, {format: 'jed'});
expect(parsed).toEqual(json);
expect(() => {
new Jed(parsed)
}).not.toThrowError(Error);
});

it("parse with MessageFormatter format", async () => {
const po = await readFile(__dirname + "/../test/fixtures/pl.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/pl-mf.json", "utf-8"));
const parsed = po2json.parse(po, {format: 'mf'});
expect(parsed).toEqual(json);
});

it("parse with MessageFormatter and compile successfully", async () => {
const po = await readFile(__dirname + "/../test/fixtures/pl.po");
const translations = await po2json.parse(po, {format: 'mf'});

const f = (n) => {
return (n === 1 ? 'p0' : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 'p1' : 'p2');
};
f.cardinal = ['p0', 'p1', 'p2'];
const mf = new MessageFormat(
{
'pl': f
}
);
const messages = mf.compile(translations);
expect(messages['A sentence with "quotation" marks.']({})).toEqual("Zdanie w \"cudzysłowie\".");
expect(messages['one product']([1])).toEqual('jeden produkt');
expect(messages['one product']([2])).toEqual('2 produkty');
expect(messages['one product']([12])).toEqual('12 produktów');
expect(messages['one product']([22])).toEqual('22 produkty');
expect(messages['string context']['the contextual phrase']({})).toEqual('zwrot kontekstowe');
});

it("parse with full MessageFormatter format", async () => {
const po = await readFile(__dirname + "/../test/fixtures/pl.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/pl-mf-full.json", "utf-8"));
const parsed = po2json.parse(po, {format: 'mf', fullMF: true});
expect(parsed.headers).toEqual(json.headers);
expect(parsed.translations).toEqual(json.translations);
});

it("parse with full MessageFormatter format and get plural function", async () => {
const po = await readFile(__dirname + "/../test/fixtures/pl.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/pl-mf-full.json", "utf-8"));
const parsed = po2json.parse(po, {format: 'mf', fullMF: true});
expect(parsed.pluralFunction).toBeTruthy();
expect(typeof parsed.pluralFunction).toBe('function');
});

it("parse with full MessageFormatter and compile successfully", async () => {
const po = await readFile(__dirname + "/../test/fixtures/pl.po");
const parsed = await po2json.parse(po, {format: 'mf', fullMF: true});

const locale = {};
locale[parsed.headers.language] = parsed.pluralFunction;
const mf = new MessageFormat(locale);
const messages = mf.compile(parsed.translations);

expect(messages['']['A sentence with "quotation" marks.']({})).toEqual("Zdanie w \"cudzysłowie\".");
expect(messages['']['one product']([1])).toEqual('jeden produkt');
expect(messages['']['one product']([2])).toEqual('2 produkty');
expect(messages['']['one product']([12])).toEqual('12 produktów');
expect(messages['']['one product']([22])).toEqual('22 produkty');
expect(messages['string context']['the contextual phrase']({})).toEqual('zwrot kontekstowe');
});

it("parse with MessageFormatter format + fallback-to-msgid", async () => {
const po = await readFile(__dirname + "/../test/fixtures/en-empty.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/en-mf-fallback-to-msgid.json", "utf-8"));

const parsed = po2json.parse(po, {format: 'mf', 'fallback-to-msgid': true});
expect(parsed).toEqual(json);
});

it("parse with fallback-to-msgid", async () => {
const po = await readFile(__dirname + "/../test/fixtures/en-empty.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/en-empty.json", "utf-8"));
const parsed = po2json.parse(po, {'fallback-to-msgid': true});
expect(parsed).toEqual(json);
});

it("parse with Plural-Forms == nplurals=1; plural=0;", async () => {
const po = await readFile(__dirname + "/../test/fixtures/ja.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/ja.json", "utf-8"));
const parsed = po2json.parse(po);
expect(parsed).toEqual(json);
});

it("parse with Plural-Forms == nplurals=1; plural=0; and with the current Jed format", async () => {
const po = await readFile(__dirname + "/../test/fixtures/ja.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/ja-jed.json", "utf-8"));
const parsed = po2json.parse(po, {format: 'jed'});
expect(parsed).toEqual(json);
});

it("parse with no headers", async () => {
const po = await readFile(__dirname + "/../test/fixtures/en-no-header.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/en-no-header.json", "utf-8"));
const parsed = po2json.parse(po);
expect(parsed).toEqual(json);
});

it("parse with raw JSON context correctly", async () => {
const po = await readFile(__dirname + "/../test/fixtures/es-context.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/es-context.json", "utf-8"));
const parsed = po2json.parse(po, {format: 'raw'});
expect(parsed).toEqual(json);
});

it("parse with jed < 1.1.0 context correctly", async () => {
const po = await readFile(__dirname + "/../test/fixtures/es-context.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/es-context-jedold.json", "utf-8"));
const parsed = po2json.parse(po, {format: 'jedold'});
expect(parsed).toEqual(json);
});

it("parse with jed >= 1.1.0 context correctly", async () => {
const po = await readFile(__dirname + "/../test/fixtures/es-context.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/es-context-jed.json", "utf-8"));
const parsed = po2json.parse(po, {format: 'jed'});
expect(parsed).toEqual(json);
});

it("parse with MessageFormat context correctly", async () => {
const po = await readFile(__dirname + "/../test/fixtures/es-context.po");
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/es-context-mf.json", "utf-8"));
const parsed = po2json.parse(po, {format: 'mf'});
expect(parsed).toEqual(json);
});

it("handle braces in mf with messageformat options", async () => {
this.po = `
msgid "test"
msgstr "Hi %{firstname}"
`;
//this.json = JSON.parse(`{ "test": "Hi %\\\\{firstname\\\\}" }`);
this.json = await JSON.parse(`{ "test": "Hi %{firstname}" }`);

const mfOptions = {
replacements: [
{
pattern: /%(\d+)(?:\$\w)?/g,
replacement: (_, n) => `{${n - 1}}`
},
{
pattern: /%\((\w+)\)\w/g,
replacement: '{$1}'
},
{
pattern: /%\w/g,
replacement: function () {
return `{${this.n++}}`
},
state: {n: 0}
},
{
pattern: /%%/g,
replacement: '%'
}
]
};

const parsed = po2json.parse(this.po, {format: 'mf', mfOptions: mfOptions});
expect(parsed).toEqual(this.json);
});
});
16 changes: 16 additions & 0 deletions lib/parseFile.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const Jed = require("jed");
const MessageFormat = require("messageformat");
const po2json = require("../index");
const fs = require("fs");
const { promisify } = require("util");
const readFile = promisify(fs.readFile);

describe("parseFile", () => {
it("parseFile", async (done) => {
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/pl.json", "utf-8"));
await po2json.parseFile(__dirname + "/../test/fixtures/pl.po", null, function (_, parsed) {
expect(parsed).toEqual(json);
done();
});
});
});
14 changes: 14 additions & 0 deletions lib/parseFileSync.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const Jed = require("jed");
const MessageFormat = require("messageformat");
const po2json = require("../index");
const fs = require("fs");
const { promisify } = require("util");
const readFile = promisify(fs.readFile);

describe("parseFileSync", () => {
it("parseFileSync", async () => {
const json = await JSON.parse(await readFile(__dirname + "/../test/fixtures/pl.json", "utf-8"));
const parsed = po2json.parseFileSync(__dirname + "/../test/fixtures/pl.po", null);
expect(parsed).toEqual(json);
});
});
Loading

0 comments on commit 47b1e91

Please sign in to comment.