'use strict'; var closureI18nExtractor = require('../src/closureI18nExtractor.js'); var converter = require('../src/converter.js'); var findLocaleId = closureI18nExtractor.findLocaleId; var extractNumberSymbols = closureI18nExtractor.extractNumberSymbols; var extractCurrencySymbols = closureI18nExtractor.extractCurrencySymbols; var extractDateTimeSymbols = closureI18nExtractor.extractDateTimeSymbols; var outputLocale = closureI18nExtractor.outputLocale; function newTestLocaleInfo() { return { fr_CA: { DATETIME_FORMATS: { MONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'], STANDALONEMONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'], SHORTMONTH: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'], DAY: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'], SHORTDAY: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'], AMPMS: ['AM', 'PM'], medium: 'yyyy-MM-dd HH:mm:ss', short: 'yy-MM-dd HH:mm', fullDate: 'EEEE d MMMM y', longDate: 'd MMMM y', mediumDate: 'yyyy-MM-dd', shortDate: 'yy-MM-dd', mediumTime: 'HH:mm:ss', shortTime: 'HH:mm' }, NUMBER_FORMATS: { 'DECIMAL_SEP': '.', 'GROUP_SEP': ',', 'PATTERNS': [{ 'minInt': 1, 'minFrac': 0, 'macFrac': 0, 'posPre': '', 'posSuf': '', 'negPre': '-', 'negSuf': '', 'gSize': 3, 'lgSize': 3, 'maxFrac': 3 }, { 'minInt': 1, 'minFrac': 2, 'macFrac': 0, 'posPre': '¤', 'posSuf': '', 'negPre': '¤-', 'negSuf': '', 'gSize': 3, 'lgSize': 3, 'maxFrac': 2 }], 'CURRENCY_SYM': '£' }}}; } describe('findLocaleId', function() { it('should find the id from numbers', function() { expect(findLocaleId('NumberFormatSymbols_en_GB', 'num')).toEqual('en_GB'); }); it('should find the id from datetime', function() { expect(findLocaleId('DateTimeSymbols_en', 'datetime')).toBe('en'); expect(findLocaleId('DateTimeSymbols_en_ISO', 'datetime')).toEqual('en_ISO'); }); it('should not find localeId if data is missing', function() { expect(findLocaleId('', 'num')).toBeUndefined(); expect(findLocaleId('aa', 'datetime')).toBeUndefined(); expect(findLocaleId('NumberFormatSymbols_en', 'datetime')).toBeUndefined(); expect(findLocaleId('DateTimeSymbols_en', 'num')).toBeUndefined(); }); it('should throw an error otherwise', function() { expect(function() { findLocaleId('str', 'otherwise'); }).toThrowError('unknown type in findLocaleId: otherwise'); }); }); describe('extractNumberSymbols', function() { it('should extract number data', function() { var CONTENT = [ 'goog.provide(\'goog.i18n.NumberFormatSymbols_en_GB\');', 'goog.i18n.NumberFormatSymbols_en_GB = {', 'DECIMAL_SEP: \'.\',', 'GROUP_SEP: \',\',', 'PERCENT: \'%\',', 'ZERO_DIGIT: \'0\',', 'PLUS_SIGN: \'+\',', 'MINUS_SIGN: \'-\',', 'EXP_SYMBOL: \'E\',', 'PERMILL: \'\u2030\',', 'INFINITY: \'\u221E\',', 'NAN: \'NaN\',', 'DECIMAL_PATTERN: \'#,##0.###\',', 'SCIENTIFIC_PATTERN: \'#E0\',', 'PERCENT_PATTERN: \'#,##0%\',', 'CURRENCY_PATTERN: \'\u00A4#,##0.00\',', 'DEF_CURRENCY_CODE: \'GBP\' };' ].join('\n'); var currencySymbols = {'GBP':[2, '£', 'GB£']}; var expectedNumberFormats = converter.convertNumberData( { DECIMAL_SEP:'.', GROUP_SEP:',', DECIMAL_PATTERN:'#,##0.###', CURRENCY_PATTERN:'\u00A4#,##0.00', DEF_CURRENCY_CODE: 'GBP' }, currencySymbols ); var localeInfo = {}; extractNumberSymbols(CONTENT, localeInfo, currencySymbols); expect(localeInfo).toEqual({ 'en_GB': { NUMBER_FORMATS: expectedNumberFormats } }); }); }); describe('extractCurrencySymbols', function() { it('should extract currency data', function() { var CONTENT = [ 'goog.i18n.currency.CurrencyInfo = {', ' \'GBP\':[2, \'£\', \'GB£\'],', '};', 'goog.i18n.currency.CurrencyInfoTier2 = {', ' \'AOA\':[2, \'Kz\', \'Kz\'],', '};' ].join('\n'); var currencySymbols = extractCurrencySymbols(CONTENT); expect(currencySymbols.GBP).toEqual([2, '£', 'GB£']); expect(currencySymbols.AOA).toEqual([2, 'Kz', 'Kz']); expect(currencySymbols).toEqual({ 'GBP':[2, '£', 'GB£'], 'AOA':[2, 'Kz', 'Kz'] }); }); }); describe('extractDateTimeSymbols', function() { it('should extract date time data', function() { var CONTENT = [ 'goog.i18n.DateTimeSymbols_fr_CA = {', ' ERAS: [\'av. J.-C.\', \'ap. J.-C.\'],', ' ERANAMES: [\'avant Jésus-Christ\', \'après Jésus-Christ\'],', ' NARROWMONTHS: [\'J\', \'F\', \'M\', \'A\', \'M\', \'J\', \'J\', \'A\', \'S\', \'O\', \'N\', \'D\'],', ' STANDALONENARROWMONTHS: [\'J\', \'F\', \'M\', \'A\', \'M\', \'J\', \'J\', \'A\', \'S\', \'O\',', ' \'N\', \'D\'],', ' MONTHS: [\'janvier\', \'février\', \'mars\', \'avril\', \'mai\', \'juin\', \'juillet\',', ' \'août\', \'septembre\', \'octobre\', \'novembre\', \'décembre\'],', ' STANDALONEMONTHS: [\'janvier\', \'février\', \'mars\', \'avril\', \'mai\', \'juin\',', ' \'juillet\', \'août\', \'septembre\', \'octobre\', \'novembre\', \'décembre\'],', ' SHORTMONTHS: [\'janv.\', \'févr.\', \'mars\', \'avr.\', \'mai\', \'juin\', \'juil.\',', ' \'août\', \'sept.\', \'oct.\', \'nov.\', \'déc.\'],', ' STANDALONESHORTMONTHS: [\'janv.\', \'févr.\', \'mars\', \'avr.\', \'mai\', \'juin\',', ' \'juil.\', \'août\', \'sept.\', \'oct.\', \'nov.\', \'déc.\'],', ' WEEKDAYS: [\'dimanche\', \'lundi\', \'mardi\', \'mercredi\', \'jeudi\', \'vendredi\',', ' \'samedi\'],', ' STANDALONEWEEKDAYS: [\'dimanche\', \'lundi\', \'mardi\', \'mercredi\', \'jeudi\',', ' \'vendredi\', \'samedi\'],', ' SHORTWEEKDAYS: [\'dim.\', \'lun.\', \'mar.\', \'mer.\', \'jeu.\', \'ven.\', \'sam.\'],', ' STANDALONESHORTWEEKDAYS: [\'dim.\', \'lun.\', \'mar.\', \'mer.\', \'jeu.\', \'ven.\',', ' \'sam.\'],', ' NARROWWEEKDAYS: [\'D\', \'L\', \'M\', \'M\', \'J\', \'V\', \'S\'],', ' STANDALONENARROWWEEKDAYS: [\'D\', \'L\', \'M\', \'M\', \'J\', \'V\', \'S\'],', ' SHORTQUARTERS: [\'T1\', \'T2\', \'T3\', \'T4\'],', ' QUARTERS: [\'1er trimestre\', \'2e trimestre\', \'3e trimestre\', \'4e trimestre\'],', ' AMPMS: [\'AM\', \'PM\'],', ' DATEFORMATS: [\'EEEE d MMMM y\', \'d MMMM y\', \'yyyy-MM-dd\', \'yy-MM-dd\'],', ' TIMEFORMATS: [\'HH \\\'h\\\' mm \\\'min\\\' ss \\\'s\\\' zzzz\', \'HH:mm:ss z\',', ' \'HH:mm:ss\', \'HH:mm\'],', ' FIRSTDAYOFWEEK: 6,', ' WEEKENDRANGE: [5, 6],', ' FIRSTWEEKCUTOFFDAY: 2', '};' ].join('\n'); var localeInfo = {}; var expectedLocaleInfo = { fr_CA: { DATETIME_FORMATS: { MONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'], STANDALONEMONTH: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'], SHORTMONTH: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.'], DAY: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'], SHORTDAY: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'], FIRSTDAYOFWEEK: 6, WEEKENDRANGE: [5, 6], AMPMS: ['AM', 'PM'], ERAS: ['av. J.-C.', 'ap. J.-C.'], ERANAMES: ['avant Jésus-Christ', 'après Jésus-Christ'], medium: 'yyyy-MM-dd HH:mm:ss', short: 'yy-MM-dd HH:mm', fullDate: 'EEEE d MMMM y', longDate: 'd MMMM y', mediumDate: 'yyyy-MM-dd', shortDate: 'yy-MM-dd', mediumTime: 'HH:mm:ss', shortTime: 'HH:mm' } } }; extractDateTimeSymbols(CONTENT, localeInfo); expect(localeInfo).toEqual(expectedLocaleInfo); }); }); describe('pluralExtractor', function() { it('should output PLURAL_CAT in the output string code', function() { var content = ( 'goog.provide(\'goog.i18n.pluralRules\');\n' + '\n' + 'goog.i18n.pluralRules.Keyword = {\n' + ' ZERO: \'zero\',\n' + ' ONE: \'one\',\n' + ' TWO: \'two\',\n' + ' FEW: \'few\',\n' + ' MANY: \'many\',\n' + ' OTHER: \'other\'\n' + '};\n' + '\n' + 'goog.i18n.pluralRules.frSelect_ = function(n) {\n' + ' if (n >= 0 && n < 2) {\n' + ' return goog.i18n.pluralRules.Keyword.ONE;\n' + ' }\n' + ' return goog.i18n.pluralRules.Keyword.OTHER;\n' + '};\n' + '\n' + 'if (goog.LOCALE == \'fr\') {\n' + ' goog.i18n.pluralRules.select = goog.i18n.pluralRules.frSelect_;\n' + '}' ); var localeInfo = newTestLocaleInfo(); closureI18nExtractor.pluralExtractor(content, localeInfo); var pluralCat = localeInfo['fr_CA'].pluralCat; expect(pluralCat).toBeDefined(); // pluralCat is the source text for the pluralCat and contains @@ // placeholders that need to be stripped before evaluation. // Ref: closureI18nExtractor.pluralExtractor. pluralCat = pluralCat.replace(/^@@|@@$/g, ''); // pluralCat requires these constants to exist. // eslint-disable-next-line no-unused-vars var PLURAL_CATEGORY = { ZERO: 'zero', ONE: 'one', TWO: 'two', FEW: 'few', MANY: 'many', OTHER: 'other' }; // Obtain the function by evaluating the source text. // eslint-disable-next-line no-eval pluralCat = eval('(' + pluralCat + ')'); // Confirm some expectations for pluralCat in fr_CA. expect(pluralCat(0)).toEqual('one'); expect(pluralCat(3)).toEqual('other'); }); }); describe('serializeContent', function() { it('should not make any modifications to the content of the locale', function() { var serializedContent = closureI18nExtractor.serializeContent(newTestLocaleInfo()); // eslint-disable-next-line no-eval expect(eval('(' + serializedContent + ')')).toEqual(newTestLocaleInfo()); }); it('should only have ascii characters', function() { var serializedContent = closureI18nExtractor.serializeContent(newTestLocaleInfo()); expect((/[^\u0001-\u007f]/).test(serializedContent)).toBe(false); }); it('should not transform arrays into objects', function() { var serializedContent = closureI18nExtractor.serializeContent(newTestLocaleInfo().fr_CA); // eslint-disable-next-line no-eval var deserializedLocale = eval('(' + serializedContent + ')'); expect(deserializedLocale.DATETIME_FORMATS.MONTH.length).not.toBeUndefined(); }); }); describe('outputLocale', function() { it('should render the correct locale ids', function() { var output = outputLocale(newTestLocaleInfo(), 'fr_CA'); expect(output).toContain('"id": "fr-ca"'); expect(output).toContain('"localeID": "fr_CA"'); }); });