<commit_before>import fs from 'fs';
import path from 'path';
import { test } from 'tap';
import { Parser } from '../src';

const defaults = {};

test('Skip undefined namespace', (t) => {
    const parser = new Parser({
        ns: ['translation']
    });
    const content = `
        i18next.t('none:key2');
        i18next.t('key1');
    `;
    const wanted = {
        en: {
            translation: {
                key1: ''
            }
        }
    };

    parser.parseFuncFromString(content);
    t.same(parser.get(), wanted);
    t.end();
});

test('Parse translation function', (t) => {
    const parser = new Parser({
        lngs: ['en'],
        fallbackLng: 'en'
    });
    const customHandler = function(key) {
        const defaultValue = '__TRANSLATION__'; // optional default value
        parser.set(key, defaultValue);
    };

    // i18next.t('key');
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/app.js'), 'utf-8');
    parser
        .parseFuncFromString(content, customHandler) // pass a custom handler
        .parseFuncFromString(content, { list: ['i18next.t']}) // override `func.list`
        .parseFuncFromString(content, { list: ['i18next.t']}, customHandler)
        .parseFuncFromString(content); // using default options and handler

    t.same(parser.get(), {
        en: {
            translation: {
                "key2": "__TRANSLATION__",
                "key1": "__TRANSLATION__"
          }
        }
    });

    // Sort keys in alphabetical order
    t.same(JSON.stringify(parser.get({ sort: true })), JSON.stringify({
        en: {
            translation: {
                "key1": "__TRANSLATION__",
                "key2": "__TRANSLATION__"
          }
        }
    }));

    t.equal(parser.get('key1', { lng: 'en' }), '__TRANSLATION__');
    t.equal(parser.get('key1', { lng: 'de' }), undefined);
    t.equal(parser.get('nokey', { lng: 'en' }), undefined);

    t.end();
});

test('Parse HTML attribute', (t) => {
    const parser = new Parser({
        lngs: ['en'],
        fallbackLng: 'en'
    });
    const customHandler = function(key) {
        const defaultValue = '__TRANSLATION__'; // optional default value
        parser.set(key, defaultValue);
    };

    // <div data-i18n="key"></div>
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/app.html'), 'utf-8');
    parser
        .parseAttrFromString(content, customHandler) // pass a custom handler
        .parseAttrFromString(content, { list: ['data-i18n']}) // override `func.list`
        .parseAttrFromString(content, { list: ['data-i18n']}, customHandler)
        .parseAttrFromString(content); // using default options and handler

    t.same(parser.get(), {
        en: {
            translation: {
                "key4": "__TRANSLATION__",
                "key3": "__TRANSLATION__",
                "key2": "__TRANSLATION__",
                "key1": "__TRANSLATION__"
            }
        }
    });

    // Sort keys in alphabetical order
    t.same(JSON.stringify(parser.get({ sort: true })), JSON.stringify({
        en: {
            translation: {
                "key1": "__TRANSLATION__",
                "key2": "__TRANSLATION__",
                "key3": "__TRANSLATION__",
                "key4": "__TRANSLATION__"
          }
        }
    }));

    t.equal(parser.get('key1', { lng: 'en' }), '__TRANSLATION__');
    t.equal(parser.get('key1', { lng: 'de' }), undefined);
    t.equal(parser.get('nokey', { lng: 'en' }), undefined);

    t.end();
});

test('Gettext style i18n', (t) => {
    const parser = new Parser({
        defaultValue: (lng, ns, key) => {
            return key;
        },
        keySeparator: false,
        nsSeparator: false
    });

    // Parse Translation Function
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/modules/index.js'), 'utf8');

    parser.parseFuncFromString(content, { list: ['_t'] });

    const resStore = parser.get();
    t.same(resStore, {
        en: {
            translation: {
                "Loading...": "Loading...",
                "This value does not exist.": "This value does not exist.",
                "YouTube has more than {{count}} billion users.": "YouTube has more than {{count}} billion users.",
                "YouTube has more than {{count}} billion users._plural": "YouTube has more than {{count}} billion users.",
                "You have {{count}} messages.": "You have {{count}} messages.",
                "You have {{count}} messages._plural": "You have {{count}} messages."
          }
        }
    });
    t.end();
});

test('Replace double backslash with single backslash', (t) => {
    const parser = new Parser({
        defaultValue: function(lng, ns, key) {
            if (lng === 'en') {
                return key;
            }
            return '__NOT_TRANSLATED__';
        },
        keySeparator: false,
        nsSeparator: false
    });
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/escape.js'), 'utf8');
    const wanted = {
        "en": {
            "translation": {
                "Primary 'email' activation": "Primary 'email' activation",
                "Primary \"email\" activation": "Primary \"email\" activation",
                "name='email' value='{{email}}'": "name='email' value='{{email}}'",
                "name=\"email\" value=\"{{email}}\"": "name=\"email\" value=\"{{email}}\"",
                "name=\"email\" value='{{email}}'": "name=\"email\" value='{{email}}'",
                "name='email' value=\"{{email}}\"": "name='email' value=\"{{email}}\"",
            }
        }
    };

    parser.parseFuncFromString(content);
    t.same(parser.get(), wanted);
    fs.writeFileSync('./tmp.json', JSON.stringify(parser.get(), null, 4), 'utf8');
    t.end();
});

test('Disable nsSeparator', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: false,
        keySeparator: '.'
    });
    parser.set('foo:bar');

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'foo:bar': '__NOT_TRANSLATED__'
            }
        }
    }, 'The key should not use default nsSeparator : to split');
    t.end();
});

test('Disable keySeparator', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: ':',
        keySeparator: false
    });
    parser.set('Creating...');

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'Creating...': '__NOT_TRANSLATED__'
            }
        }
    }, 'The key should not use default keySeparator . to split');
    t.end();
});

test('Default nsSeparator', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: ':',
        keySeparator: '.'
    });
    parser.set('translation:key1.key2');

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'key1': {
                    'key2': '__NOT_TRANSLATED__'
                }
            }
        }
    }, 'The key should use default nsSeparator : to split');
    t.end();
});

test('Default keySeparator', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: ':',
        keySeparator: '.'
    });
    parser.set('key1.key2');

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'key1': {
                    'key2': '__NOT_TRANSLATED__'
                }
            }
        }
    }, 'The key should use default keySeparator . to split');
    t.end();
});

test('Override nsSeparator with a false value', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: ':',
        keySeparator: '.'
    });
    parser.set('translation:key1.key2', {
        nsSeparator: false
    });

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'translation:key1': {
                    'key2': '__NOT_TRANSLATED__'
                }
            }
        }
    }, 'Override nsSeparator with a false value');
    t.end();
});

test('Override keySeparator with a false value', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: ':',
        keySeparator: '.'
    });
    parser.set('translation:key1.key2', {
        keySeparator: false
    });

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'key1.key2': '__NOT_TRANSLATED__'
            }
        }
    }, 'Override keySeparator with a false value');
    t.end();
});

test('Plural', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/plural.js'), 'utf-8');
    parser.parseFuncFromString(content);
    t.same(parser.get(), {
        en: {
            translation: {
                "key": "",
                "key_plural": "",
                "keyWithCount": "",
                "keyWithCount_plural": "",
                "keyWithVariable": "",
                "keyWithVariable_plural": ""
            }
        }
    });
    t.end();
});

test('Context', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/context.js'), 'utf-8');
    parser.parseFuncFromString(content);
    t.same(parser.get(), {
        en: {
            translation: {
                "friend": "",
                "friend_male": "",
                "friend_female": ""
            }
        }
    });
    t.end();
});

test('Context with plural combined', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/context-plural.js'), 'utf-8');
    parser.parseFuncFromString(content);
    t.same(parser.get(), {
        en: {
            translation: {
                "friend": "",
                "friend_plural": "",
                "friend_male": "",
                "friend_male_plural": "",
                "friend_female": "",
                "friend_female_plural": ""
            }
        }
    });
    t.end();
});

test('parser.toJSON()', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/app.js'), 'utf-8');

    parser.parseFuncFromString(content);

    t.same(parser.toJSON(), '{"en":{"translation":{"key2":"","key1":""}}}');
    t.end();
});

test('parser.toJSON({ sort: true })', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/app.js'), 'utf-8');

    parser.parseFuncFromString(content);

    t.same(parser.toJSON({ sort: true }), '{"en":{"translation":{"key1":"","key2":""}}}');
    t.end();
});

test('parser.toJSON({ sort: true, space: 2 })', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/app.js'), 'utf-8');
    const wanted = JSON.stringify({
        en: {
            translation: {
                key1: '',
                key2: ''
            }
        }
    }, null, 2);

    parser.parseFuncFromString(content);
    t.same(parser.toJSON({ sort: true, space: 2 }), wanted);
    t.end();
});
<commit_msg>Remove tmp files<commit_after>import fs from 'fs';
import path from 'path';
import { test } from 'tap';
import { Parser } from '../src';

const defaults = {};

test('Skip undefined namespace', (t) => {
    const parser = new Parser({
        ns: ['translation']
    });
    const content = `
        i18next.t('none:key2');
        i18next.t('key1');
    `;
    const wanted = {
        en: {
            translation: {
                key1: ''
            }
        }
    };

    parser.parseFuncFromString(content);
    t.same(parser.get(), wanted);
    t.end();
});

test('Parse translation function', (t) => {
    const parser = new Parser({
        lngs: ['en'],
        fallbackLng: 'en'
    });
    const customHandler = function(key) {
        const defaultValue = '__TRANSLATION__'; // optional default value
        parser.set(key, defaultValue);
    };

    // i18next.t('key');
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/app.js'), 'utf-8');
    parser
        .parseFuncFromString(content, customHandler) // pass a custom handler
        .parseFuncFromString(content, { list: ['i18next.t']}) // override `func.list`
        .parseFuncFromString(content, { list: ['i18next.t']}, customHandler)
        .parseFuncFromString(content); // using default options and handler

    t.same(parser.get(), {
        en: {
            translation: {
                "key2": "__TRANSLATION__",
                "key1": "__TRANSLATION__"
          }
        }
    });

    // Sort keys in alphabetical order
    t.same(JSON.stringify(parser.get({ sort: true })), JSON.stringify({
        en: {
            translation: {
                "key1": "__TRANSLATION__",
                "key2": "__TRANSLATION__"
          }
        }
    }));

    t.equal(parser.get('key1', { lng: 'en' }), '__TRANSLATION__');
    t.equal(parser.get('key1', { lng: 'de' }), undefined);
    t.equal(parser.get('nokey', { lng: 'en' }), undefined);

    t.end();
});

test('Parse HTML attribute', (t) => {
    const parser = new Parser({
        lngs: ['en'],
        fallbackLng: 'en'
    });
    const customHandler = function(key) {
        const defaultValue = '__TRANSLATION__'; // optional default value
        parser.set(key, defaultValue);
    };

    // <div data-i18n="key"></div>
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/app.html'), 'utf-8');
    parser
        .parseAttrFromString(content, customHandler) // pass a custom handler
        .parseAttrFromString(content, { list: ['data-i18n']}) // override `func.list`
        .parseAttrFromString(content, { list: ['data-i18n']}, customHandler)
        .parseAttrFromString(content); // using default options and handler

    t.same(parser.get(), {
        en: {
            translation: {
                "key4": "__TRANSLATION__",
                "key3": "__TRANSLATION__",
                "key2": "__TRANSLATION__",
                "key1": "__TRANSLATION__"
            }
        }
    });

    // Sort keys in alphabetical order
    t.same(JSON.stringify(parser.get({ sort: true })), JSON.stringify({
        en: {
            translation: {
                "key1": "__TRANSLATION__",
                "key2": "__TRANSLATION__",
                "key3": "__TRANSLATION__",
                "key4": "__TRANSLATION__"
          }
        }
    }));

    t.equal(parser.get('key1', { lng: 'en' }), '__TRANSLATION__');
    t.equal(parser.get('key1', { lng: 'de' }), undefined);
    t.equal(parser.get('nokey', { lng: 'en' }), undefined);

    t.end();
});

test('Gettext style i18n', (t) => {
    const parser = new Parser({
        defaultValue: (lng, ns, key) => {
            return key;
        },
        keySeparator: false,
        nsSeparator: false
    });

    // Parse Translation Function
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/modules/index.js'), 'utf8');

    parser.parseFuncFromString(content, { list: ['_t'] });

    const resStore = parser.get();
    t.same(resStore, {
        en: {
            translation: {
                "Loading...": "Loading...",
                "This value does not exist.": "This value does not exist.",
                "YouTube has more than {{count}} billion users.": "YouTube has more than {{count}} billion users.",
                "YouTube has more than {{count}} billion users._plural": "YouTube has more than {{count}} billion users.",
                "You have {{count}} messages.": "You have {{count}} messages.",
                "You have {{count}} messages._plural": "You have {{count}} messages."
          }
        }
    });
    t.end();
});

test('Replace double backslash with single backslash', (t) => {
    const parser = new Parser({
        defaultValue: function(lng, ns, key) {
            if (lng === 'en') {
                return key;
            }
            return '__NOT_TRANSLATED__';
        },
        keySeparator: false,
        nsSeparator: false
    });
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/escape.js'), 'utf8');
    const wanted = {
        "en": {
            "translation": {
                "Primary 'email' activation": "Primary 'email' activation",
                "Primary \"email\" activation": "Primary \"email\" activation",
                "name='email' value='{{email}}'": "name='email' value='{{email}}'",
                "name=\"email\" value=\"{{email}}\"": "name=\"email\" value=\"{{email}}\"",
                "name=\"email\" value='{{email}}'": "name=\"email\" value='{{email}}'",
                "name='email' value=\"{{email}}\"": "name='email' value=\"{{email}}\"",
            }
        }
    };

    parser.parseFuncFromString(content);
    t.same(parser.get(), wanted);
    t.end();
});

test('Disable nsSeparator', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: false,
        keySeparator: '.'
    });
    parser.set('foo:bar');

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'foo:bar': '__NOT_TRANSLATED__'
            }
        }
    }, 'The key should not use default nsSeparator : to split');
    t.end();
});

test('Disable keySeparator', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: ':',
        keySeparator: false
    });
    parser.set('Creating...');

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'Creating...': '__NOT_TRANSLATED__'
            }
        }
    }, 'The key should not use default keySeparator . to split');
    t.end();
});

test('Default nsSeparator', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: ':',
        keySeparator: '.'
    });
    parser.set('translation:key1.key2');

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'key1': {
                    'key2': '__NOT_TRANSLATED__'
                }
            }
        }
    }, 'The key should use default nsSeparator : to split');
    t.end();
});

test('Default keySeparator', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: ':',
        keySeparator: '.'
    });
    parser.set('key1.key2');

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'key1': {
                    'key2': '__NOT_TRANSLATED__'
                }
            }
        }
    }, 'The key should use default keySeparator . to split');
    t.end();
});

test('Override nsSeparator with a false value', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: ':',
        keySeparator: '.'
    });
    parser.set('translation:key1.key2', {
        nsSeparator: false
    });

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'translation:key1': {
                    'key2': '__NOT_TRANSLATED__'
                }
            }
        }
    }, 'Override nsSeparator with a false value');
    t.end();
});

test('Override keySeparator with a false value', (t) => {
    const parser = new Parser({
        defaultValue: '__NOT_TRANSLATED__',
        nsSeparator: ':',
        keySeparator: '.'
    });
    parser.set('translation:key1.key2', {
        keySeparator: false
    });

    const resStore = parser.get();

    t.same(resStore, {
        en: {
            translation: {
                'key1.key2': '__NOT_TRANSLATED__'
            }
        }
    }, 'Override keySeparator with a false value');
    t.end();
});

test('Plural', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/plural.js'), 'utf-8');
    parser.parseFuncFromString(content);
    t.same(parser.get(), {
        en: {
            translation: {
                "key": "",
                "key_plural": "",
                "keyWithCount": "",
                "keyWithCount_plural": "",
                "keyWithVariable": "",
                "keyWithVariable_plural": ""
            }
        }
    });
    t.end();
});

test('Context', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/context.js'), 'utf-8');
    parser.parseFuncFromString(content);
    t.same(parser.get(), {
        en: {
            translation: {
                "friend": "",
                "friend_male": "",
                "friend_female": ""
            }
        }
    });
    t.end();
});

test('Context with plural combined', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/context-plural.js'), 'utf-8');
    parser.parseFuncFromString(content);
    t.same(parser.get(), {
        en: {
            translation: {
                "friend": "",
                "friend_plural": "",
                "friend_male": "",
                "friend_male_plural": "",
                "friend_female": "",
                "friend_female_plural": ""
            }
        }
    });
    t.end();
});

test('parser.toJSON()', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/app.js'), 'utf-8');

    parser.parseFuncFromString(content);

    t.same(parser.toJSON(), '{"en":{"translation":{"key2":"","key1":""}}}');
    t.end();
});

test('parser.toJSON({ sort: true })', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/app.js'), 'utf-8');

    parser.parseFuncFromString(content);

    t.same(parser.toJSON({ sort: true }), '{"en":{"translation":{"key1":"","key2":""}}}');
    t.end();
});

test('parser.toJSON({ sort: true, space: 2 })', (t) => {
    const parser = new Parser();
    const content = fs.readFileSync(path.resolve(__dirname, 'fixtures/app.js'), 'utf-8');
    const wanted = JSON.stringify({
        en: {
            translation: {
                key1: '',
                key2: ''
            }
        }
    }, null, 2);

    parser.parseFuncFromString(content);
    t.same(parser.toJSON({ sort: true, space: 2 }), wanted);
    t.end();
});

{'fraction_non_alphanumeric': 0.16976581001666521, 'fraction_numerical': 0.00640294710990264, 'mean_word_length': 1.9668227946916472, 'pattern_counts': {'":': 98, '<': 7, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '295723', 'n_tokens_mistral': 7002, 'n_tokens_neox': 6828, 'n_words': 1411}