diff --git a/fluent-dom/README.md b/fluent-dom/README.md index 997fc35f5..fbfdc4086 100644 --- a/fluent-dom/README.md +++ b/fluent-dom/README.md @@ -16,7 +16,7 @@ can install it from the npm registry or use it as a standalone script (as the The `DOMLocalization` constructor provides the core functionality of full-fallback ready message formatting. It uses a lazy-resolved -`MessageContext` objects from the `fluent` package to format messages. +`FluentBundle` objects from the `fluent` package to format messages. On top of that, `DOMLocalization` can localize any DOMFragment by identifying localizable elements with `data-l10n-id` and translating them. @@ -27,7 +27,7 @@ import { DOMLocalization } from 'fluent-dom' const l10n = new DOMLocalization(MutationObserver, [ '/browser/main.ftl', '/toolkit/menu.ftl' -], generateMessages); +], generateBundles); l10n.connectRoot(document.documentElement); @@ -47,15 +47,15 @@ class that provides just the API needed to format messages in the running code. ```javascript import { Localization } from 'fluent-dom' -function *generateMessages() { - // Some lazy logic for yielding MessageContexts. - yield *[ctx1, ctx2]; +function *generateBundles() { + // Some lazy logic for yielding FluentBundles. + yield *[bundle1, bundle2]; } const l10n = new Localization(document, [ '/browser/main.ftl', '/toolkit/menu.ftl' -], generateMessages); +], generateBundles); async function main() { const msg = await l10n.formatValue('welcome', { name: 'Anna' }); diff --git a/fluent-dom/src/dom_localization.js b/fluent-dom/src/dom_localization.js index bfcd31545..f85864f18 100644 --- a/fluent-dom/src/dom_localization.js +++ b/fluent-dom/src/dom_localization.js @@ -16,13 +16,13 @@ const L10N_ELEMENT_QUERY = `[${L10NID_ATTR_NAME}]`; */ export default class DOMLocalization extends Localization { /** - * @param {Array} resourceIds - List of resource IDs - * @param {Function} generateMessages - Function that returns a - * generator over MessageContexts + * @param {Array} resourceIds - List of resource IDs + * @param {Function} generateBundles - Function that returns a + * generator over FluentBundles * @returns {DOMLocalization} */ - constructor(resourceIds, generateMessages) { - super(resourceIds, generateMessages); + constructor(resourceIds, generateBundles) { + super(resourceIds, generateBundles); // A Set of DOM trees observed by the `MutationObserver`. this.roots = new Set(); diff --git a/fluent-dom/src/localization.js b/fluent-dom/src/localization.js index 3dd882eea..dfc4d594f 100644 --- a/fluent-dom/src/localization.js +++ b/fluent-dom/src/localization.js @@ -6,22 +6,22 @@ import { CachedAsyncIterable } from "cached-iterable"; /** * The `Localization` class is a central high-level API for vanilla * JavaScript use of Fluent. - * It combines language negotiation, MessageContext and I/O to + * It combines language negotiation, FluentBundle and I/O to * provide a scriptable API to format translations. */ export default class Localization { /** - * @param {Array} resourceIds - List of resource IDs - * @param {Function} generateMessages - Function that returns a - * generator over MessageContexts + * @param {Array} resourceIds - List of resource IDs + * @param {Function} generateBundles - Function that returns a + * generator over FluentBundles * * @returns {Localization} */ - constructor(resourceIds = [], generateMessages) { + constructor(resourceIds = [], generateBundles) { this.resourceIds = resourceIds; - this.generateMessages = generateMessages; - this.ctxs = CachedAsyncIterable.from( - this.generateMessages(this.resourceIds)); + this.generateBundles = generateBundles; + this.bundles = CachedAsyncIterable.from( + this.generateBundles(this.resourceIds)); } addResourceIds(resourceIds) { @@ -39,7 +39,7 @@ export default class Localization { /** * Format translations and handle fallback if needed. * - * Format translations for `keys` from `MessageContext` instances on this + * Format translations for `keys` from `FluentBundle` instances on this * DOMLocalization. In case of errors, fetch the next context in the * fallback chain. * @@ -51,15 +51,15 @@ export default class Localization { async formatWithFallback(keys, method) { const translations = []; - for await (const ctx of this.ctxs) { - const missingIds = keysFromContext(method, ctx, keys, translations); + for await (const bundle of this.bundles) { + const missingIds = keysFromBundle(method, bundle, keys, translations); if (missingIds.size === 0) { break; } if (typeof console !== "undefined") { - const locale = ctx.locales[0]; + const locale = bundle.locales[0]; const ids = Array.from(missingIds).join(", "); console.warn(`Missing translations in ${locale}: ${ids}`); } @@ -92,7 +92,7 @@ export default class Localization { * @private */ formatMessages(keys) { - return this.formatWithFallback(keys, messageFromContext); + return this.formatWithFallback(keys, messageFromBundle); } /** @@ -115,7 +115,7 @@ export default class Localization { * @returns {Promise>} */ formatValues(keys) { - return this.formatWithFallback(keys, valueFromContext); + return this.formatWithFallback(keys, valueFromBundle); } /** @@ -154,40 +154,40 @@ export default class Localization { * that language negotiation or available resources changed. */ onChange() { - this.ctxs = CachedAsyncIterable.from( - this.generateMessages(this.resourceIds)); - this.ctxs.touchNext(2); + this.bundles = CachedAsyncIterable.from( + this.generateBundles(this.resourceIds)); + this.bundles.touchNext(2); } } /** * Format the value of a message into a string. * - * This function is passed as a method to `keysFromContext` and resolve - * a value of a single L10n Entity using provided `MessageContext`. + * This function is passed as a method to `keysFromBundle` and resolve + * a value of a single L10n Entity using provided `FluentBundle`. * * If the function fails to retrieve the entity, it will return an ID of it. * If formatting fails, it will return a partially resolved entity. * * In both cases, an error is being added to the errors array. * - * @param {MessageContext} ctx + * @param {FluentBundle} bundle * @param {Array} errors * @param {string} id * @param {Object} args * @returns {string} * @private */ -function valueFromContext(ctx, errors, id, args) { - const msg = ctx.getMessage(id); - return ctx.format(msg, args, errors); +function valueFromBundle(bundle, errors, id, args) { + const msg = bundle.getMessage(id); + return bundle.format(msg, args, errors); } /** * Format all public values of a message into a {value, attributes} object. * - * This function is passed as a method to `keysFromContext` and resolve - * a single L10n Entity using provided `MessageContext`. + * This function is passed as a method to `keysFromBundle` and resolve + * a single L10n Entity using provided `FluentBundle`. * * The function will return an object with a value and attributes of the * entity. @@ -198,25 +198,25 @@ function valueFromContext(ctx, errors, id, args) { * * In both cases, an error is being added to the errors array. * - * @param {MessageContext} ctx + * @param {FluentBundle} bundle * @param {Array} errors * @param {String} id * @param {Object} args * @returns {Object} * @private */ -function messageFromContext(ctx, errors, id, args) { - const msg = ctx.getMessage(id); +function messageFromBundle(bundle, errors, id, args) { + const msg = bundle.getMessage(id); const formatted = { - value: ctx.format(msg, args, errors), + value: bundle.format(msg, args, errors), attributes: null, }; if (msg.attrs) { formatted.attributes = []; for (const [name, attr] of Object.entries(msg.attrs)) { - const value = ctx.format(attr, args, errors); + const value = bundle.format(attr, args, errors); if (value !== null) { formatted.attributes.push({name, value}); } @@ -229,12 +229,12 @@ function messageFromContext(ctx, errors, id, args) { /** * This function is an inner function for `Localization.formatWithFallback`. * - * It takes a `MessageContext`, list of l10n-ids and a method to be used for - * key resolution (either `valueFromContext` or `messageFromContext`) and - * optionally a value returned from `keysFromContext` executed against - * another `MessageContext`. + * It takes a `FluentBundle`, list of l10n-ids and a method to be used for + * key resolution (either `valueFromBundle` or `messageFromBundle`) and + * optionally a value returned from `keysFromBundle` executed against + * another `FluentBundle`. * - * The idea here is that if the previous `MessageContext` did not resolve + * The idea here is that if the previous `FluentBundle` did not resolve * all keys, we're calling this function with the next context to resolve * the remaining ones. * @@ -243,7 +243,7 @@ function messageFromContext(ctx, errors, id, args) { * * If it doesn't, it means that we have a good translation for this key and * we return it. If it does, we'll try to resolve the key using the passed - * `MessageContext`. + * `FluentBundle`. * * In the end, we fill the translations array, and return the Set with * missing ids. @@ -251,14 +251,14 @@ function messageFromContext(ctx, errors, id, args) { * See `Localization.formatWithFallback` for more info on how this is used. * * @param {Function} method - * @param {MessageContext} ctx + * @param {FluentBundle} bundle * @param {Array} keys * @param {{Array<{value: string, attributes: Object}>}} translations * * @returns {Set} * @private */ -function keysFromContext(method, ctx, keys, translations) { +function keysFromBundle(method, bundle, keys, translations) { const messageErrors = []; const missingIds = new Set(); @@ -267,9 +267,9 @@ function keysFromContext(method, ctx, keys, translations) { return; } - if (ctx.hasMessage(id)) { + if (bundle.hasMessage(id)) { messageErrors.length = 0; - translations[i] = method(ctx, messageErrors, id, args); + translations[i] = method(bundle, messageErrors, id, args); // XXX: Report resolver errors } else { missingIds.add(id); diff --git a/fluent-dom/src/overlay.js b/fluent-dom/src/overlay.js index 945db92c8..957d60ba9 100644 --- a/fluent-dom/src/overlay.js +++ b/fluent-dom/src/overlay.js @@ -152,7 +152,7 @@ function overlayAttributes(fromElement, toElement) { } // fromElement might be a {value, attributes} object as returned by - // Localization.messageFromContext. In which case attributes may be null to + // Localization.messageFromBundle. In which case attributes may be null to // save GC cycles. if (!fromElement.attributes) { return; diff --git a/fluent-dom/test/dom_localization_test.js b/fluent-dom/test/dom_localization_test.js index 29898b3d7..d3268b7b2 100644 --- a/fluent-dom/test/dom_localization_test.js +++ b/fluent-dom/test/dom_localization_test.js @@ -1,11 +1,11 @@ import assert from "assert"; -import { MessageContext } from "../../fluent/src/index"; +import { FluentBundle } from "../../fluent/src/index"; import DOMLocalization from "../src/dom_localization"; async function* mockGenerateMessages(resourceIds) { - const mc = new MessageContext(["en-US"]); - mc.addMessages("key1 = Key 1"); - yield mc; + const bundle = new FluentBundle(["en-US"]); + bundle.addMessages("key1 = Key 1"); + yield bundle; } suite("translateFragment", function() { diff --git a/fluent-dom/test/localization_test.js b/fluent-dom/test/localization_test.js index 278023b10..f02275a4e 100644 --- a/fluent-dom/test/localization_test.js +++ b/fluent-dom/test/localization_test.js @@ -1,11 +1,11 @@ import assert from "assert"; -import { MessageContext } from "../../fluent/src/index"; +import { FluentBundle } from "../../fluent/src/index"; import Localization from "../src/localization"; async function* mockGenerateMessages(resourceIds) { - const mc = new MessageContext(["en-US"]); - mc.addMessages("key1 = Key 1"); - yield mc; + const bundle = new FluentBundle(["en-US"]); + bundle.addMessages("key1 = Key 1"); + yield bundle; } suite("formatMessages", function() { diff --git a/fluent-gecko/README.md b/fluent-gecko/README.md index c058eeea4..32f68598a 100644 --- a/fluent-gecko/README.md +++ b/fluent-gecko/README.md @@ -10,7 +10,7 @@ natural language. The `fluent-gecko` build system produces `*.jsm` files which are ready to be used as Gecko modules. -`Fluent.jsm` exports the `MessageContext` constructor which provides the +`Fluent.jsm` exports the `FluentBundle` constructor which provides the core functionality of formatting translations from FTL files. See the [README][] of the main `fluent` package for more information. diff --git a/fluent-gecko/makefile b/fluent-gecko/makefile index e96860244..d3ffa8476 100644 --- a/fluent-gecko/makefile +++ b/fluent-gecko/makefile @@ -2,9 +2,9 @@ PACKAGE := fluent-gecko include ../common.mk -build: MessageContext.jsm Localization.jsm DOMLocalization.jsm l10n.js +build: Fluent.jsm Localization.jsm DOMLocalization.jsm l10n.js -MessageContext.jsm: $(SOURCES) +Fluent.jsm: $(SOURCES) @rollup $(CURDIR)/src/message_context.js \ --config ./xpcom_config.js \ --output.file ./dist/$@ @@ -29,7 +29,7 @@ l10n.js: $(SOURCES) @echo -e " $(OK) $@ built" clean: - @rm -f ./dist/MessageContext.jsm + @rm -f ./dist/FluentBundle.jsm @rm -f ./dist/Localization.jsm @rm -f ./dist/DOMLocalization.jsm @rm -f ./dist/l10n.js diff --git a/fluent-gecko/src/dom_localization.js b/fluent-gecko/src/dom_localization.js index f7213bba6..d1c59ad23 100644 --- a/fluent-gecko/src/dom_localization.js +++ b/fluent-gecko/src/dom_localization.js @@ -4,13 +4,13 @@ import DOMLocalization from "../../fluent-dom/src/dom_localization"; /** * The default localization strategy for Gecko. It comabines locales * available in L10nRegistry, with locales requested by the user to - * generate the iterator over MessageContexts. + * generate the iterator over FluentBundles. * * In the future, we may want to allow certain modules to override this * with a different negotitation strategy to allow for the module to * be localized into a different language - for example DevTools. */ -function defaultGenerateMessages(resourceIds) { +function defaultGenerateBundles(resourceIds) { const requestedLocales = Services.locale.getRequestedLocales(); const availableLocales = L10nRegistry.getAvailableLocales(); const defaultLocale = Services.locale.defaultLocale; @@ -25,9 +25,9 @@ class GeckoDOMLocalization extends DOMLocalization { constructor( windowElement, resourceIds, - generateMessages = defaultGenerateMessages + generateBundles = defaultGenerateBundles ) { - super(windowElement, resourceIds, generateMessages); + super(windowElement, resourceIds, generateBundles); } } diff --git a/fluent-gecko/src/l10n.js b/fluent-gecko/src/l10n.js index d8ceffff8..edab81c84 100644 --- a/fluent-gecko/src/l10n.js +++ b/fluent-gecko/src/l10n.js @@ -48,7 +48,7 @@ document.l10n = new DOMLocalization(window, resourceIds); // trigger first context to be fetched eagerly - document.l10n.ctxs.touchNext(); + document.l10n.bundles.touchNext(); document.l10n.ready = documentReady().then(() => { document.l10n.registerObservers(); diff --git a/fluent-gecko/src/localization.js b/fluent-gecko/src/localization.js index f9308da8b..9ad17629b 100644 --- a/fluent-gecko/src/localization.js +++ b/fluent-gecko/src/localization.js @@ -18,13 +18,13 @@ import Localization from "../../fluent-dom/src/localization"; /** * The default localization strategy for Gecko. It comabines locales * available in L10nRegistry, with locales requested by the user to - * generate the iterator over MessageContexts. + * generate the iterator over FluentBundles. * * In the future, we may want to allow certain modules to override this * with a different negotitation strategy to allow for the module to * be localized into a different language - for example DevTools. */ -function defaultGenerateMessages(resourceIds) { +function defaultGenerateBundles(resourceIds) { const requestedLocales = Services.locale.getRequestedLocales(); const availableLocales = L10nRegistry.getAvailableLocales(); const defaultLocale = Services.locale.defaultLocale; @@ -35,8 +35,8 @@ function defaultGenerateMessages(resourceIds) { } class GeckoLocalization extends Localization { - constructor(resourceIds, generateMessages = defaultGenerateMessages) { - super(resourceIds, generateMessages); + constructor(resourceIds, generateBundles = defaultGenerateBundles) { + super(resourceIds, generateBundles); } } diff --git a/fluent-gecko/src/message_context.js b/fluent-gecko/src/message_context.js index 0834c1000..0296c6ebb 100644 --- a/fluent-gecko/src/message_context.js +++ b/fluent-gecko/src/message_context.js @@ -1,4 +1,4 @@ -import { MessageContext } from "../../fluent/src/index"; +import { FluentBundle } from "../../fluent/src/index"; -this.MessageContext = MessageContext; -this.EXPORTED_SYMBOLS = ["MessageContext"]; +this.FluentBundle = FluentBundle; +this.EXPORTED_SYMBOLS = ["FluentBundle"]; diff --git a/fluent-react/CHANGELOG.md b/fluent-react/CHANGELOG.md index 223f1fe5a..6b38661ee 100644 --- a/fluent-react/CHANGELOG.md +++ b/fluent-react/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased + - Rename the `messages` prop to `bundles`. (#222) + + `` now expects an iterable of `FluentBundles` to be + passed as the `bundles` prop, rather than `messages`. + - Drop support for IE and old evergreen browsers. (#133) Currently supported are: Firefox 52+, Chrome 55+, Edge 15+, Safari 10.1+, @@ -315,12 +320,12 @@ troubles. `LocalizationProvider` component. The `LocalizationProvider` component takes one prop: `messages`. It should - be an iterable of `MessageContext` instances in order of user's preferred + be an iterable of `FluentBundle` instances in order of user's preferred languages. This iterable will be used by `Localization` to format translations. If a translation is missing in one language, `Localization` will fall back to the next locale. - - The relevant `MessageContext` is now cached in `Localized`'s state. + - The relevant `FluentBundle` is now cached in `Localized`'s state. ## fluent-react 0.2.0 diff --git a/fluent-react/examples/async-messages/src/l10n.js b/fluent-react/examples/async-messages/src/l10n.js index 3af8e6efe..4d6c7091c 100644 --- a/fluent-react/examples/async-messages/src/l10n.js +++ b/fluent-react/examples/async-messages/src/l10n.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import delay from 'delay'; import 'fluent-intl-polyfill/compat'; -import { MessageContext } from 'fluent/compat'; +import { FluentBundle } from 'fluent/compat'; import { LocalizationProvider } from 'fluent-react/compat'; import { negotiateLanguages } from 'fluent-langneg/compat'; @@ -19,15 +19,15 @@ async function createMessagesGenerator(currentLocales) { const fetched = await Promise.all( currentLocales.map(fetchMessages) ); - const bundle = fetched.reduce( + const messages = fetched.reduce( (obj, cur) => Object.assign(obj, cur) ); - return function* generateMessages() { + return function* generateBundles() { for (const locale of currentLocales) { - const cx = new MessageContext(locale); - cx.addMessages(bundle[locale]); - yield cx; + const bundle = new FluentBundle(locale); + bundle.addMessages(messages[locale]); + yield bundle; } } } @@ -51,21 +51,21 @@ export class AppLocalizationProvider extends Component { async componentWillMount() { const { currentLocales } = this.state; - const generateMessages = await createMessagesGenerator(currentLocales); - this.setState({ messages: generateMessages() }); + const generateBundles = await createMessagesGenerator(currentLocales); + this.setState({ bundles: generateBundles() }); } render() { const { children } = this.props; - const { messages } = this.state; + const { bundles } = this.state; - if (!messages) { + if (!bundles) { // Show a loader. return
; } return ( - + {children} ); diff --git a/fluent-react/examples/change-language/src/l10n.js b/fluent-react/examples/change-language/src/l10n.js index 8f1f960c7..8dc925ede 100644 --- a/fluent-react/examples/change-language/src/l10n.js +++ b/fluent-react/examples/change-language/src/l10n.js @@ -1,7 +1,7 @@ import React, { cloneElement, Children, Component } from 'react'; import 'fluent-intl-polyfill/compat'; -import { MessageContext } from 'fluent/compat'; +import { FluentBundle } from 'fluent/compat'; import { LocalizationProvider } from 'fluent-react/compat'; import { negotiateLanguages } from 'fluent-langneg/compat'; @@ -18,11 +18,11 @@ change = Change to { $locale } `, }; -function* generateMessages(currentLocales) { +function* generateBundles(currentLocales) { for (const locale of currentLocales) { - const cx = new MessageContext(locale); - cx.addMessages(MESSAGES_ALL[locale]); - yield cx; + const bundle = new FluentBundle(locale); + bundle.addMessages(MESSAGES_ALL[locale]); + yield bundle; } } @@ -59,7 +59,7 @@ export class AppLocalizationProvider extends Component { }; return ( - + { cloneElement(child, l10nProps) } ); diff --git a/fluent-react/examples/fallback-sync/src/index.js b/fluent-react/examples/fallback-sync/src/index.js index 63c002097..829aa45bc 100644 --- a/fluent-react/examples/fallback-sync/src/index.js +++ b/fluent-react/examples/fallback-sync/src/index.js @@ -3,11 +3,11 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { LocalizationProvider } from 'fluent-react/compat'; -import { generateMessages } from './l10n'; +import { generateBundles } from './l10n'; import App from './App'; ReactDOM.render( - + , document.getElementById('root') diff --git a/fluent-react/examples/fallback-sync/src/l10n.js b/fluent-react/examples/fallback-sync/src/l10n.js index de5f3802f..2eb385ef3 100644 --- a/fluent-react/examples/fallback-sync/src/l10n.js +++ b/fluent-react/examples/fallback-sync/src/l10n.js @@ -1,5 +1,5 @@ import 'fluent-intl-polyfill/compat'; -import { MessageContext } from 'fluent/compat'; +import { FluentBundle } from 'fluent/compat'; const MESSAGES_ALL = { 'pl': ` @@ -11,10 +11,10 @@ bar = Bar in English `, }; -export function* generateMessages() { +export function* generateBundles() { for (const locale of ['pl', 'en-US']) { - const cx = new MessageContext(locale); - cx.addMessages(MESSAGES_ALL[locale]); - yield cx; + const bundle = new FluentBundle(locale); + bundle.addMessages(MESSAGES_ALL[locale]); + yield bundle; } } diff --git a/fluent-react/examples/hello-world/src/index.js b/fluent-react/examples/hello-world/src/index.js index 3f6a96093..f9452d99f 100644 --- a/fluent-react/examples/hello-world/src/index.js +++ b/fluent-react/examples/hello-world/src/index.js @@ -3,11 +3,11 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { LocalizationProvider } from 'fluent-react/compat'; -import { generateMessages } from './l10n'; +import { generateBundles } from './l10n'; import App from './App'; ReactDOM.render( - + , document.getElementById('root') diff --git a/fluent-react/examples/hello-world/src/l10n.js b/fluent-react/examples/hello-world/src/l10n.js index 05451f4d5..429d508df 100644 --- a/fluent-react/examples/hello-world/src/l10n.js +++ b/fluent-react/examples/hello-world/src/l10n.js @@ -1,5 +1,5 @@ import 'fluent-intl-polyfill/compat'; -import { MessageContext } from 'fluent/compat'; +import { FluentBundle } from 'fluent/compat'; import { negotiateLanguages } from 'fluent-langneg/compat'; const MESSAGES_ALL = { @@ -13,7 +13,7 @@ today-is = Today is { DATETIME($date, month: "long", day: "numeric") }. `, }; -export function* generateMessages(userLocales) { +export function* generateBundles(userLocales) { // Choose locales that are best for the user. const currentLocales = negotiateLanguages( userLocales, @@ -22,8 +22,8 @@ export function* generateMessages(userLocales) { ); for (const locale of currentLocales) { - const cx = new MessageContext(locale); - cx.addMessages(MESSAGES_ALL[locale]); - yield cx; + const bundle = new FluentBundle(locale); + bundle.addMessages(MESSAGES_ALL[locale]); + yield bundle; } } diff --git a/fluent-react/examples/higher-order/src/index.js b/fluent-react/examples/higher-order/src/index.js index 3f6a96093..f9452d99f 100644 --- a/fluent-react/examples/higher-order/src/index.js +++ b/fluent-react/examples/higher-order/src/index.js @@ -3,11 +3,11 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { LocalizationProvider } from 'fluent-react/compat'; -import { generateMessages } from './l10n'; +import { generateBundles } from './l10n'; import App from './App'; ReactDOM.render( - + , document.getElementById('root') diff --git a/fluent-react/examples/higher-order/src/l10n.js b/fluent-react/examples/higher-order/src/l10n.js index 352c0ea52..952db62a9 100644 --- a/fluent-react/examples/higher-order/src/l10n.js +++ b/fluent-react/examples/higher-order/src/l10n.js @@ -1,5 +1,5 @@ import 'fluent-intl-polyfill/compat'; -import { MessageContext } from 'fluent/compat'; +import { FluentBundle } from 'fluent/compat'; import { negotiateLanguages } from 'fluent-langneg/compat'; const MESSAGES_ALL = { @@ -13,7 +13,7 @@ button-show-alert = Click me `, }; -export function* generateMessages(userLocales) { +export function* generateBundles(userLocales) { // Choose locales that are best for the user. const currentLocales = negotiateLanguages( userLocales, @@ -22,8 +22,8 @@ export function* generateMessages(userLocales) { ); for (const locale of currentLocales) { - const cx = new MessageContext(locale); - cx.addMessages(MESSAGES_ALL[locale]); - yield cx; + const bundle = new FluentBundle(locale); + bundle.addMessages(MESSAGES_ALL[locale]); + yield bundle; } } diff --git a/fluent-react/examples/html-markup/src/index.js b/fluent-react/examples/html-markup/src/index.js index 3f6a96093..f9452d99f 100644 --- a/fluent-react/examples/html-markup/src/index.js +++ b/fluent-react/examples/html-markup/src/index.js @@ -3,11 +3,11 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { LocalizationProvider } from 'fluent-react/compat'; -import { generateMessages } from './l10n'; +import { generateBundles } from './l10n'; import App from './App'; ReactDOM.render( - + , document.getElementById('root') diff --git a/fluent-react/examples/html-markup/src/l10n.js b/fluent-react/examples/html-markup/src/l10n.js index 6aaf3d267..07556e610 100644 --- a/fluent-react/examples/html-markup/src/l10n.js +++ b/fluent-react/examples/html-markup/src/l10n.js @@ -1,5 +1,5 @@ import 'fluent-intl-polyfill/compat'; -import { MessageContext } from 'fluent/compat'; +import { FluentBundle } from 'fluent/compat'; import { negotiateLanguages } from 'fluent-langneg/compat'; const MESSAGES_ALL = { @@ -21,7 +21,7 @@ agree-alert = Cool, agreed. `, }; -export function* generateMessages(userLocales) { +export function* generateBundles(userLocales) { // Choose locales that are best for the user. const currentLocales = negotiateLanguages( userLocales, @@ -30,8 +30,8 @@ export function* generateMessages(userLocales) { ); for (const locale of currentLocales) { - const cx = new MessageContext(locale); - cx.addMessages(MESSAGES_ALL[locale]); - yield cx; + const bundle = new FluentBundle(locale); + bundle.addMessages(MESSAGES_ALL[locale]); + yield bundle; } } diff --git a/fluent-react/examples/redux-async/src/actions.js b/fluent-react/examples/redux-async/src/actions.js index 781b9330a..96f0cad3c 100644 --- a/fluent-react/examples/redux-async/src/actions.js +++ b/fluent-react/examples/redux-async/src/actions.js @@ -1,4 +1,4 @@ -import { MessageContext } from 'fluent/compat'; +import { FluentBundle } from 'fluent/compat'; import { negotiateLanguages } from 'fluent-langneg/compat'; import delay from 'delay'; @@ -25,15 +25,15 @@ export function changeLocales(userLocales) { currentLocales.map(fetchMessages) ); - const bundle = fetched.reduce( + const messages = fetched.reduce( (obj, cur) => Object.assign(obj, cur) ); - const generateMessages = function* () { + const generateBundles = function* () { for (const locale of currentLocales) { - const cx = new MessageContext(locale); - cx.addMessages(bundle[locale]); - yield cx; + const bundle = new FluentBundle(locale); + bundle.addMessages(messages[locale]); + yield bundle; } } @@ -41,7 +41,7 @@ export function changeLocales(userLocales) { type: 'CHANGE_LOCALES_RESPONSE', userLocales, currentLocales, - messages: generateMessages() + bundles: generateBundles() }); }; } diff --git a/fluent-react/examples/redux-async/src/l10n.js b/fluent-react/examples/redux-async/src/l10n.js index 8b54fddf6..1e6f6646f 100644 --- a/fluent-react/examples/redux-async/src/l10n.js +++ b/fluent-react/examples/redux-async/src/l10n.js @@ -13,22 +13,22 @@ class AppLocalizationProvider extends Component { } render() { - const { messages, children } = this.props; + const { bundles, children } = this.props; - if (!messages) { + if (!bundles) { // Show a loader return
; } return ( - + {children} ); } } -const mapStateToProps = state => ({ messages: state.messages }); +const mapStateToProps = state => ({ bundles: state.bundles }); const mapDispatchToProps = { changeLocales }; export default connect(mapStateToProps, mapDispatchToProps)( diff --git a/fluent-react/examples/redux-async/src/reducer.js b/fluent-react/examples/redux-async/src/reducer.js index 8c5da5e40..33aac9863 100644 --- a/fluent-react/examples/redux-async/src/reducer.js +++ b/fluent-react/examples/redux-async/src/reducer.js @@ -2,7 +2,7 @@ export default function reducer(state = { isFetching: false, userLocales: ['en-US'], currentLocales: ['en-US'], - messages: null + bundles: null }, action) { switch (action.type) { case 'CHANGE_LOCALES_REQUEST': { @@ -12,13 +12,13 @@ export default function reducer(state = { }; } case 'CHANGE_LOCALES_RESPONSE': { - const { userLocales, currentLocales, messages } = action; + const { userLocales, currentLocales, bundles } = action; return { ...state, isFetching: false, userLocales, currentLocales, - messages + bundles }; } default: diff --git a/fluent-react/examples/redux-sync/src/actions.js b/fluent-react/examples/redux-sync/src/actions.js index 392b59f95..5a122cf83 100644 --- a/fluent-react/examples/redux-sync/src/actions.js +++ b/fluent-react/examples/redux-sync/src/actions.js @@ -1,4 +1,4 @@ -import { MessageContext } from 'fluent/compat'; +import { FluentBundle } from 'fluent/compat'; import { negotiateLanguages } from 'fluent-langneg/compat'; const MESSAGES_ALL = { @@ -21,11 +21,11 @@ export function changeLocales(userLocales) { { defaultLocale: 'en-US' } ); - const generateMessages = function* () { + const generateBundles = function* () { for (const locale of currentLocales) { - const cx = new MessageContext(locale); - cx.addMessages(MESSAGES_ALL[locale]); - yield cx; + const bundle = new FluentBundle(locale); + bundle.addMessages(MESSAGES_ALL[locale]); + yield bundle; } } @@ -33,6 +33,6 @@ export function changeLocales(userLocales) { type: 'CHANGE_LOCALES', userLocales, currentLocales, - messages: generateMessages() + bundles: generateBundles() }; } diff --git a/fluent-react/examples/redux-sync/src/l10n.js b/fluent-react/examples/redux-sync/src/l10n.js index 5f95b6cea..e11e72c58 100644 --- a/fluent-react/examples/redux-sync/src/l10n.js +++ b/fluent-react/examples/redux-sync/src/l10n.js @@ -12,22 +12,22 @@ class AppLocalizationProvider extends Component { } render() { - const { messages, children } = this.props; + const { bundles, children } = this.props; - if (!messages) { + if (!bundles) { // Show a loader return
; } return ( - + {children} ); } } -const mapStateToProps = state => ({ messages: state.messages }); +const mapStateToProps = state => ({ bundles: state.bundles }); const mapDispatchToProps = { changeLocales }; export default connect(mapStateToProps, mapDispatchToProps)( diff --git a/fluent-react/examples/redux-sync/src/reducer.js b/fluent-react/examples/redux-sync/src/reducer.js index 6e382174a..20dd93c19 100644 --- a/fluent-react/examples/redux-sync/src/reducer.js +++ b/fluent-react/examples/redux-sync/src/reducer.js @@ -1,16 +1,16 @@ export default function reducer(state = { userLocales: ['en-US'], currentLocales: ['en-US'], - messages: null + bundles: null }, action) { switch (action.type) { case 'CHANGE_LOCALES': { - const { userLocales, currentLocales, messages } = action; + const { userLocales, currentLocales, bundles } = action; return { ...state, userLocales, currentLocales, - messages + bundles }; } default: diff --git a/fluent-react/examples/text-input/src/index.js b/fluent-react/examples/text-input/src/index.js index 3f6a96093..f9452d99f 100644 --- a/fluent-react/examples/text-input/src/index.js +++ b/fluent-react/examples/text-input/src/index.js @@ -3,11 +3,11 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { LocalizationProvider } from 'fluent-react/compat'; -import { generateMessages } from './l10n'; +import { generateBundles } from './l10n'; import App from './App'; ReactDOM.render( - + , document.getElementById('root') diff --git a/fluent-react/examples/text-input/src/l10n.js b/fluent-react/examples/text-input/src/l10n.js index 0bba57131..0294b38b5 100644 --- a/fluent-react/examples/text-input/src/l10n.js +++ b/fluent-react/examples/text-input/src/l10n.js @@ -1,5 +1,5 @@ import 'fluent-intl-polyfill/compat'; -import { MessageContext } from 'fluent/compat'; +import { FluentBundle } from 'fluent/compat'; import { negotiateLanguages } from 'fluent-langneg/compat'; const MESSAGES_ALL = { @@ -17,7 +17,7 @@ type-name = `, }; -export function* generateMessages(userLocales) { +export function* generateBundles(userLocales) { // Choose locales that are best for the user. const currentLocales = negotiateLanguages( userLocales, @@ -26,8 +26,8 @@ export function* generateMessages(userLocales) { ); for (const locale of currentLocales) { - const cx = new MessageContext(locale); - cx.addMessages(MESSAGES_ALL[locale]); - yield cx; + const bundle = new FluentBundle(locale); + bundle.addMessages(MESSAGES_ALL[locale]); + yield bundle; } } diff --git a/fluent-react/src/index.js b/fluent-react/src/index.js index 874aeaee7..0c5ade489 100644 --- a/fluent-react/src/index.js +++ b/fluent-react/src/index.js @@ -7,7 +7,7 @@ * React's Components system and the virtual DOM. Translations are exposed to * components via the provider pattern. * - * + * * *

{'Hello, world!'}

*
diff --git a/fluent-react/src/localization.js b/fluent-react/src/localization.js index 63812cb24..36b70aaea 100644 --- a/fluent-react/src/localization.js +++ b/fluent-react/src/localization.js @@ -5,58 +5,58 @@ import { CachedSyncIterable } from "cached-iterable"; * `ReactLocalization` handles translation formatting and fallback. * * The current negotiated fallback chain of languages is stored in the - * `ReactLocalization` instance in form of an iterable of `MessageContext` + * `ReactLocalization` instance in form of an iterable of `FluentBundle` * instances. This iterable is used to find the best existing translation for * a given identifier. * * `Localized` components must subscribe to the changes of the * `ReactLocalization`'s fallback chain. When the fallback chain changes (the - * `messages` iterable is set anew), all subscribed compontent must relocalize. + * `bundles` iterable is set anew), all subscribed compontent must relocalize. * * The `ReactLocalization` class instances are exposed to `Localized` elements * via the `LocalizationProvider` component. */ export default class ReactLocalization { - constructor(messages) { - this.contexts = CachedSyncIterable.from(messages); + constructor(bundles) { + this.bundles = CachedSyncIterable.from(bundles); this.subs = new Set(); } /* - * Subscribe a `Localized` component to changes of `messages`. + * Subscribe a `Localized` component to changes of `bundles`. */ subscribe(comp) { this.subs.add(comp); } /* - * Unsubscribe a `Localized` component from `messages` changes. + * Unsubscribe a `Localized` component from `bundles` changes. */ unsubscribe(comp) { this.subs.delete(comp); } /* - * Set a new `messages` iterable and trigger the retranslation. + * Set a new `bundles` iterable and trigger the retranslation. */ - setMessages(messages) { - this.contexts = CachedSyncIterable.from(messages); + setBundles(bundles) { + this.bundles = CachedSyncIterable.from(bundles); // Update all subscribed Localized components. this.subs.forEach(comp => comp.relocalize()); } - getMessageContext(id) { - return mapContextSync(this.contexts, id); + getBundle(id) { + return mapContextSync(this.bundles, id); } - formatCompound(mcx, msg, args) { - const value = mcx.format(msg, args); + formatCompound(bundle, msg, args) { + const value = bundle.format(msg, args); if (msg.attrs) { var attrs = {}; for (const name of Object.keys(msg.attrs)) { - attrs[name] = mcx.format(msg.attrs[name], args); + attrs[name] = bundle.format(msg.attrs[name], args); } } @@ -67,14 +67,14 @@ export default class ReactLocalization { * Find a translation by `id` and format it to a string using `args`. */ getString(id, args, fallback) { - const mcx = this.getMessageContext(id); + const bundle = this.getBundle(id); - if (mcx === null) { + if (bundle === null) { return fallback || id; } - const msg = mcx.getMessage(id); - return mcx.format(msg, args); + const msg = bundle.getMessage(id); + return bundle.format(msg, args); } } diff --git a/fluent-react/src/localized.js b/fluent-react/src/localized.js index bcf47de93..8a69f92c7 100644 --- a/fluent-react/src/localized.js +++ b/fluent-react/src/localized.js @@ -87,19 +87,19 @@ export default class Localized extends Component { return elem; } - const mcx = l10n.getMessageContext(id); + const bundle = l10n.getBundle(id); - if (mcx === null) { + if (bundle === null) { // Use the wrapped component as fallback. return elem; } - const msg = mcx.getMessage(id); + const msg = bundle.getMessage(id); const [args, elems] = toArguments(this.props); const { value: messageValue, attrs: messageAttrs - } = l10n.formatCompound(mcx, msg, args); + } = l10n.formatCompound(bundle, msg, args); // The default is to forbid all message attributes. If the attrs prop exists // on the Localized instance, only set message attributes which have been diff --git a/fluent-react/src/provider.js b/fluent-react/src/provider.js index f288aaec2..ab7a826cb 100644 --- a/fluent-react/src/provider.js +++ b/fluent-react/src/provider.js @@ -11,30 +11,30 @@ import createParseMarkup from "./markup"; * elements in the descendant's render tree without the need to pass them * explicitly. * - * + * * … * * - * The `LocalizationProvider` component takes one prop: `messages`. It should - * be an iterable of `MessageContext` instances in order of the user's - * preferred languages. The `MessageContext` instances will be used by + * The `LocalizationProvider` component takes one prop: `bundles`. It should + * be an iterable of `FluentBundle` instances in order of the user's + * preferred languages. The `FluentBundle` instances will be used by * `ReactLocalization` to format translations. If a translation is missing in * one instance, `ReactLocalization` will fall back to the next one. */ export default class LocalizationProvider extends Component { constructor(props) { super(props); - const {messages, parseMarkup} = props; + const {bundles, parseMarkup} = props; - if (messages === undefined) { - throw new Error("LocalizationProvider must receive the messages prop."); + if (bundles === undefined) { + throw new Error("LocalizationProvider must receive the bundles prop."); } - if (!messages[Symbol.iterator]) { - throw new Error("The messages prop must be an iterable."); + if (!bundles[Symbol.iterator]) { + throw new Error("The bundles prop must be an iterable."); } - this.l10n = new ReactLocalization(messages); + this.l10n = new ReactLocalization(bundles); this.parseMarkup = parseMarkup || createParseMarkup(); } @@ -46,10 +46,10 @@ export default class LocalizationProvider extends Component { } componentWillReceiveProps(next) { - const { messages } = next; + const { bundles } = next; - if (messages !== this.props.messages) { - this.l10n.setMessages(messages); + if (bundles !== this.props.bundles) { + this.l10n.setBundles(bundles); } } @@ -65,7 +65,7 @@ LocalizationProvider.childContextTypes = { LocalizationProvider.propTypes = { children: PropTypes.element.isRequired, - messages: isIterable, + bundles: isIterable, parseMarkup: PropTypes.func, }; diff --git a/fluent-react/test/localized_change_test.js b/fluent-react/test/localized_change_test.js index 9d997728b..121b7255d 100644 --- a/fluent-react/test/localized_change_test.js +++ b/fluent-react/test/localized_change_test.js @@ -1,16 +1,16 @@ import React from 'react'; import assert from 'assert'; import { shallow } from 'enzyme'; -import { MessageContext } from '../../fluent/src'; +import { FluentBundle } from '../../fluent/src'; import ReactLocalization from '../src/localization'; import { Localized } from '../src/index'; -suite('Localized - change messages', function() { +suite('Localized - change bundles', function() { test('relocalizing', function() { - const mcx1 = new MessageContext(); - const l10n = new ReactLocalization([mcx1]); + const bundle1 = new FluentBundle(); + const l10n = new ReactLocalization([bundle1]); - mcx1.addMessages(` + bundle1.addMessages(` foo = FOO `); @@ -25,12 +25,12 @@ foo = FOO
FOO
)); - const mcx2 = new MessageContext(); - mcx2.addMessages(` + const bundle2 = new FluentBundle(); + bundle2.addMessages(` foo = BAR `); - l10n.setMessages([mcx2]); + l10n.setBundles([bundle2]); wrapper.update(); assert.ok(wrapper.contains( diff --git a/fluent-react/test/localized_fallback_test.js b/fluent-react/test/localized_fallback_test.js index 81eb43062..976524feb 100644 --- a/fluent-react/test/localized_fallback_test.js +++ b/fluent-react/test/localized_fallback_test.js @@ -1,16 +1,16 @@ import React from 'react'; import assert from 'assert'; import { shallow } from 'enzyme'; -import { MessageContext } from '../../fluent/src'; +import { FluentBundle } from '../../fluent/src'; import ReactLocalization from '../src/localization'; import { Localized } from '../src/index'; suite('Localized - fallback', function() { test('message id in the first context', function() { - const mcx1 = new MessageContext(); - const l10n = new ReactLocalization([mcx1]); + const bundle1 = new FluentBundle(); + const l10n = new ReactLocalization([bundle1]); - mcx1.addMessages(` + bundle1.addMessages(` foo = FOO `); @@ -27,14 +27,14 @@ foo = FOO }); test('message id in the second context', function() { - const mcx1 = new MessageContext(); - const mcx2 = new MessageContext(); - const l10n = new ReactLocalization([mcx1, mcx2]); + const bundle1 = new FluentBundle(); + const bundle2 = new FluentBundle(); + const l10n = new ReactLocalization([bundle1, bundle2]); - mcx1.addMessages(` + bundle1.addMessages(` not-foo = NOT FOO `); - mcx2.addMessages(` + bundle2.addMessages(` foo = FOO `); @@ -51,10 +51,10 @@ foo = FOO }); test('missing message', function() { - const mcx1 = new MessageContext(); - const l10n = new ReactLocalization([mcx1]); + const bundle1 = new FluentBundle(); + const l10n = new ReactLocalization([bundle1]); - mcx1.addMessages(` + bundle1.addMessages(` not-foo = NOT FOO `); diff --git a/fluent-react/test/localized_overlay_test.js b/fluent-react/test/localized_overlay_test.js index 11069172b..9b097cc34 100644 --- a/fluent-react/test/localized_overlay_test.js +++ b/fluent-react/test/localized_overlay_test.js @@ -1,7 +1,7 @@ import React from 'react'; import assert from 'assert'; import { shallow } from 'enzyme'; -import { MessageContext } from '../../fluent/src'; +import { FluentBundle } from '../../fluent/src'; import ReactLocalization from '../src/localization'; import createParseMarkup from '../src/markup'; import { Localized } from '../src/index'; @@ -10,10 +10,10 @@ suite('Localized - overlay', function() {; let parseMarkup = createParseMarkup(); test('< in text', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` true = 0 < 3 is true. `) @@ -32,10 +32,10 @@ true = 0 < 3 is true. }); test('& in text', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` megaman = Jumping & Shooting `) @@ -54,10 +54,10 @@ megaman = Jumping & Shooting }); test('HTML entity', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` two = First · Second `) @@ -76,10 +76,10 @@ two = First · Second }); test('one element is matched', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = Click ! `) @@ -98,10 +98,10 @@ foo = Click ! }); test('an element of different case is matched', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = Click ! `) @@ -123,10 +123,10 @@ foo = Click ! }); test('two elements are matched', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = Sign in or cancel. `) @@ -148,10 +148,10 @@ foo = Sign in or cancel. }); test('unexpected child is reduced to text', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = Sign in or cancel. `) @@ -172,10 +172,10 @@ foo = Sign in or cancel. }); test('element not found in the translation is removed', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = Sign in. `) @@ -197,10 +197,10 @@ foo = Sign in. }); test('attributes on translated children are ignored', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = Click ! `) @@ -219,10 +219,10 @@ foo = Click ! }); test('nested children are ignored', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = Click ! `) @@ -241,10 +241,10 @@ foo = Click ! }); test('non-React element prop is used in markup', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = Sign in. `) @@ -268,10 +268,10 @@ suite('Localized - overlay of void elements', function() {; let parseMarkup = createParseMarkup(); test('void prop name, void prop value, void translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -290,10 +290,10 @@ foo = BEFORE AFTER }); test('void prop name, void prop value, empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -312,10 +312,10 @@ foo = BEFORE AFTER }); test('void prop name, void prop value, non-empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE Foo AFTER `) @@ -336,10 +336,10 @@ foo = BEFORE Foo AFTER }); test('void prop name, non-empty prop value, void translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -358,10 +358,10 @@ foo = BEFORE AFTER }); test('void prop name, non-empty prop value, empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -380,10 +380,10 @@ foo = BEFORE AFTER }); test('void prop name, non-empty prop value, non-empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE Foo AFTER `) @@ -404,10 +404,10 @@ foo = BEFORE Foo AFTER }); test('non-void prop name, void prop value, void translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -431,10 +431,10 @@ foo = BEFORE AFTER }); test('non-void prop name, void prop value, empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -453,10 +453,10 @@ foo = BEFORE AFTER }); test('non-void prop name, void prop value, non-empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE Foo AFTER `) @@ -475,10 +475,10 @@ foo = BEFORE Foo AFTER }); test('non-void prop name, non-empty prop value, void translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -501,10 +501,10 @@ foo = BEFORE AFTER }); test('non-void prop name, non-empty prop value, empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -523,10 +523,10 @@ foo = BEFORE AFTER }); test('non-void prop name, non-empty prop value, non-empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE Foo AFTER `) @@ -545,10 +545,10 @@ foo = BEFORE Foo AFTER }); test('custom prop name, void prop value, void translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -572,10 +572,10 @@ foo = BEFORE AFTER }); test('custom prop name, void prop value, empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -594,10 +594,10 @@ foo = BEFORE AFTER }); test('custom prop name, void prop value, non-empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE Foo AFTER `) @@ -616,10 +616,10 @@ foo = BEFORE Foo AFTER }); test('custom prop name, non-empty prop value, void translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -643,10 +643,10 @@ foo = BEFORE AFTER }); test('custom prop name, non-empty prop value, empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE AFTER `) @@ -665,10 +665,10 @@ foo = BEFORE AFTER }); test('custom prop name, non-empty prop value, non-empty translation', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = BEFORE Foo AFTER `) @@ -695,10 +695,10 @@ suite('Localized - custom parseMarkup', function() {; return createParseMarkup()(str); } - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` # We must use an HTML tag to trigger the overlay logic. foo = test custom markup parser `); @@ -724,10 +724,10 @@ foo = test custom markup parser ]; } - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` # We must use an HTML tag to trigger the overlay logic. foo = test custom markup parser `); diff --git a/fluent-react/test/localized_render_test.js b/fluent-react/test/localized_render_test.js index 7ccb25e9f..767015b13 100644 --- a/fluent-react/test/localized_render_test.js +++ b/fluent-react/test/localized_render_test.js @@ -2,16 +2,16 @@ import React from 'react'; import assert from 'assert'; import sinon from 'sinon'; import { shallow } from 'enzyme'; -import { MessageContext } from '../../fluent/src'; +import { FluentBundle } from '../../fluent/src'; import ReactLocalization from '../src/localization'; import { Localized } from '../src/index'; suite('Localized - rendering', function() { test('render the value', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = FOO `) @@ -28,10 +28,10 @@ foo = FOO }); test('render an allowed attribute', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = .attr = ATTR `) @@ -49,10 +49,10 @@ foo = }); test('only render allowed attributes', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = .attr1 = ATTR 1 .attr2 = ATTR 2 @@ -71,10 +71,10 @@ foo = }); test('filter out forbidden attributes', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = .attr = ATTR `) @@ -92,10 +92,10 @@ foo = }); test('filter all attributes if attrs not given', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = .attr = ATTR `) @@ -113,10 +113,10 @@ foo = }); test('preserve existing attributes when setting new ones', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = .attr = ATTR `) @@ -134,10 +134,10 @@ foo = }); test('overwrite existing attributes if allowed', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = .existing = ATTR `) @@ -155,10 +155,10 @@ foo = }); test('protect existing attributes if setting is forbidden', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = .existing = ATTR `) @@ -176,10 +176,10 @@ foo = }); test('protect existing attributes by default', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = .existing = ATTR `) @@ -197,10 +197,10 @@ foo = }); test('preserve children when translation value is null', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = .title = TITLE `) @@ -223,11 +223,11 @@ foo = test('$arg is passed to format the value', function() { - const mcx = new MessageContext(); - const format = sinon.spy(mcx, 'format'); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const format = sinon.spy(bundle, 'format'); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = { $arg } `) @@ -243,11 +243,11 @@ foo = { $arg } }); test('$arg is passed to format the attributes', function() { - const mcx = new MessageContext(); - const format = sinon.spy(mcx, 'format'); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const format = sinon.spy(bundle, 'format'); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = { $arg } .attr = { $arg } `) diff --git a/fluent-react/test/localized_valid_test.js b/fluent-react/test/localized_valid_test.js index 12c4dc748..95febcd8c 100644 --- a/fluent-react/test/localized_valid_test.js +++ b/fluent-react/test/localized_valid_test.js @@ -16,7 +16,7 @@ suite('Localized - validation', function() { test('inside of a LocalizationProvider', function() { const wrapper = shallow( - +
diff --git a/fluent-react/test/localized_void_test.js b/fluent-react/test/localized_void_test.js index 2d785e7c9..a77967fd1 100644 --- a/fluent-react/test/localized_void_test.js +++ b/fluent-react/test/localized_void_test.js @@ -1,16 +1,16 @@ import React from 'react'; import assert from 'assert'; import { shallow } from 'enzyme'; -import { MessageContext } from '../../fluent/src'; +import { FluentBundle } from '../../fluent/src'; import ReactLocalization from '../src/localization'; import { Localized } from '../src/index'; suite('Localized - void elements', function() { test('do not render the value in void elements', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = FOO `) @@ -27,10 +27,10 @@ foo = FOO }); test('render attributes in void elements', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = .title = TITLE `) @@ -48,10 +48,10 @@ foo = }); test('render attributes but not value in void elements', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); - mcx.addMessages(` + bundle.addMessages(` foo = FOO .title = TITLE `) diff --git a/fluent-react/test/provider_change_test.js b/fluent-react/test/provider_change_test.js index 2ffaca5f8..1102f0a03 100644 --- a/fluent-react/test/provider_change_test.js +++ b/fluent-react/test/provider_change_test.js @@ -7,42 +7,42 @@ import { LocalizationProvider } from '../src/index'; suite('LocalizationProvider - changing props', function() { test('does not change the ReactLocalization', function() { const wrapper = shallow( - +
); const oldL10n = wrapper.instance().l10n; - wrapper.setProps({ messages: [] }); + wrapper.setProps({ bundles: [] }); const newL10n = wrapper.instance().l10n; assert.equal(oldL10n, newL10n); }); - test('calls the ReactLocalization\'s setMessages method', function() { + test('calls the ReactLocalization\'s setBundles method', function() { const wrapper = shallow( - +
); - const spy = sinon.spy(wrapper.instance().l10n, 'setMessages'); + const spy = sinon.spy(wrapper.instance().l10n, 'setBundles'); const newMessages = []; - wrapper.setProps({ messages: newMessages }); + wrapper.setProps({ bundles: newMessages }); const { args } = spy.getCall(0); assert.deepEqual(args, [newMessages]); }); - test('changes the ReactLocalization\'s messages contexts', function() { + test('changes the ReactLocalization\'s bundles bundles', function() { const wrapper = shallow( - +
); - const oldContexts = wrapper.instance().l10n.contexts; - wrapper.setProps({ messages: [] }); - const newContexts = wrapper.instance().l10n.contexts; + const oldContexts = wrapper.instance().l10n.bundles; + wrapper.setProps({ bundles: [] }); + const newContexts = wrapper.instance().l10n.bundles; assert.notEqual(oldContexts, newContexts); }); diff --git a/fluent-react/test/provider_context_test.js b/fluent-react/test/provider_context_test.js index d139637e8..c084cda38 100644 --- a/fluent-react/test/provider_context_test.js +++ b/fluent-react/test/provider_context_test.js @@ -2,14 +2,14 @@ import React, {Component} from 'react'; import PropTypes from "prop-types"; import assert from 'assert'; import { render } from 'enzyme'; -import { MessageContext } from '../../fluent/src'; +import { FluentBundle } from '../../fluent/src'; import { LocalizationProvider, isReactLocalization } from '../src/index'; suite('LocalizationProvider - context', function() { test('exposes localization', function() { - const mcx = new MessageContext(); - mcx.addMessages("foo = Foo"); + const bundle = new FluentBundle(); + bundle.addMessages("foo = Foo"); class Testing extends Component { render() { @@ -22,7 +22,7 @@ suite('LocalizationProvider - context', function() { }; const wrapper = render( - + ); @@ -43,7 +43,7 @@ suite('LocalizationProvider - context', function() { }; const wrapper = render( - "Test"}> + "Test"}> ); diff --git a/fluent-react/test/provider_valid_test.js b/fluent-react/test/provider_valid_test.js index 83d29f2b1..fde249757 100644 --- a/fluent-react/test/provider_valid_test.js +++ b/fluent-react/test/provider_valid_test.js @@ -15,7 +15,7 @@ suite('LocalizationProvider - validation', function() { test('valid use', function() { const wrapper = shallow( - +
); @@ -25,7 +25,7 @@ suite('LocalizationProvider - validation', function() { test('without a child', function() { function render() { shallow( - + ); } assert.throws(render, /a single React element child/); @@ -34,7 +34,7 @@ suite('LocalizationProvider - validation', function() { test('with multiple children', function() { function render() { shallow( - +
@@ -43,19 +43,19 @@ suite('LocalizationProvider - validation', function() { assert.throws(render, /a single React element child/); }); - test('without messages', function() { + test('without bundles', function() { function render() { shallow( ); } - assert.throws(render, /must receive the messages prop/); + assert.throws(render, /must receive the bundles prop/); }); - test('without iterable messages', function() { + test('without iterable bundles', function() { function render() { shallow( - + ); } assert.throws(render, /must be an iterable/); diff --git a/fluent-react/test/with_localization_test.js b/fluent-react/test/with_localization_test.js index f3c1264a2..e521a344f 100644 --- a/fluent-react/test/with_localization_test.js +++ b/fluent-react/test/with_localization_test.js @@ -1,7 +1,7 @@ import React from 'react'; import assert from 'assert'; import { mount, shallow } from 'enzyme'; -import { MessageContext } from '../../fluent/src'; +import { FluentBundle } from '../../fluent/src'; import ReactLocalization from '../src/localization'; import { withLocalization, LocalizationProvider } from '../src'; @@ -14,7 +14,7 @@ suite('withLocalization', function() { const EnhancedComponent = withLocalization(DummyComponent); const wrapper = shallow( - + ); @@ -31,11 +31,11 @@ suite('withLocalization', function() { }); test('getString with access to the l10n context', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); const EnhancedComponent = withLocalization(DummyComponent); - mcx.addMessages(` + bundle.addMessages(` foo = FOO `); @@ -50,11 +50,11 @@ foo = FOO }); test('getString with access to the l10n context, with fallback value', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); + const bundle = new FluentBundle(); + const l10n = new ReactLocalization([bundle]); const EnhancedComponent = withLocalization(DummyComponent); - mcx.addMessages(` + bundle.addMessages(` foo = FOO `); @@ -69,14 +69,8 @@ foo = FOO }); test('getString without access to the l10n context', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); const EnhancedComponent = withLocalization(DummyComponent); - mcx.addMessages(` -foo = FOO -`); - const wrapper = shallow( ); @@ -87,14 +81,8 @@ foo = FOO }); test('getString without access to the l10n context, with fallback value', function() { - const mcx = new MessageContext(); - const l10n = new ReactLocalization([mcx]); const EnhancedComponent = withLocalization(DummyComponent); - mcx.addMessages(` -foo = FOO -`); - const wrapper = shallow( ); @@ -105,11 +93,11 @@ foo = FOO }); test('getString with access to the l10n context, with message changes', function() { - const initialMcx = new MessageContext(); - const l10n = new ReactLocalization([initialMcx]); + const initialBundle = new FluentBundle(); + const l10n = new ReactLocalization([initialBundle]); const EnhancedComponent = withLocalization(({ getString }) => getString('foo')); - initialMcx.addMessages('foo = FOO'); + initialBundle.addMessages('foo = FOO'); const wrapper = mount( , @@ -118,9 +106,9 @@ foo = FOO assert.equal(wrapper.text(), 'FOO'); - const newMcx = new MessageContext(); - newMcx.addMessages('foo = BAR'); - l10n.setMessages([newMcx]); + const newBundle = new FluentBundle(); + newBundle.addMessages('foo = BAR'); + l10n.setBundles([newBundle]); assert.equal(wrapper.text(), 'BAR'); }) diff --git a/fluent-sequence/CHANGELOG.md b/fluent-sequence/CHANGELOG.md index 6737d3218..68b61fcf2 100644 --- a/fluent-sequence/CHANGELOG.md +++ b/fluent-sequence/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Unreleased + + - Rename `mapContextSync` to `mapBundleSync`. + - Rename `mapContextAsync` to `mapBundleAsync`. + ## fluent-sequence 0.1.0 (August 17, 2018) The initial release based on `fluent` 0.7.0. diff --git a/fluent-sequence/README.md b/fluent-sequence/README.md index 1c323241b..5a71b0c92 100644 --- a/fluent-sequence/README.md +++ b/fluent-sequence/README.md @@ -1,7 +1,7 @@ # fluent-sequence `fluent-sequence` provides mapping functions from string identifiers to -`MessageContext` instances taken from synchronous or asynchronous sequences. +`FluentBundle` instances taken from synchronous or asynchronous sequences. It's part of Project Fluent, a localization framework designed to unleash the expressive power of the natural language. @@ -17,25 +17,25 @@ the `FluentSequence` global). ## How to use -An ordered iterable of `MessageContext` instances can represent the current +An ordered iterable of `FluentBundle` instances can represent the current negotiated fallback chain of languages. This iterable can be used to find the best existing translation for a given identifier. -`fluent-sequence` provides two mapping functions: `mapContextSync`, and -`mapContextAsync`. They can be used to find the first `MessageContext` in the +`fluent-sequence` provides two mapping functions: `mapBundleSync`, and +`mapBundleAsync`. They can be used to find the first `FluentBundle` in the given iterable which contains the translation with the given identifier. If the iterable is ordered according to the result of a language negotiation the -returned `MessageContext` contains the best available translation. +returned `FluentBundle` contains the best available translation. A simple function which formats translations based on the identifier might be implemented as follows: ```js -import {mapContextSync} from "fluent-sequence"; +import {mapBundleSync} from "fluent-sequence"; function formatString(id, args) { - // contexts is a negotiated iterable of MessageContext instances. - let ctx = mapContextSync(contexts, id); + // contexts is a negotiated iterable of FluentBundle instances. + let ctx = mapBundleSync(contexts, id); if (ctx === null) { return id; @@ -46,9 +46,9 @@ function formatString(id, args) { } ``` -When passing a synchronous iterator to `mapContextSync`, wrap it in +When passing a synchronous iterator to `mapBundleSync`, wrap it in `CachedSyncIterable` from the [`cached-iterable`][] package. When passing an -asynchronous iterator to `mapContextAsync`, wrap it in `CachedAsyncIterable`. +asynchronous iterator to `mapBundleAsync`, wrap it in `CachedAsyncIterable`. This allows multiple calls to `mapContext*` without advancing and eventually depleting the iterator. diff --git a/fluent-sequence/package.json b/fluent-sequence/package.json index 3119123b2..68c923dc4 100644 --- a/fluent-sequence/package.json +++ b/fluent-sequence/package.json @@ -1,6 +1,6 @@ { "name": "fluent-sequence", - "description": "Manage ordered sequences of MessageContexts", + "description": "Manage ordered sequences of FluentBundles", "version": "0.1.0", "homepage": "https://projectfluent.org", "author": "Mozilla ", diff --git a/fluent-sequence/src/index.js b/fluent-sequence/src/index.js index bef6380c9..84f354fb8 100644 --- a/fluent-sequence/src/index.js +++ b/fluent-sequence/src/index.js @@ -1,7 +1,7 @@ /* * @module fluent-sequence - * @overview Manage ordered sequences of MessageContexts. + * @overview Manage ordered sequences of FluentBundles. */ -export {default as mapContextSync} from "./map_sync"; -export {default as mapContextAsync} from "./map_async"; +export {default as mapBundleSync} from "./map_sync"; +export {default as mapBundleAsync} from "./map_async"; diff --git a/fluent-sequence/src/map_async.js b/fluent-sequence/src/map_async.js index 5cb7fc70d..ebd2abe77 100644 --- a/fluent-sequence/src/map_async.js +++ b/fluent-sequence/src/map_async.js @@ -1,36 +1,36 @@ /* * Asynchronously map an identifier or an array of identifiers to the best - * `MessageContext` instance(s). + * `FluentBundle` instance(s). * * @param {AsyncIterable} iterable * @param {string|Array} ids - * @returns {Promise>} + * @returns {Promise>} */ -export default async function mapContextAsync(iterable, ids) { +export default async function mapBundleAsync(iterable, ids) { if (!Array.isArray(ids)) { - for await (const context of iterable) { - if (context.hasMessage(ids)) { - return context; + for await (const bundle of iterable) { + if (bundle.hasMessage(ids)) { + return bundle; } } } let remainingCount = ids.length; - const foundContexts = new Array(remainingCount).fill(null); + const foundBundles = new Array(remainingCount).fill(null); - for await (const context of iterable) { + for await (const bundle of iterable) { for (const [index, id] of ids.entries()) { - if (!foundContexts[index] && context.hasMessage(id)) { - foundContexts[index] = context; + if (!foundBundles[index] && bundle.hasMessage(id)) { + foundBundles[index] = bundle; remainingCount--; } // Return early when all ids have been mapped to contexts. if (remainingCount === 0) { - return foundContexts; + return foundBundles; } } } - return foundContexts; + return foundBundles; } diff --git a/fluent-sequence/src/map_sync.js b/fluent-sequence/src/map_sync.js index 8f4e05571..b40cedbe3 100644 --- a/fluent-sequence/src/map_sync.js +++ b/fluent-sequence/src/map_sync.js @@ -1,28 +1,28 @@ /* * Synchronously map an identifier or an array of identifiers to the best - * `MessageContext` instance(s). + * `FluentBundle` instance(s). * * @param {Iterable} iterable * @param {string|Array} ids - * @returns {MessageContext|Array} + * @returns {FluentBundle|Array} */ -export default function mapContextSync(iterable, ids) { +export default function mapBundleSync(iterable, ids) { if (!Array.isArray(ids)) { - return getContextForId(iterable, ids); + return getBundleForId(iterable, ids); } return ids.map( - id => getContextForId(iterable, id) + id => getBundleForId(iterable, id) ); } /* - * Find the best `MessageContext` with the translation for `id`. + * Find the best `FluentBundle` with the translation for `id`. */ -function getContextForId(iterable, id) { - for (const context of iterable) { - if (context.hasMessage(id)) { - return context; +function getBundleForId(iterable, id) { + for (const bundle of iterable) { + if (bundle.hasMessage(id)) { + return bundle; } } diff --git a/fluent-sequence/test/message_context_stub.js b/fluent-sequence/test/bundle_stub.js similarity index 86% rename from fluent-sequence/test/message_context_stub.js rename to fluent-sequence/test/bundle_stub.js index 3b1097c7f..0eca6671d 100644 --- a/fluent-sequence/test/message_context_stub.js +++ b/fluent-sequence/test/bundle_stub.js @@ -1,4 +1,4 @@ -export default class MessageContext { +export default class BundleStub { _setMessages(ids) { this.ids = ids; } diff --git a/fluent-sequence/test/fallback_async_test.js b/fluent-sequence/test/fallback_async_test.js index 4317cf8fb..caf1c68da 100644 --- a/fluent-sequence/test/fallback_async_test.js +++ b/fluent-sequence/test/fallback_async_test.js @@ -1,121 +1,121 @@ import assert from 'assert'; import {CachedAsyncIterable} from 'cached-iterable'; -import MessageContext from './message_context_stub'; -import {mapContextAsync} from '../src/index'; +import FluentBundle from './bundle_stub'; +import {mapBundleAsync} from '../src/index'; suite('Async Fallback — single id', function() { - let ctx1, ctx2, generateMessages; + let bundle1, bundle2, generateBundles; suiteSetup(function() { - ctx1 = new MessageContext(); - ctx1._setMessages(['bar']); - ctx2 = new MessageContext(); - ctx2._setMessages(['foo', 'bar']); + bundle1 = new FluentBundle(); + bundle1._setMessages(['bar']); + bundle2 = new FluentBundle(); + bundle2._setMessages(['foo', 'bar']); - generateMessages = async function *generateMessages() { - yield *[ctx1, ctx2]; + generateBundles = async function *generateBundles() { + yield *[bundle1, bundle2]; } }); test('eager iterable', async function() { - const contexts = new CachedAsyncIterable(generateMessages()); - assert.equal(await mapContextAsync(contexts, 'foo'), ctx2); - assert.equal(await mapContextAsync(contexts, 'bar'), ctx1); + const bundles = new CachedAsyncIterable(generateBundles()); + assert.equal(await mapBundleAsync(bundles, 'foo'), bundle2); + assert.equal(await mapBundleAsync(bundles, 'bar'), bundle1); }); test('eager iterable works more than once', async function() { - const contexts = new CachedAsyncIterable(generateMessages()); - assert.equal(await mapContextAsync(contexts, 'foo'), ctx2); - assert.equal(await mapContextAsync(contexts, 'bar'), ctx1); - assert.equal(await mapContextAsync(contexts, 'foo'), ctx2); - assert.equal(await mapContextAsync(contexts, 'bar'), ctx1); + const bundles = new CachedAsyncIterable(generateBundles()); + assert.equal(await mapBundleAsync(bundles, 'foo'), bundle2); + assert.equal(await mapBundleAsync(bundles, 'bar'), bundle1); + assert.equal(await mapBundleAsync(bundles, 'foo'), bundle2); + assert.equal(await mapBundleAsync(bundles, 'bar'), bundle1); }); test('lazy iterable', async function() { - const contexts = new CachedAsyncIterable(generateMessages()); - assert.equal(await mapContextAsync(contexts, 'foo'), ctx2); - assert.equal(await mapContextAsync(contexts, 'bar'), ctx1); + const bundles = new CachedAsyncIterable(generateBundles()); + assert.equal(await mapBundleAsync(bundles, 'foo'), bundle2); + assert.equal(await mapBundleAsync(bundles, 'bar'), bundle1); }); test('lazy iterable works more than once', async function() { - const contexts = new CachedAsyncIterable(generateMessages()); - assert.equal(await mapContextAsync(contexts, 'foo'), ctx2); - assert.equal(await mapContextAsync(contexts, 'bar'), ctx1); - assert.equal(await mapContextAsync(contexts, 'foo'), ctx2); - assert.equal(await mapContextAsync(contexts, 'bar'), ctx1); + const bundles = new CachedAsyncIterable(generateBundles()); + assert.equal(await mapBundleAsync(bundles, 'foo'), bundle2); + assert.equal(await mapBundleAsync(bundles, 'bar'), bundle1); + assert.equal(await mapBundleAsync(bundles, 'foo'), bundle2); + assert.equal(await mapBundleAsync(bundles, 'bar'), bundle1); }); }); suite('Async Fallback — multiple ids', async function() { - let ctx1, ctx2, generateMessages; + let bundle1, bundle2, generateBundles; suiteSetup(function() { - ctx1 = new MessageContext(); - ctx1._setMessages(['foo', 'bar']); - ctx2 = new MessageContext(); - ctx2._setMessages(['foo', 'bar', 'baz']); + bundle1 = new FluentBundle(); + bundle1._setMessages(['foo', 'bar']); + bundle2 = new FluentBundle(); + bundle2._setMessages(['foo', 'bar', 'baz']); - generateMessages = async function *generateMessages() { - yield *[ctx1, ctx2]; + generateBundles = async function *generateBundles() { + yield *[bundle1, bundle2]; } }); test('existing translations', async function() { - const contexts = new CachedAsyncIterable(generateMessages()); + const bundles = new CachedAsyncIterable(generateBundles()); assert.deepEqual( - await mapContextAsync(contexts, ['foo', 'bar']), - [ctx1, ctx1] + await mapBundleAsync(bundles, ['foo', 'bar']), + [bundle1, bundle1] ); }); test('fallback translations', async function() { - const contexts = new CachedAsyncIterable(generateMessages()); + const bundles = new CachedAsyncIterable(generateBundles()); assert.deepEqual( - await mapContextAsync(contexts, ['foo', 'bar', 'baz']), - [ctx1, ctx1, ctx2] + await mapBundleAsync(bundles, ['foo', 'bar', 'baz']), + [bundle1, bundle1, bundle2] ); }); test('missing translations', async function() { - const contexts = new CachedAsyncIterable(generateMessages()); + const bundles = new CachedAsyncIterable(generateBundles()); assert.deepEqual( - await mapContextAsync(contexts, ['foo', 'bar', 'baz', 'qux']), - [ctx1, ctx1, ctx2, null] + await mapBundleAsync(bundles, ['foo', 'bar', 'baz', 'qux']), + [bundle1, bundle1, bundle2, null] ); }); }); suite('Async Fallback — early return', async function() { - let ctx1, ctx2; + let bundle1, bundle2; suiteSetup(function() { - ctx1 = new MessageContext(); - ctx1._setMessages(['foo', 'bar']); - ctx2 = new MessageContext(); - ctx2._setMessages(['foo', 'bar', 'baz']); + bundle1 = new FluentBundle(); + bundle1._setMessages(['foo', 'bar']); + bundle2 = new FluentBundle(); + bundle2._setMessages(['foo', 'bar', 'baz']); }); test('break early if possible', async function() { - const contexts = [ctx1, ctx2].values(); + const bundles = [bundle1, bundle2].values(); assert.deepEqual( - await mapContextAsync(contexts, ['foo', 'bar']), - [ctx1, ctx1] + await mapBundleAsync(bundles, ['foo', 'bar']), + [bundle1, bundle1] ); assert.deepEqual( - contexts.next(), - {value: ctx2, done: false} + bundles.next(), + {value: bundle2, done: false} ); }); - test('iterate over all contexts', async function() { - const contexts = [ctx1, ctx2].values(); + test('iterate over all bundles', async function() { + const bundles = [bundle1, bundle2].values(); assert.deepEqual( - await mapContextAsync(contexts, ['foo', 'bar', 'baz']), - [ctx1, ctx1, ctx2] + await mapBundleAsync(bundles, ['foo', 'bar', 'baz']), + [bundle1, bundle1, bundle2] ); assert.deepEqual( - contexts.next(), + bundles.next(), {value: undefined, done: true} ); }); diff --git a/fluent-sequence/test/fallback_sync_test.js b/fluent-sequence/test/fallback_sync_test.js index 34e774b91..4416ef876 100644 --- a/fluent-sequence/test/fallback_sync_test.js +++ b/fluent-sequence/test/fallback_sync_test.js @@ -1,87 +1,87 @@ import assert from 'assert'; import {CachedSyncIterable} from 'cached-iterable'; -import MessageContext from './message_context_stub'; -import {mapContextSync} from '../src/index'; +import FluentBundle from './bundle_stub'; +import {mapBundleSync} from '../src/index'; suite('Sync Fallback — single id', function() { - let ctx1, ctx2; + let bundle1, bundle2; suiteSetup(function() { - ctx1 = new MessageContext(); - ctx1._setMessages(['bar']); - ctx2 = new MessageContext(); - ctx2._setMessages(['foo', 'bar']); + bundle1 = new FluentBundle(); + bundle1._setMessages(['bar']); + bundle2 = new FluentBundle(); + bundle2._setMessages(['foo', 'bar']); }); test('eager iterable', function() { - const contexts = new CachedSyncIterable([ctx1, ctx2]); - assert.equal(mapContextSync(contexts, 'foo'), ctx2); - assert.equal(mapContextSync(contexts, 'bar'), ctx1); + const bundles = new CachedSyncIterable([bundle1, bundle2]); + assert.equal(mapBundleSync(bundles, 'foo'), bundle2); + assert.equal(mapBundleSync(bundles, 'bar'), bundle1); }); test('eager iterable works more than once', function() { - const contexts = new CachedSyncIterable([ctx1, ctx2]); - assert.equal(mapContextSync(contexts, 'foo'), ctx2); - assert.equal(mapContextSync(contexts, 'bar'), ctx1); - assert.equal(mapContextSync(contexts, 'foo'), ctx2); - assert.equal(mapContextSync(contexts, 'bar'), ctx1); + const bundles = new CachedSyncIterable([bundle1, bundle2]); + assert.equal(mapBundleSync(bundles, 'foo'), bundle2); + assert.equal(mapBundleSync(bundles, 'bar'), bundle1); + assert.equal(mapBundleSync(bundles, 'foo'), bundle2); + assert.equal(mapBundleSync(bundles, 'bar'), bundle1); }); test('lazy iterable', function() { - function *generateMessages() { - yield *[ctx1, ctx2]; + function *generateBundles() { + yield *[bundle1, bundle2]; } - const contexts = new CachedSyncIterable(generateMessages()); - assert.equal(mapContextSync(contexts, 'foo'), ctx2); - assert.equal(mapContextSync(contexts, 'bar'), ctx1); + const bundles = new CachedSyncIterable(generateBundles()); + assert.equal(mapBundleSync(bundles, 'foo'), bundle2); + assert.equal(mapBundleSync(bundles, 'bar'), bundle1); }); test('lazy iterable works more than once', function() { - function *generateMessages() { - yield *[ctx1, ctx2]; + function *generateBundles() { + yield *[bundle1, bundle2]; } - const contexts = new CachedSyncIterable(generateMessages()); - assert.equal(mapContextSync(contexts, 'foo'), ctx2); - assert.equal(mapContextSync(contexts, 'bar'), ctx1); - assert.equal(mapContextSync(contexts, 'foo'), ctx2); - assert.equal(mapContextSync(contexts, 'bar'), ctx1); + const bundles = new CachedSyncIterable(generateBundles()); + assert.equal(mapBundleSync(bundles, 'foo'), bundle2); + assert.equal(mapBundleSync(bundles, 'bar'), bundle1); + assert.equal(mapBundleSync(bundles, 'foo'), bundle2); + assert.equal(mapBundleSync(bundles, 'bar'), bundle1); }); }); suite('Sync Fallback — multiple ids', function() { - let ctx1, ctx2; + let bundle1, bundle2; suiteSetup(function() { - ctx1 = new MessageContext(); - ctx1._setMessages(['foo', 'bar']); - ctx2 = new MessageContext(); - ctx2._setMessages(['foo', 'bar', 'baz']); + bundle1 = new FluentBundle(); + bundle1._setMessages(['foo', 'bar']); + bundle2 = new FluentBundle(); + bundle2._setMessages(['foo', 'bar', 'baz']); }); test('existing translations', function() { - const contexts = new CachedSyncIterable([ctx1, ctx2]); + const bundles = new CachedSyncIterable([bundle1, bundle2]); assert.deepEqual( - mapContextSync(contexts, ['foo', 'bar']), - [ctx1, ctx1] + mapBundleSync(bundles, ['foo', 'bar']), + [bundle1, bundle1] ); }); test('fallback translations', function() { - const contexts = new CachedSyncIterable([ctx1, ctx2]); + const bundles = new CachedSyncIterable([bundle1, bundle2]); assert.deepEqual( - mapContextSync(contexts, ['foo', 'bar', 'baz']), - [ctx1, ctx1, ctx2] + mapBundleSync(bundles, ['foo', 'bar', 'baz']), + [bundle1, bundle1, bundle2] ); }); test('missing translations', function() { - const contexts = new CachedSyncIterable([ctx1, ctx2]); + const bundles = new CachedSyncIterable([bundle1, bundle2]); assert.deepEqual( - mapContextSync(contexts, ['foo', 'bar', 'baz', 'qux']), - [ctx1, ctx1, ctx2, null] + mapBundleSync(bundles, ['foo', 'bar', 'baz', 'qux']), + [bundle1, bundle1, bundle2, null] ); }); }); diff --git a/fluent/CHANGELOG.md b/fluent/CHANGELOG.md index e668bae6c..ac331ea8c 100644 --- a/fluent/CHANGELOG.md +++ b/fluent/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased + - Rename `MessageContext` to `FluentBundle`. (#222) + + Also, export `FluentType` and its derived classes under their own names + rather than `MessageArgument` etc. + - Move `mapContext*` functions to `fluent-sequence`. (#273) The `mapContextSync` and `mapContextAsync` functions previously exported @@ -9,6 +14,9 @@ package. `fluent-sequence` 0.1.0 corresponds to the exact implementation of these functions from `fluent` 0.7.0. + In later versions of `fluent-sequence`, these functions are called + `mapBundleSync` and `mapBundleAsync`. + ## fluent 0.7.0 (July 24, 2018) - Implement support for Fluent Syntax 0.6. @@ -91,14 +99,14 @@ ```js async formatString(id, args) { - const ctx = await mapContextAsync(contexts, id); + const bundle = await mapContextAsync(bundles, id); - if (ctx === null) { + if (bundle === null) { return id; } - const msg = ctx.getMessage(id); - return ctx.format(msg, args); + const msg = bundle.getMessage(id); + return bundle.format(msg, args); } ``` @@ -118,7 +126,7 @@ indentation. ```js - ctx.addMessages(ftl` + bundle.addMessages(ftl` foo = Foo bar = Bar ); @@ -178,14 +186,14 @@ might be implemented as follows: getString(id, args) { - const ctx = mapContextSync(contexts, id); + const bundle = mapContextSync(bundles, id); - if (ctx === null) { + if (bundle === null) { return id; } - const msg = ctx.getMessage(id); - return ctx.format(msg, args); + const msg = bundle.getMessage(id); + return bundle.format(msg, args); } In order to pass an iterator to mapContext*, wrap it in CachedIterable. @@ -194,11 +202,11 @@ function *generateMessages() { // Some lazy logic for yielding MessageContexts. - yield *[ctx1, ctx2]; + yield *[bundle1, bundle2]; } - const contexts = new CachedIterable(generateMessages()); - const ctx = mapContextSync(contexts, id); + const bundles = new CachedIterable(generateMessages()); + const bundle = mapContextSync(bundles, id); ## fluent 0.4.0 (May 17th, 2017) @@ -211,13 +219,13 @@ Before: - const msg = ctx.messages.get(id); - const txt = ctx.format(msg); + const msg = bundle.messages.get(id); + const txt = bundle.format(msg); Now: - const msg = ctx.getMessage(id); - const txt = ctx.format(msg); + const msg = bundle.getMessage(id); + const txt = bundle.format(msg); - The compat build is now transpiled using rollup-plugin-babel. diff --git a/fluent/README.md b/fluent/README.md index d28391f9e..e90ec5229 100644 --- a/fluent/README.md +++ b/fluent/README.md @@ -15,15 +15,15 @@ install it from the npm registry or use it as a standalone script (as the ## How to use -The `MessageContext` constructor provides the core functionality of formatting +The `FluentBundle` constructor provides the core functionality of formatting translations from FTL files. ```javascript -import { MessageContext, ftl } from 'fluent'; +import { FluentBundle, ftl } from 'fluent'; -const ctx = new MessageContext('en-US'); +const bundle = new FluentBundle('en-US'); -const errors = ctx.addMessages(ftl` +const errors = bundle.addMessages(ftl` -brand-name = Foo 3000 welcome = Welcome, { $name }, to { -brand-name }! `); @@ -32,9 +32,9 @@ if (errors.length) { // syntax errors are per-message and don't break the whole resource } -const welcome = ctx.getMessage('welcome'); +const welcome = bundle.getMessage('welcome'); -ctx.format(welcome, { name: 'Anna' }); +bundle.format(welcome, { name: 'Anna' }); // → 'Welcome, Anna, to Foo 3000!' ``` @@ -55,14 +55,14 @@ which uses [intl-pluralrules][]. ```javascript import 'fluent-intl-polyfill'; -import { MessageContext } from 'fluent'; +import { FluentBundle } from 'fluent'; ``` For legacy browsers, the `compat` build has been transpiled using Babel's [env preset][]. It requires the regenerator runtime provided by [babel-polyfill][]. ```javascript -import { MessageContext } from 'fluent/compat'; +import { FluentBundle } from 'fluent/compat'; ``` diff --git a/fluent/src/context.js b/fluent/src/context.js index f349a14e0..ffcc100cf 100644 --- a/fluent/src/context.js +++ b/fluent/src/context.js @@ -2,11 +2,11 @@ import resolve from "./resolver"; import FluentResource from "./resource"; /** - * Message contexts are single-language stores of translations. They are + * Message bundles are single-language stores of translations. They are * responsible for parsing translation resources in the Fluent syntax and can * format translation units (entities) to strings. * - * Always use `MessageContext.format` to retrieve translation units from a + * Always use `FluentBundle.format` to retrieve translation units from a * context. Translations can contain references to other entities or variables, * conditional logic in form of select expressions, traits which describe their * grammatical features, and can use Fluent builtins which make use of the @@ -14,21 +14,21 @@ import FluentResource from "./resource"; * context's language. See the documentation of the Fluent syntax for more * information. */ -export class MessageContext { +export class FluentBundle { /** - * Create an instance of `MessageContext`. + * Create an instance of `FluentBundle`. * * The `locales` argument is used to instantiate `Intl` formatters used by * translations. The `options` object can be used to configure the context. * * Examples: * - * const ctx = new MessageContext(locales); + * const bundle = new FluentBundle(locales); * - * const ctx = new MessageContext(locales, { useIsolating: false }); + * const bundle = new FluentBundle(locales, { useIsolating: false }); * - * const ctx = new MessageContext(locales, { + * const bundle = new FluentBundle(locales, { * useIsolating: true, * functions: { * NODE_ENV: () => process.env.NODE_ENV @@ -47,7 +47,7 @@ export class MessageContext { * * @param {string|Array} locales - Locale or locales of the context * @param {Object} [options] - * @returns {MessageContext} + * @returns {FluentBundle} */ constructor(locales, { functions = {}, @@ -87,7 +87,7 @@ export class MessageContext { * Return the internal representation of a message. * * The internal representation should only be used as an argument to - * `MessageContext.format`. + * `FluentBundle.format`. * * @param {string} id - The identifier of the message to check. * @returns {Any} @@ -103,8 +103,8 @@ export class MessageContext { * the context and each translation unit (message) will be available in the * context by its identifier. * - * ctx.addMessages('foo = Foo'); - * ctx.getMessage('foo'); + * bundle.addMessages('foo = Foo'); + * bundle.getMessage('foo'); * * // Returns a raw representation of the 'foo' message. * @@ -123,11 +123,11 @@ export class MessageContext { * Add a translation resource to the context. * * The translation resource must be a proper FluentResource - * parsed by `MessageContext.parseResource`. + * parsed by `FluentBundle.parseResource`. * - * let res = MessageContext.parseResource("foo = Foo"); - * ctx.addResource(res); - * ctx.getMessage('foo'); + * let res = FluentBundle.parseResource("foo = Foo"); + * bundle.addResource(res); + * bundle.getMessage('foo'); * * // Returns a raw representation of the 'foo' message. * @@ -142,7 +142,7 @@ export class MessageContext { for (const [id, value] of res) { if (id.startsWith("-")) { // Identifiers starting with a dash (-) define terms. Terms are private - // and cannot be retrieved from MessageContext. + // and cannot be retrieved from FluentBundle. if (this._terms.has(id)) { errors.push(`Attempt to override an existing term: "${id}"`); continue; @@ -173,13 +173,13 @@ export class MessageContext { * `errors` array passed as the third argument. * * const errors = []; - * ctx.addMessages('hello = Hello, { $name }!'); - * const hello = ctx.getMessage('hello'); - * ctx.format(hello, { name: 'Jane' }, errors); + * bundle.addMessages('hello = Hello, { $name }!'); + * const hello = bundle.getMessage('hello'); + * bundle.format(hello, { name: 'Jane' }, errors); * * // Returns 'Hello, Jane!' and `errors` is empty. * - * ctx.format(hello, undefined, errors); + * bundle.format(hello, undefined, errors); * * // Returns 'Hello, name!' and `errors` is now: * diff --git a/fluent/src/index.js b/fluent/src/index.js index 6430c0c16..911ed60e7 100644 --- a/fluent/src/index.js +++ b/fluent/src/index.js @@ -9,11 +9,7 @@ export { default as _parse } from "./parser"; -export { MessageContext } from "./context"; -export { - FluentType as MessageArgument, - FluentNumber as MessageNumberArgument, - FluentDateTime as MessageDateTimeArgument, -} from "./types"; +export { FluentBundle } from "./context"; +export { FluentType, FluentNumber, FluentDateTime } from "./types"; export { ftl } from "./util"; diff --git a/fluent/src/parser.js b/fluent/src/parser.js index d2e51dc18..456057661 100644 --- a/fluent/src/parser.js +++ b/fluent/src/parser.js @@ -24,10 +24,10 @@ const trailingWSRe = /[ \t\n\r]+$/; */ class RuntimeParser { /** - * Parse FTL code into entries formattable by the MessageContext. + * Parse FTL code into entries formattable by the FluentBundle. * * Given a string of FTL syntax, return a map of entries that can be passed - * to MessageContext.format and a list of errors encountered during parsing. + * to FluentBundle.format and a list of errors encountered during parsing. * * @param {String} string * @returns {Array} diff --git a/fluent/src/resolver.js b/fluent/src/resolver.js index b5c462714..0a844cdbb 100644 --- a/fluent/src/resolver.js +++ b/fluent/src/resolver.js @@ -35,7 +35,7 @@ * All functions in this file pass around a special object called `env`. * This object stores a set of elements used by all resolve functions: * - * * {MessageContext} ctx + * * {FluentBundle} bundle * context for which the given resolution is happening * * {Object} args * list of developer provided arguments that can be used @@ -97,10 +97,10 @@ function DefaultMember(env, members, def) { * @private */ function MessageReference(env, {name}) { - const { ctx, errors } = env; + const { bundle, errors } = env; const message = name.startsWith("-") - ? ctx._terms.get(name) - : ctx._messages.get(name); + ? bundle._terms.get(name) + : bundle._messages.get(name); if (!message) { const err = name.startsWith("-") @@ -135,7 +135,7 @@ function VariantExpression(env, {id, key}) { return message; } - const { ctx, errors } = env; + const { bundle, errors } = env; const keyword = Type(env, key); function isVariantList(node) { @@ -148,13 +148,14 @@ function VariantExpression(env, {id, key}) { // Match the specified key against keys of each variant, in order. for (const variant of message.val[0].vars) { const variantKey = Type(env, variant.key); - if (keyword.match(ctx, variantKey)) { + if (keyword.match(bundle, variantKey)) { return variant; } } } - errors.push(new ReferenceError(`Unknown variant: ${keyword.toString(ctx)}`)); + errors.push( + new ReferenceError(`Unknown variant: ${keyword.toString(bundle)}`)); return Type(env, message); } @@ -229,9 +230,9 @@ function SelectExpression(env, {exp, vars, def}) { continue; } - const { ctx } = env; + const { bundle } = env; - if (key.match(ctx, selector)) { + if (key.match(bundle, selector)) { return variant; } } @@ -258,7 +259,7 @@ function Type(env, expr) { // A fast-path for strings which are the most common case, and for // `FluentNone` which doesn't require any additional logic. if (typeof expr === "string") { - return env.ctx._transform(expr); + return env.bundle._transform(expr); } if (expr instanceof FluentNone) { return expr; @@ -372,8 +373,8 @@ function VariableReference(env, {name}) { */ function FunctionReference(env, {name}) { // Some functions are built-in. Others may be provided by the runtime via - // the `MessageContext` constructor. - const { ctx: { _functions }, errors } = env; + // the `FluentBundle` constructor. + const { bundle: { _functions }, errors } = env; const func = _functions[name] || builtins[name]; if (!func) { @@ -440,7 +441,7 @@ function CallExpression(env, {fun, args}) { * @private */ function Pattern(env, ptn) { - const { ctx, dirty, errors } = env; + const { bundle, dirty, errors } = env; if (dirty.has(ptn)) { errors.push(new RangeError("Cyclic reference")); @@ -453,15 +454,15 @@ function Pattern(env, ptn) { // Wrap interpolations with Directional Isolate Formatting characters // only when the pattern has more than one element. - const useIsolating = ctx._useIsolating && ptn.length > 1; + const useIsolating = bundle._useIsolating && ptn.length > 1; for (const elem of ptn) { if (typeof elem === "string") { - result.push(ctx._transform(elem)); + result.push(bundle._transform(elem)); continue; } - const part = Type(env, elem).toString(ctx); + const part = Type(env, elem).toString(bundle); if (useIsolating) { result.push(FSI); @@ -491,8 +492,8 @@ function Pattern(env, ptn) { /** * Format a translation into a string. * - * @param {MessageContext} ctx - * A MessageContext instance which will be used to resolve the + * @param {FluentBundle} bundle + * A FluentBundle instance which will be used to resolve the * contextual information of the message. * @param {Object} args * List of arguments provided by the developer which can be accessed @@ -503,9 +504,9 @@ function Pattern(env, ptn) { * An error array that any encountered errors will be appended to. * @returns {FluentType} */ -export default function resolve(ctx, args, message, errors = []) { +export default function resolve(bundle, args, message, errors = []) { const env = { - ctx, args, errors, dirty: new WeakSet() + bundle, args, errors, dirty: new WeakSet() }; - return Type(env, message).toString(ctx); + return Type(env, message).toString(bundle); } diff --git a/fluent/src/types.js b/fluent/src/types.js index 39dde7aae..4077a41ca 100644 --- a/fluent/src/types.js +++ b/fluent/src/types.js @@ -33,11 +33,11 @@ export class FluentType { /** * Format this instance of `FluentType` to a string. * - * Formatted values are suitable for use outside of the `MessageContext`. - * This method can use `Intl` formatters memoized by the `MessageContext` + * Formatted values are suitable for use outside of the `FluentBundle`. + * This method can use `Intl` formatters memoized by the `FluentBundle` * instance passed as an argument. * - * @param {MessageContext} [ctx] + * @param {FluentBundle} [bundle] * @returns {string} */ toString() { @@ -56,9 +56,9 @@ export class FluentNumber extends FluentType { super(parseFloat(value), opts); } - toString(ctx) { + toString(bundle) { try { - const nf = ctx._memoizeIntlObject( + const nf = bundle._memoizeIntlObject( Intl.NumberFormat, this.opts ); return nf.format(this.value); @@ -71,11 +71,11 @@ export class FluentNumber extends FluentType { /** * Compare the object with another instance of a FluentType. * - * @param {MessageContext} ctx + * @param {FluentBundle} bundle * @param {FluentType} other * @returns {bool} */ - match(ctx, other) { + match(bundle, other) { if (other instanceof FluentNumber) { return this.value === other.value; } @@ -88,9 +88,9 @@ export class FluentDateTime extends FluentType { super(new Date(value), opts); } - toString(ctx) { + toString(bundle) { try { - const dtf = ctx._memoizeIntlObject( + const dtf = bundle._memoizeIntlObject( Intl.DateTimeFormat, this.opts ); return dtf.format(this.value); @@ -109,17 +109,17 @@ export class FluentSymbol extends FluentType { /** * Compare the object with another instance of a FluentType. * - * @param {MessageContext} ctx + * @param {FluentBundle} bundle * @param {FluentType} other * @returns {bool} */ - match(ctx, other) { + match(bundle, other) { if (other instanceof FluentSymbol) { return this.value === other.value; } else if (typeof other === "string") { return this.value === other; } else if (other instanceof FluentNumber) { - const pr = ctx._memoizeIntlObject( + const pr = bundle._memoizeIntlObject( Intl.PluralRules, other.opts ); return this.value === pr.select(other.value); diff --git a/fluent/test/arguments_test.js b/fluent/test/arguments_test.js index 1bc8aadbf..222c12b25 100644 --- a/fluent/test/arguments_test.js +++ b/fluent/test/arguments_test.js @@ -2,12 +2,12 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { FluentType } from '../src/types'; import { ftl } from '../src/util'; suite('Variables', function() { - let ctx, errs; + let bundle, errs; setup(function() { errs = []; @@ -15,8 +15,8 @@ suite('Variables', function() { suite('in values', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo { $num } bar = { foo } baz = @@ -28,29 +28,29 @@ suite('Variables', function() { }); test('can be used in the message value', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, { num: 3 }, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, { num: 3 }, errs); assert.equal(val, 'Foo 3'); assert.equal(errs.length, 0); }); test('can be used in the message value which is referenced', function() { - const msg = ctx.getMessage('bar'); - const val = ctx.format(msg, { num: 3 }, errs); + const msg = bundle.getMessage('bar'); + const val = bundle.format(msg, { num: 3 }, errs); assert.equal(val, 'Foo 3'); assert.equal(errs.length, 0); }); test('can be used in an attribute', function() { - const msg = ctx.getMessage('baz').attrs.attr; - const val = ctx.format(msg, { num: 3 }, errs); + const msg = bundle.getMessage('baz').attrs.attr; + const val = bundle.format(msg, { num: 3 }, errs); assert.equal(val, 'Baz Attribute 3'); assert.equal(errs.length, 0); }); test('can be used in a variant', function() { - const msg = ctx.getMessage('qux'); - const val = ctx.format(msg, { num: 3 }, errs); + const msg = bundle.getMessage('qux'); + const val = bundle.format(msg, { num: 3 }, errs); assert.equal(val, 'Baz Variant A 3'); assert.equal(errs.length, 0); }); @@ -58,8 +58,8 @@ suite('Variables', function() { suite('in selectors', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { $num -> *[3] Foo } @@ -67,8 +67,8 @@ suite('Variables', function() { }); test('can be used as a selector', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, { num: 3 }, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, { num: 3 }, errs); assert.equal(val, 'Foo'); assert.equal(errs.length, 0); }); @@ -76,15 +76,15 @@ suite('Variables', function() { suite('in function calls', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { NUMBER($num) } `); }); test('can be a positional argument', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, { num: 3 }, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, { num: 3 }, errs); assert.equal(val, '3'); assert.equal(errs.length, 0); }); @@ -92,57 +92,57 @@ suite('Variables', function() { suite('simple errors', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { $arg } `); }); test('falls back to argument\'s name if it\'s missing', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, {}, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, {}, errs); assert.equal(val, 'arg'); assert(errs[0] instanceof ReferenceError); // unknown variable }); test('cannot be arrays', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, { arg: [1, 2, 3] }, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, { arg: [1, 2, 3] }, errs); assert.equal(val, 'arg'); assert(errs[0] instanceof TypeError); // unsupported variable type }); test('cannot be a dict-like object', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, { arg: { prop: 1 } }, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, { arg: { prop: 1 } }, errs); assert.equal(val, 'arg'); assert(errs[0] instanceof TypeError); // unsupported variable type }); test('cannot be a boolean', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, { arg: true }, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, { arg: true }, errs); assert.equal(val, 'arg'); assert(errs[0] instanceof TypeError); // unsupported variable type }); test('cannot be undefined', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, { arg: undefined }, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, { arg: undefined }, errs); assert.equal(val, 'arg'); assert(errs[0] instanceof TypeError); // unsupported variable type }); test('cannot be null', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, { arg: null }, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, { arg: null }, errs); assert.equal(val, 'arg'); assert(errs[0] instanceof TypeError); // unsupported variable type }); test('cannot be a function', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, { arg: () => null }, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, { arg: () => null }, errs); assert.equal(val, 'arg'); assert(errs[0] instanceof TypeError); // unsupported variable type }); @@ -152,8 +152,8 @@ suite('Variables', function() { let args; suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { $arg } `); args = { @@ -162,8 +162,8 @@ suite('Variables', function() { }); test('can be a string', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Argument'); assert.equal(errs.length, 0); }); @@ -173,8 +173,8 @@ suite('Variables', function() { let args; suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { $arg } `); args = { @@ -183,8 +183,8 @@ suite('Variables', function() { }); test('can be a number', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, '1'); assert.equal(errs.length, 0); }); @@ -195,8 +195,8 @@ suite('Variables', function() { suiteSetup(function() { dtf = new Intl.DateTimeFormat('en-US'); - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { $arg } `); args = { @@ -205,8 +205,8 @@ suite('Variables', function() { }); test('can be a date', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); // format the date argument to account for the testrunner's timezone assert.equal(val, dtf.format(args.arg)); assert.equal(errs.length, 0); @@ -223,8 +223,8 @@ suite('Variables', function() { } suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { $arg } bar = { foo } `); @@ -235,15 +235,15 @@ suite('Variables', function() { }; test('interpolation', function () { - const msg = ctx.getMessage('foo'); - const value = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const value = bundle.format(msg, args, errs); assert.equal(value, 'CUSTOM'); assert.equal(errs.length, 0); }); test('nested interpolation', function () { - const msg = ctx.getMessage('bar'); - const value = ctx.format(msg, args, errs); + const msg = bundle.getMessage('bar'); + const value = bundle.format(msg, args, errs); assert.equal(value, 'CUSTOM'); assert.equal(errs.length, 0); }); diff --git a/fluent/test/attributes_test.js b/fluent/test/attributes_test.js index d2a571ee9..5ac5c84b6 100644 --- a/fluent/test/attributes_test.js +++ b/fluent/test/attributes_test.js @@ -2,11 +2,11 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; suite('Attributes', function() { - let ctx, args, errs; + let bundle, args, errs; setup(function() { errs = []; @@ -14,8 +14,8 @@ suite('Attributes', function() { suite('missing', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo bar = Bar .attr = Bar Attribute @@ -31,32 +31,32 @@ suite('Attributes', function() { }); test('falls back gracefully for entities with string values and no attributes', function() { - const msg = ctx.getMessage('ref-foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo'); assert.equal(errs.length, 1); assert(errs[0] instanceof ReferenceError); // unknown attribute }); test('falls back gracefully for entities with string values and other attributes', function() { - const msg = ctx.getMessage('ref-bar'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-bar'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Bar'); assert.equal(errs.length, 1); assert(errs[0] instanceof ReferenceError); // unknown attribute }); test('falls back gracefully for entities with pattern values and no attributes', function() { - const msg = ctx.getMessage('ref-baz'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-baz'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Baz'); assert.equal(errs.length, 1); assert(errs[0] instanceof ReferenceError); // unknown attribute }); test('falls back gracefully for entities with pattern values and other attributes', function() { - const msg = ctx.getMessage('ref-qux'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-qux'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Qux'); assert.equal(errs.length, 1); assert(errs[0] instanceof ReferenceError); // unknown attribute @@ -65,8 +65,8 @@ suite('Attributes', function() { suite('with string values', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo .attr = Foo Attribute bar = { foo } Bar @@ -78,29 +78,29 @@ suite('Attributes', function() { }); test('can be referenced for entities with string values', function() { - const msg = ctx.getMessage('ref-foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Attribute'); assert.equal(errs.length, 0); }); test('can be formatted directly for entities with string values', function() { - const msg = ctx.getMessage('foo').attrs.attr; - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo').attrs.attr; + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Attribute'); assert.equal(errs.length, 0); }); test('can be referenced for entities with pattern values', function() { - const msg = ctx.getMessage('ref-bar'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-bar'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Bar Attribute'); assert.equal(errs.length, 0); }); test('can be formatted directly for entities with pattern values', function() { - const msg = ctx.getMessage('bar').attrs.attr; - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('bar').attrs.attr; + const val = bundle.format(msg, args, errs); assert.equal(val, 'Bar Attribute'); assert.equal(errs.length, 0); }); @@ -108,8 +108,8 @@ suite('Attributes', function() { suite('with simple pattern values', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo bar = Bar .attr = { foo } Attribute @@ -125,43 +125,43 @@ suite('Attributes', function() { }); test('can be referenced for entities with string values', function() { - const msg = ctx.getMessage('ref-bar'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-bar'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Attribute'); assert.equal(errs.length, 0); }); test('can be formatted directly for entities with string values', function() { - const msg = ctx.getMessage('bar').attrs.attr; - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('bar').attrs.attr; + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Attribute'); assert.equal(errs.length, 0); }); test('can be referenced for entities with simple pattern values', function() { - const msg = ctx.getMessage('ref-baz'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-baz'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Attribute'); assert.equal(errs.length, 0); }); test('can be formatted directly for entities with simple pattern values', function() { - const msg = ctx.getMessage('baz').attrs.attr; - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('baz').attrs.attr; + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Attribute'); assert.equal(errs.length, 0); }); test('works with self-references', function() { - const msg = ctx.getMessage('ref-qux'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-qux'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Qux Attribute'); assert.equal(errs.length, 0); }); test('can be formatted directly when it uses a self-reference', function() { - const msg = ctx.getMessage('qux').attrs.attr; - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('qux').attrs.attr; + const val = bundle.format(msg, args, errs); assert.equal(val, 'Qux Attribute'); assert.equal(errs.length, 0); }); @@ -169,8 +169,8 @@ suite('Attributes', function() { suite('with values with select expressions', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo .attr = { "a" -> [a] A @@ -182,15 +182,15 @@ suite('Attributes', function() { }); test('can be referenced', function() { - const msg = ctx.getMessage('ref-foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'A'); assert.equal(errs.length, 0); }); test('can be formatted directly', function() { - const msg = ctx.getMessage('foo').attrs.attr; - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo').attrs.attr; + const val = bundle.format(msg, args, errs); assert.equal(val, 'A'); assert.equal(errs.length, 0); }); diff --git a/fluent/test/bomb_test.js b/fluent/test/bomb_test.js index fe00da488..0ddacbad2 100644 --- a/fluent/test/bomb_test.js +++ b/fluent/test/bomb_test.js @@ -2,11 +2,11 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; suite('Reference bombs', function() { - let ctx, args, errs; + let bundle, args, errs; setup(function() { errs = []; @@ -14,8 +14,8 @@ suite('Reference bombs', function() { suite('Billion Laughs', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` lol0 = LOL lol1 = {lol0} {lol0} {lol0} {lol0} {lol0} {lol0} {lol0} {lol0} {lol0} {lol0} lol2 = {lol1} {lol1} {lol1} {lol1} {lol1} {lol1} {lol1} {lol1} {lol1} {lol1} @@ -33,8 +33,8 @@ suite('Reference bombs', function() { // XXX Protect the FTL Resolver against the billion laughs attack // https://bugzil.la/1307126 it.skip('does not expand all placeables', function() { - const msg = ctx.getMessage('lolz'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('lolz'); + const val = bundle.format(msg, args, errs); assert.equal(val, '???'); assert.equal(errs.length, 1); }); diff --git a/fluent/test/constructor_test.js b/fluent/test/constructor_test.js index 76a4860d5..33f439fad 100644 --- a/fluent/test/constructor_test.js +++ b/fluent/test/constructor_test.js @@ -3,10 +3,10 @@ import assert from 'assert'; import sinon from 'sinon'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; -suite('MessageContext constructor', function() { +suite('FluentBundle constructor', function() { setup(function() { this.nf = sinon.spy(Intl, 'NumberFormat'); }); @@ -17,13 +17,13 @@ suite('MessageContext constructor', function() { test('accepts a single locale string', function() { const errs = []; - const ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + const bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo { 1 } `); - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, null, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, null, errs); assert.equal(val, 'Foo 1'); assert.equal(errs.length, 0); @@ -34,13 +34,13 @@ suite('MessageContext constructor', function() { test('accepts an array of locales', function() { const errs = []; - const ctx = new MessageContext(['de', 'en-US'], { useIsolating: false }); - ctx.addMessages(ftl` + const bundle = new FluentBundle(['de', 'en-US'], { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo { 1 } `); - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, null, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, null, errs); assert.equal(val, 'Foo 1'); assert.equal(errs.length, 0); diff --git a/fluent/test/context_test.js b/fluent/test/context_test.js index faa9b75c1..7d4d1823f 100644 --- a/fluent/test/context_test.js +++ b/fluent/test/context_test.js @@ -2,11 +2,11 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; -suite('Context', function() { - let ctx, args, errs; +suite('Bundle', function() { + let bundle, args, errs; setup(function() { errs = []; @@ -14,57 +14,57 @@ suite('Context', function() { suite('addMessages', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo -bar = Private Bar `); }); test('adds messages', function() { - assert.equal(ctx._messages.has('foo'), true); - assert.equal(ctx._terms.has('foo'), false); - assert.equal(ctx._messages.has('-bar'), false); - assert.equal(ctx._terms.has('-bar'), true); + assert.equal(bundle._messages.has('foo'), true); + assert.equal(bundle._terms.has('foo'), false); + assert.equal(bundle._messages.has('-bar'), false); + assert.equal(bundle._terms.has('-bar'), true); }); test('preserves existing messages when new are added', function() { - ctx.addMessages(ftl` + bundle.addMessages(ftl` baz = Baz `); - assert.equal(ctx._messages.has('foo'), true); - assert.equal(ctx._terms.has('foo'), false); - assert.equal(ctx._messages.has('-bar'), false); - assert.equal(ctx._terms.has('-bar'), true); + assert.equal(bundle._messages.has('foo'), true); + assert.equal(bundle._terms.has('foo'), false); + assert.equal(bundle._messages.has('-bar'), false); + assert.equal(bundle._terms.has('-bar'), true); - assert.equal(ctx._messages.has('baz'), true); - assert.equal(ctx._terms.has('baz'), false); + assert.equal(bundle._messages.has('baz'), true); + assert.equal(bundle._terms.has('baz'), false); }); test('messages and terms can share the same name', function() { - ctx.addMessages(ftl` + bundle.addMessages(ftl` -foo = Private Foo `); - assert.equal(ctx._messages.has('foo'), true); - assert.equal(ctx._terms.has('foo'), false); - assert.equal(ctx._messages.has('-foo'), false); - assert.equal(ctx._terms.has('-foo'), true); + assert.equal(bundle._messages.has('foo'), true); + assert.equal(bundle._terms.has('foo'), false); + assert.equal(bundle._messages.has('-foo'), false); + assert.equal(bundle._terms.has('-foo'), true); }); test('does not overwrite existing messages if the ids are the same', function() { - const errors = ctx.addMessages(ftl` + const errors = bundle.addMessages(ftl` foo = New Foo `); // Attempt to overwrite error reported assert.equal(errors.length, 1); - assert.equal(ctx._messages.size, 2); + assert.equal(bundle._messages.size, 2); - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo'); assert.equal(errs.length, 0); }); @@ -72,41 +72,41 @@ suite('Context', function() { suite('hasMessage', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo -bar = Bar `); }); test('returns true only for public messages', function() { - assert.equal(ctx.hasMessage('foo'), true); + assert.equal(bundle.hasMessage('foo'), true); }); test('returns false for terms and missing messages', function() { - assert.equal(ctx.hasMessage('-bar'), false); - assert.equal(ctx.hasMessage('baz'), false); - assert.equal(ctx.hasMessage('-baz'), false); + assert.equal(bundle.hasMessage('-bar'), false); + assert.equal(bundle.hasMessage('baz'), false); + assert.equal(bundle.hasMessage('-baz'), false); }); }); suite('getMessage', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo -bar = Bar `); }); test('returns public messages', function() { - assert.equal(ctx.getMessage('foo'), 'Foo'); + assert.equal(bundle.getMessage('foo'), 'Foo'); }); test('returns null for terms and missing messages', function() { - assert.equal(ctx.getMessage('-bar'), null); - assert.equal(ctx.getMessage('baz'), null); - assert.equal(ctx.getMessage('-baz'), null); + assert.equal(bundle.getMessage('-bar'), null); + assert.equal(bundle.getMessage('baz'), null); + assert.equal(bundle.getMessage('-baz'), null); }); }); diff --git a/fluent/test/functions_builtin_test.js b/fluent/test/functions_builtin_test.js index 65be70fd4..250f9fc23 100644 --- a/fluent/test/functions_builtin_test.js +++ b/fluent/test/functions_builtin_test.js @@ -2,16 +2,16 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; suite('Built-in functions', function() { - let ctx; + let bundle; suite('NUMBER', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` num-decimal = { NUMBER($arg) } num-percent = { NUMBER($arg, style: "percent") } num-bad-opt = { NUMBER($arg, style: "bad") } @@ -21,49 +21,49 @@ suite('Built-in functions', function() { test('missing argument', function() { let msg; - msg = ctx.getMessage('num-decimal'); - assert.equal(ctx.format(msg), 'NaN'); + msg = bundle.getMessage('num-decimal'); + assert.equal(bundle.format(msg), 'NaN'); - msg = ctx.getMessage('num-percent'); - assert.equal(ctx.format(msg), 'NaN'); + msg = bundle.getMessage('num-percent'); + assert.equal(bundle.format(msg), 'NaN'); - msg = ctx.getMessage('num-bad-opt'); - assert.equal(ctx.format(msg), 'NaN'); + msg = bundle.getMessage('num-bad-opt'); + assert.equal(bundle.format(msg), 'NaN'); }); test('number argument', function() { const args = {arg: 1}; let msg; - msg = ctx.getMessage('num-decimal'); - assert.equal(ctx.format(msg, args), '1'); + msg = bundle.getMessage('num-decimal'); + assert.equal(bundle.format(msg, args), '1'); - msg = ctx.getMessage('num-percent'); - assert.equal(ctx.format(msg, args), '100%'); + msg = bundle.getMessage('num-percent'); + assert.equal(bundle.format(msg, args), '100%'); - msg = ctx.getMessage('num-bad-opt'); - assert.equal(ctx.format(msg, args), '1'); + msg = bundle.getMessage('num-bad-opt'); + assert.equal(bundle.format(msg, args), '1'); }); test('string argument', function() { const args = {arg: "Foo"}; let msg; - msg = ctx.getMessage('num-decimal'); - assert.equal(ctx.format(msg, args), 'NaN'); + msg = bundle.getMessage('num-decimal'); + assert.equal(bundle.format(msg, args), 'NaN'); - msg = ctx.getMessage('num-percent'); - assert.equal(ctx.format(msg, args), 'NaN'); + msg = bundle.getMessage('num-percent'); + assert.equal(bundle.format(msg, args), 'NaN'); - msg = ctx.getMessage('num-bad-opt'); - assert.equal(ctx.format(msg, args), 'NaN'); + msg = bundle.getMessage('num-bad-opt'); + assert.equal(bundle.format(msg, args), 'NaN'); }); }); suite('DATETIME', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` dt-default = { DATETIME($arg) } dt-month = { DATETIME($arg, month: "long") } dt-bad-opt = { DATETIME($arg, month: "bad") } @@ -73,14 +73,14 @@ suite('Built-in functions', function() { test('missing argument', function() { let msg; - msg = ctx.getMessage('dt-default'); - assert.equal(ctx.format(msg), 'Invalid Date'); + msg = bundle.getMessage('dt-default'); + assert.equal(bundle.format(msg), 'Invalid Date'); - msg = ctx.getMessage('dt-month'); - assert.equal(ctx.format(msg), 'Invalid Date'); + msg = bundle.getMessage('dt-month'); + assert.equal(bundle.format(msg), 'Invalid Date'); - msg = ctx.getMessage('dt-bad-opt'); - assert.equal(ctx.format(msg), 'Invalid Date'); + msg = bundle.getMessage('dt-bad-opt'); + assert.equal(bundle.format(msg), 'Invalid Date'); }); test('Date argument', function () { @@ -94,18 +94,18 @@ suite('Built-in functions', function() { const args = {arg: date}; let msg; - msg = ctx.getMessage('dt-default'); - assert.equal(ctx.format(msg, args), expectedDefault); + msg = bundle.getMessage('dt-default'); + assert.equal(bundle.format(msg, args), expectedDefault); - msg = ctx.getMessage('dt-month'); - assert.equal(ctx.format(msg, args), expectedMonth); + msg = bundle.getMessage('dt-month'); + assert.equal(bundle.format(msg, args), expectedMonth); - msg = ctx.getMessage('dt-bad-opt'); + msg = bundle.getMessage('dt-bad-opt'); // The argument value will be coerced into a string by the join operation - // in MessageContext.format. The result looks something like this; it + // in FluentBundle.format. The result looks something like this; it // may vary depending on the TZ: // Thu Sep 29 2016 02:00:00 GMT+0200 (CEST) - assert.equal(ctx.format(msg, args), date.toString()); + assert.equal(bundle.format(msg, args), date.toString()); }); }); }); diff --git a/fluent/test/functions_runtime_test.js b/fluent/test/functions_runtime_test.js index 60169bc25..b6bab1a07 100644 --- a/fluent/test/functions_runtime_test.js +++ b/fluent/test/functions_runtime_test.js @@ -2,11 +2,11 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; suite('Runtime-specific functions', function() { - let ctx, args, errs; + let bundle, args, errs; setup(function() { errs = []; @@ -14,22 +14,22 @@ suite('Runtime-specific functions', function() { suite('passing into the constructor', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { + bundle = new FluentBundle('en-US', { useIsolating: false, functions: { CONCAT: (args, kwargs) => args.reduce((a, b) => `${a}${b}`, ''), SUM: (args, kwargs) => args.reduce((a, b) => a + b, 0) } }); - ctx.addMessages(ftl` + bundle.addMessages(ftl` foo = { CONCAT("Foo", "Bar") } bar = { SUM(1, 2) } `); }); test('works for strings', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'FooBar'); assert.equal(errs.length, 0); }); @@ -37,8 +37,8 @@ suite('Runtime-specific functions', function() { // XXX When they are passed as variables, convert JS types to FTL types // https://bugzil.la/1307116 it.skip('works for numbers', function() { - const msg = ctx.getMessage('bar'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('bar'); + const val = bundle.format(msg, args, errs); assert.equal(val, '3'); assert.equal(errs.length, 0); }); diff --git a/fluent/test/functions_test.js b/fluent/test/functions_test.js index 70e69959c..c9f826e29 100644 --- a/fluent/test/functions_test.js +++ b/fluent/test/functions_test.js @@ -2,11 +2,11 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; suite('Functions', function() { - let ctx, args, errs; + let bundle, args, errs; setup(function() { errs = []; @@ -14,15 +14,15 @@ suite('Functions', function() { suite('missing', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { MISSING("Foo") } `); }); test('falls back to the name of the function', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'MISSING()'); assert.equal(errs.length, 1); assert(errs[0] instanceof ReferenceError); // unknown function @@ -31,13 +31,13 @@ suite('Functions', function() { suite('arguments', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { + bundle = new FluentBundle('en-US', { useIsolating: false, functions: { IDENTITY: args => args[0] } }); - ctx.addMessages(ftl` + bundle.addMessages(ftl` foo = Foo .attr = Attribute pass-nothing = { IDENTITY() } @@ -53,30 +53,30 @@ suite('Functions', function() { // XXX Gracefully handle wrong argument types passed into FTL Functions // https://bugzil.la/1307124 it.skip('falls back when arguments don\'t match the arity', function() { - const msg = ctx.getMessage('pass-nothing'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('pass-nothing'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'IDENTITY()'); assert.equal(errs.length, 1); assert(errs[0] instanceof RangeError); // wrong argument type }); test('accepts strings', function() { - const msg = ctx.getMessage('pass-string'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('pass-string'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'a'); assert.equal(errs.length, 0); }); test('accepts numbers', function() { - const msg = ctx.getMessage('pass-number'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('pass-number'); + const val = bundle.format(msg, args, errs); assert.equal(val, '1'); assert.equal(errs.length, 0); }); test('accepts entities', function() { - const msg = ctx.getMessage('pass-message'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('pass-message'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo'); assert.equal(errs.length, 0); }); @@ -84,22 +84,22 @@ suite('Functions', function() { // XXX Accept complex types (e.g. attributes) as arguments to FTL Functions // https://bugzil.la/1307120 it.skip('accepts attributes', function() { - const msg = ctx.getMessage('pass-attr'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('pass-attr'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Attribute'); assert.equal(errs.length, 0); }); test('accepts variables', function() { - const msg = ctx.getMessage('pass-variable'); - const val = ctx.format(msg, { var: "Variable" }, errs); + const msg = bundle.getMessage('pass-variable'); + const val = bundle.format(msg, { var: "Variable" }, errs); assert.equal(val, 'Variable'); assert.equal(errs.length, 0); }); test('accepts function calls', function() { - const msg = ctx.getMessage('pass-function-call'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('pass-function-call'); + const val = bundle.format(msg, args, errs); assert.equal(val, '1'); assert.equal(errs.length, 0); }); diff --git a/fluent/test/isolating_test.js b/fluent/test/isolating_test.js index 218b5c7da..30f6a89eb 100644 --- a/fluent/test/isolating_test.js +++ b/fluent/test/isolating_test.js @@ -2,7 +2,7 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; // Unicode bidi isolation characters. @@ -10,11 +10,11 @@ const FSI = '\u2068'; const PDI = '\u2069'; suite('Isolating interpolations', function(){ - let ctx, args, errs; + let bundle, args, errs; suiteSetup(function() { - ctx = new MessageContext('en-US'); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US'); + bundle.addMessages(ftl` foo = Foo bar = { foo } Bar baz = { $arg } Baz @@ -27,22 +27,22 @@ suite('Isolating interpolations', function(){ }); test('isolates interpolated message references', function(){ - const msg = ctx.getMessage('bar'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('bar'); + const val = bundle.format(msg, args, errs); assert.equal(val, `${FSI}Foo${PDI} Bar`); assert.equal(errs.length, 0); }); test('isolates interpolated string-typed variables', function(){ - const msg = ctx.getMessage('baz'); - const val = ctx.format(msg, {arg: 'Arg'}, errs); + const msg = bundle.getMessage('baz'); + const val = bundle.format(msg, {arg: 'Arg'}, errs); assert.equal(val, `${FSI}Arg${PDI} Baz`); assert.equal(errs.length, 0); }); test('isolates interpolated number-typed variables', function(){ - const msg = ctx.getMessage('baz'); - const val = ctx.format(msg, {arg: 1}, errs); + const msg = bundle.getMessage('baz'); + const val = bundle.format(msg, {arg: 1}, errs); assert.equal(val, `${FSI}1${PDI} Baz`); assert.equal(errs.length, 0); }); @@ -51,16 +51,16 @@ suite('Isolating interpolations', function(){ const dtf = new Intl.DateTimeFormat('en-US'); const arg = new Date('2016-09-29'); - const msg = ctx.getMessage('baz'); - const val = ctx.format(msg, {arg}, errs); + const msg = bundle.getMessage('baz'); + const val = bundle.format(msg, {arg}, errs); // format the date argument to account for the testrunner's timezone assert.equal(val, `${FSI}${dtf.format(arg)}${PDI} Baz`); assert.equal(errs.length, 0); }); test('isolates complex interpolations', function(){ - const msg = ctx.getMessage('qux'); - const val = ctx.format(msg, {arg: 'Arg'}, errs); + const msg = bundle.getMessage('qux'); + const val = bundle.format(msg, {arg: 'Arg'}, errs); const expected_bar = `${FSI}${FSI}Foo${PDI} Bar${PDI}`; const expected_baz = `${FSI}${FSI}Arg${PDI} Baz${PDI}`; @@ -70,11 +70,11 @@ suite('Isolating interpolations', function(){ }); suite('Skip isolation cases', function(){ - let ctx, args, errs; + let bundle, args, errs; suiteSetup(function() { - ctx = new MessageContext('en-US'); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US'); + bundle.addMessages(ftl` -brand-short-name = Amaya foo = { -brand-short-name } `); @@ -85,8 +85,8 @@ suite('Skip isolation cases', function(){ }); test('skips isolation if the only element is a placeable', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, `Amaya`); assert.equal(errs.length, 0); }); diff --git a/fluent/test/message_context_stub.js b/fluent/test/message_context_stub.js deleted file mode 100644 index 3b1097c7f..000000000 --- a/fluent/test/message_context_stub.js +++ /dev/null @@ -1,19 +0,0 @@ -export default class MessageContext { - _setMessages(ids) { - this.ids = ids; - } - - hasMessage(id) { - return this.ids.includes(id); - } - - getMessage(id) { - if (this.hasMessage(id)) { - return id.toUpperCase(); - } - } - - format(msg) { - return msg; - } -} diff --git a/fluent/test/patterns_test.js b/fluent/test/patterns_test.js index c0ed50baf..d4fdb984b 100644 --- a/fluent/test/patterns_test.js +++ b/fluent/test/patterns_test.js @@ -2,11 +2,11 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; suite('Patterns', function(){ - let ctx, args, errs; + let bundle, args, errs; setup(function() { errs = []; @@ -14,15 +14,15 @@ suite('Patterns', function(){ suite('Simple string value', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo `); }); test('returns the value', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo'); assert.equal(errs.length, 0); }); @@ -30,8 +30,8 @@ suite('Patterns', function(){ suite('Complex string value', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo -bar = Bar @@ -46,29 +46,29 @@ suite('Patterns', function(){ }); test('resolves the reference to a message', function(){ - const msg = ctx.getMessage('ref-message'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-message'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, 'Foo'); assert.equal(errs.length, 0); }); test('resolves the reference to a term', function(){ - const msg = ctx.getMessage('ref-term'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-term'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, 'Bar'); assert.equal(errs.length, 0); }); test('returns the id if a message reference is missing', function(){ - const msg = ctx.getMessage('ref-missing-message'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-missing-message'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, 'missing'); assert.ok(errs[0] instanceof ReferenceError); // unknown message }); test('returns the id if a term reference is missing', function(){ - const msg = ctx.getMessage('ref-missing-term'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref-missing-term'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, '-missing'); assert.ok(errs[0] instanceof ReferenceError); // unknown message }); @@ -76,8 +76,8 @@ suite('Patterns', function(){ suite('Complex string referencing a message with null value', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = .attr = Foo Attr bar = { foo } Bar @@ -85,23 +85,23 @@ suite('Patterns', function(){ }); test('returns the null value', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, null); assert.equal(errs.length, 0); }); test('formats the attribute', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg.attrs.attr, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg.attrs.attr, args, errs); assert.strictEqual(val, 'Foo Attr'); assert.equal(errs.length, 0); }); test('formats ??? when the referenced message has no value and no default', function(){ - const msg = ctx.getMessage('bar'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('bar'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, '??? Bar'); assert.ok(errs[0] instanceof RangeError); // no default }); @@ -109,16 +109,16 @@ suite('Patterns', function(){ suite('Cyclic reference', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { bar } bar = { foo } `); }); test('returns ???', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, '???'); assert.ok(errs[0] instanceof RangeError); // cyclic reference }); @@ -126,15 +126,15 @@ suite('Patterns', function(){ suite('Cyclic self-reference', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { foo } `); }); test('returns the raw string', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, '???'); assert.ok(errs[0] instanceof RangeError); // cyclic reference }); @@ -142,8 +142,8 @@ suite('Patterns', function(){ suite('Cyclic self-reference in a member', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { $sel -> *[a] { foo } @@ -154,15 +154,15 @@ suite('Patterns', function(){ }); test('returns ???', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, {sel: 'a'}, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, {sel: 'a'}, errs); assert.strictEqual(val, '???'); assert.ok(errs[0] instanceof RangeError); // cyclic reference }); test('returns the other member if requested', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, {sel: 'b'}, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, {sel: 'b'}, errs); assert.strictEqual(val, 'Bar'); assert.equal(errs.length, 0); }); @@ -170,8 +170,8 @@ suite('Patterns', function(){ suite('Cyclic reference in a selector', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` -foo = { -bar.attr -> *[a] Foo @@ -184,8 +184,8 @@ suite('Patterns', function(){ }); test('returns the default variant', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, 'Foo'); assert.ok(errs[0] instanceof RangeError); // cyclic reference }); @@ -193,8 +193,8 @@ suite('Patterns', function(){ suite('Cyclic self-reference in a selector', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` -foo = { -bar.attr -> *[a] Foo @@ -213,15 +213,15 @@ suite('Patterns', function(){ }); test('returns the default variant', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, 'Foo'); assert.ok(errs[0] instanceof RangeError); // cyclic reference }); test('can reference an attribute', function(){ - const msg = ctx.getMessage('bar'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('bar'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, 'Bar'); assert.equal(errs.length, 0); }); diff --git a/fluent/test/primitives_test.js b/fluent/test/primitives_test.js index 0c5bca698..fa42ddbbf 100644 --- a/fluent/test/primitives_test.js +++ b/fluent/test/primitives_test.js @@ -2,11 +2,11 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; suite('Primitives', function() { - let ctx, args, errs; + let bundle, args, errs; setup(function() { errs = []; @@ -14,8 +14,8 @@ suite('Primitives', function() { suite('Numbers', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` one = { 1 } select = { 1 -> *[0] Zero @@ -25,15 +25,15 @@ suite('Primitives', function() { }); test('can be used in a placeable', function(){ - const msg = ctx.getMessage('one'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('one'); + const val = bundle.format(msg, args, errs); assert.equal(val, '1'); assert.equal(errs.length, 0); }); test('can be used as a selector', function(){ - const msg = ctx.getMessage('select'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('select'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'One'); assert.equal(errs.length, 0); }); @@ -41,8 +41,8 @@ suite('Primitives', function() { suite('Simple string value', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo placeable-literal = { "Foo" } Bar @@ -67,55 +67,55 @@ suite('Primitives', function() { }); test('can be used as a value', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo'); assert.equal(errs.length, 0); }); test('is detected to be non-complex', function(){ - const msg = ctx.getMessage('foo'); + const msg = bundle.getMessage('foo'); assert.equal(typeof msg, 'string'); }); test('can be used in a placeable', function(){ - const msg = ctx.getMessage('placeable-literal'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('placeable-literal'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Bar'); assert.equal(errs.length, 0); }); test('can be a value of a message referenced in a placeable', function(){ - const msg = ctx.getMessage('placeable-message'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('placeable-message'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Bar'); assert.equal(errs.length, 0); }); test('can be a selector', function(){ - const msg = ctx.getMessage('selector-literal'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('selector-literal'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Member 1'); assert.equal(errs.length, 0); }); test('can be used as an attribute value', function(){ - const msg = ctx.getMessage('bar').attrs.attr; - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('bar').attrs.attr; + const val = bundle.format(msg, args, errs); assert.equal(val, 'Bar Attribute'); assert.equal(errs.length, 0); }); test('can be a value of an attribute used in a placeable', function(){ - const msg = ctx.getMessage('placeable-attr'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('placeable-attr'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Bar Attribute'); assert.equal(errs.length, 0); }); test('can be a value of an attribute used as a selector', function(){ - const msg = ctx.getMessage('selector-attr'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('selector-attr'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Member 3'); assert.equal(errs.length, 0); }); @@ -123,8 +123,8 @@ suite('Primitives', function() { suite('Complex string value', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = Foo bar = { foo } Bar @@ -143,42 +143,42 @@ suite('Primitives', function() { }); test('can be used as a value', function(){ - const msg = ctx.getMessage('bar'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('bar'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Bar'); assert.equal(errs.length, 0); }); test('is detected to be complex', function(){ - const msg = ctx.getMessage('bar'); + const msg = bundle.getMessage('bar'); assert.equal(typeof msg, 'object'); assert(Array.isArray(msg.val)); }); test('can be a value of a message referenced in a placeable', function(){ - const msg = ctx.getMessage('placeable-message'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('placeable-message'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Bar Baz'); assert.equal(errs.length, 0); }); test('can be used as an attribute value', function(){ - const msg = ctx.getMessage('baz').attrs.attr - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('baz').attrs.attr + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Bar Baz Attribute'); assert.equal(errs.length, 0); }); test('can be a value of an attribute used in a placeable', function(){ - const msg = ctx.getMessage('placeable-attr'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('placeable-attr'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Foo Bar Baz Attribute'); assert.equal(errs.length, 0); }); test.skip('can be a value of an attribute used as a selector', function(){ - const msg = ctx.getMessage('selector-attr'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('selector-attr'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Variant 2'); assert.equal(errs.length, 0); }); diff --git a/fluent/test/select_expressions_test.js b/fluent/test/select_expressions_test.js index b4e4aae8a..b95c55f50 100644 --- a/fluent/test/select_expressions_test.js +++ b/fluent/test/select_expressions_test.js @@ -2,11 +2,11 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; suite('Select expressions', function() { - let ctx, args, errs; + let bundle, args, errs; setup(function() { errs = []; @@ -14,8 +14,8 @@ suite('Select expressions', function() { suite('with a matching selector', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { "a" -> [a] A *[b] B @@ -24,8 +24,8 @@ suite('Select expressions', function() { }); test('selects the variant matching the selector', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'A'); assert.equal(errs.length, 0); }); @@ -33,8 +33,8 @@ suite('Select expressions', function() { suite('with a valid non-matching selector', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { "c" -> *[a] A [b] B @@ -43,8 +43,8 @@ suite('Select expressions', function() { }); test('selects the default variant', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'A'); assert.equal(errs.length, 0); }); @@ -52,8 +52,8 @@ suite('Select expressions', function() { suite('with a missing selector', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { $none -> *[a] A [b] B @@ -62,8 +62,8 @@ suite('Select expressions', function() { }); test('selects the default variant', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'A'); assert.equal(errs.length, 1); assert(errs[0] instanceof ReferenceError); // unknown variable @@ -72,8 +72,8 @@ suite('Select expressions', function() { suite('with a number selector', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { 1 -> *[0] A [1] B @@ -87,22 +87,22 @@ suite('Select expressions', function() { }); test('selects the right variant', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'B'); }); test('selects the default variant', function() { - const msg = ctx.getMessage('bar'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('bar'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'A'); }); }); suite('with a number selector and plural categories', function(){ suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` foo = { 1 -> *[one] A [other] B @@ -116,14 +116,14 @@ suite('Select expressions', function() { }); test('selects the right category', function() { - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'A'); }); test('selects the exact match', function() { - const msg = ctx.getMessage('bar'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('bar'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'A'); }); }); diff --git a/fluent/test/transform_test.js b/fluent/test/transform_test.js index caa423adf..bf5e6b33a 100644 --- a/fluent/test/transform_test.js +++ b/fluent/test/transform_test.js @@ -2,17 +2,17 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; suite('Transformations', function(){ - let ctx, errs; + let bundle, errs; suiteSetup(function() { - ctx = new MessageContext('en-US', { + bundle = new FluentBundle('en-US', { transform: v => v.replace(/a/g, "A") }); - ctx.addMessages(ftl` + bundle.addMessages(ftl` foo = Faa .bar = Bar { $foo } Baz `); @@ -23,9 +23,9 @@ suite('Transformations', function(){ }); test('transforms strings', function(){ - const msg = ctx.getMessage('foo'); - const val = ctx.format(msg, {}, errs); - const attr = ctx.format(msg.attrs["bar"], {foo: "arg"}, errs); + const msg = bundle.getMessage('foo'); + const val = bundle.format(msg, {}, errs); + const attr = bundle.format(msg.attrs["bar"], {foo: "arg"}, errs); assert(val.includes("FAA")); assert(attr.includes("BAr")); assert(attr.includes("BAz")); diff --git a/fluent/test/values_format_test.js b/fluent/test/values_format_test.js index 40e45eaa0..9f54d52f3 100644 --- a/fluent/test/values_format_test.js +++ b/fluent/test/values_format_test.js @@ -2,15 +2,15 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; suite('Formatting values', function(){ - let ctx, args, errs; + let bundle, args, errs; suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` key1 = Value 1 key2 = { [a] A2 @@ -32,44 +32,44 @@ suite('Formatting values', function(){ }); test('returns the value', function(){ - const msg = ctx.getMessage('key1'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('key1'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Value 1'); assert.equal(errs.length, 0); }); test('returns the default variant', function(){ - const msg = ctx.getMessage('key2'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('key2'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'B2'); assert.equal(errs.length, 0); }); test('returns the value if it is a pattern', function(){ - const msg = ctx.getMessage('key3'); - const val = ctx.format(msg, args, errs) + const msg = bundle.getMessage('key3'); + const val = bundle.format(msg, args, errs) assert.strictEqual(val, 'Value 3'); assert.equal(errs.length, 0); }); test('returns the default variant if it is a pattern', function(){ - const msg = ctx.getMessage('key4'); - const val = ctx.format(msg, args, errs) + const msg = bundle.getMessage('key4'); + const val = bundle.format(msg, args, errs) assert.strictEqual(val, 'B4'); assert.equal(errs.length, 0); }); test('returns null if there is no value', function(){ - const msg = ctx.getMessage('key5'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('key5'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, null); assert.equal(errs.length, 0); }); - test('allows to pass traits directly to ctx.format', function(){ - const msg = ctx.getMessage('key5'); - assert.strictEqual(ctx.format(msg.attrs.a, args, errs), 'A5'); - assert.strictEqual(ctx.format(msg.attrs.b, args, errs), 'B5'); + test('allows to pass traits directly to bundle.format', function(){ + const msg = bundle.getMessage('key5'); + assert.strictEqual(bundle.format(msg.attrs.a, args, errs), 'A5'); + assert.strictEqual(bundle.format(msg.attrs.b, args, errs), 'B5'); assert.equal(errs.length, 0); }); diff --git a/fluent/test/values_ref_test.js b/fluent/test/values_ref_test.js index ca4c1de32..44d18bc8d 100644 --- a/fluent/test/values_ref_test.js +++ b/fluent/test/values_ref_test.js @@ -2,15 +2,15 @@ import assert from 'assert'; -import { MessageContext } from '../src/context'; +import { FluentBundle } from '../src/context'; import { ftl } from '../src/util'; suite('Referencing values', function(){ - let ctx, args, errs; + let bundle, args, errs; suiteSetup(function() { - ctx = new MessageContext('en-US', { useIsolating: false }); - ctx.addMessages(ftl` + bundle = new FluentBundle('en-US', { useIsolating: false }); + bundle.addMessages(ftl` key1 = Value 1 key2 = { [a] A2 @@ -47,65 +47,65 @@ suite('Referencing values', function(){ }); test('references the value', function(){ - const msg = ctx.getMessage('ref1'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref1'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Value 1'); assert.equal(errs.length, 0); }); test('references the default variant', function(){ - const msg = ctx.getMessage('ref2'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref2'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'B2'); assert.equal(errs.length, 0); }); test('references the value if it is a pattern', function(){ - const msg = ctx.getMessage('ref3'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref3'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'Value 3'); assert.equal(errs.length, 0); }); test('references the default variant if it is a pattern', function(){ - const msg = ctx.getMessage('ref4'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref4'); + const val = bundle.format(msg, args, errs); assert.equal(val, 'B4'); assert.equal(errs.length, 0); }); test('uses ??? if there is no value', function(){ - const msg = ctx.getMessage('ref5'); - const val = ctx.format(msg, args, errs); + const msg = bundle.getMessage('ref5'); + const val = bundle.format(msg, args, errs); assert.strictEqual(val, '???'); assert.ok(errs[0] instanceof RangeError); // no default }); test('references the variants', function(){ - const msg_a = ctx.getMessage('ref6'); - const msg_b = ctx.getMessage('ref7'); - const val_a = ctx.format(msg_a, args, errs) - const val_b = ctx.format(msg_b, args, errs) + const msg_a = bundle.getMessage('ref6'); + const msg_b = bundle.getMessage('ref7'); + const val_a = bundle.format(msg_a, args, errs) + const val_b = bundle.format(msg_b, args, errs) assert.strictEqual(val_a, 'A2'); assert.strictEqual(val_b, 'B2'); assert.equal(errs.length, 0); }); test('references the variants which are patterns', function(){ - const msg_a = ctx.getMessage('ref8'); - const msg_b = ctx.getMessage('ref9'); - const val_a = ctx.format(msg_a, args, errs) - const val_b = ctx.format(msg_b, args, errs) + const msg_a = bundle.getMessage('ref8'); + const msg_b = bundle.getMessage('ref9'); + const val_a = bundle.format(msg_a, args, errs) + const val_b = bundle.format(msg_b, args, errs) assert.strictEqual(val_a, 'A4'); assert.strictEqual(val_b, 'B4'); assert.equal(errs.length, 0); }); test('references the attributes', function(){ - const msg_a = ctx.getMessage('ref10'); - const msg_b = ctx.getMessage('ref11'); - const val_a = ctx.format(msg_a, args, errs) - const val_b = ctx.format(msg_b, args, errs) + const msg_a = bundle.getMessage('ref10'); + const msg_b = bundle.getMessage('ref11'); + const val_a = bundle.format(msg_a, args, errs) + const val_b = bundle.format(msg_b, args, errs) assert.strictEqual(val_a, 'A5'); assert.strictEqual(val_b, 'B5'); assert.equal(errs.length, 0); diff --git a/tools/format.js b/tools/format.js index 42dcce2af..def6721e5 100755 --- a/tools/format.js +++ b/tools/format.js @@ -55,14 +55,14 @@ function print(err, data) { return console.error('File not found: ' + err.path); } - const ctx = new Fluent.MessageContext(program.lang); - const parseErrors = ctx.addMessages(data.toString()); + const bundle = new Fluent.FluentBundle(program.lang); + const parseErrors = bundle.addMessages(data.toString()); parseErrors.forEach(printError); - for (const [id, message] of ctx.messages) { + for (const [id, message] of bundle.messages) { const formatErrors = []; - printEntry(id, ctx.format(message, ext, formatErrors)); + printEntry(id, bundle.format(message, ext, formatErrors)); formatErrors.forEach(printError); } } diff --git a/tools/perf/benchmark.d8.js b/tools/perf/benchmark.d8.js index 6010eb857..9c9bc7cf6 100644 --- a/tools/perf/benchmark.d8.js +++ b/tools/perf/benchmark.d8.js @@ -19,15 +19,15 @@ times.ftlEntriesParseStart = Date.now(); var [entries] = Fluent._parse(ftlCode); times.ftlEntriesParseEnd = Date.now(); -var ctx = new Fluent.MessageContext('en-US'); -var errors = ctx.addMessages(ftlCode); +var bundle = new Fluent.FluentBundle('en-US'); +var errors = bundle.addMessages(ftlCode); times.format = Date.now(); -for (const [id, message] of ctx.messages) { - ctx.format(message, args, errors); +for (const [id, message] of bundle.messages) { + bundle.format(message, args, errors); if (message.attrs) { for (const name in message.attrs) { - ctx.format(message.attrs[name], args, errors) + bundle.format(message.attrs[name], args, errors) } } } diff --git a/tools/perf/benchmark.jsshell.js b/tools/perf/benchmark.jsshell.js index 5b05f7f09..034eff2e0 100644 --- a/tools/perf/benchmark.jsshell.js +++ b/tools/perf/benchmark.jsshell.js @@ -19,15 +19,15 @@ times.ftlEntriesParseStart = dateNow(); var [entries] = Fluent._parse(ftlCode); times.ftlEntriesParseEnd = dateNow(); -var ctx = new Fluent.MessageContext('en-US'); -var errors = ctx.addMessages(ftlCode); +var bundle = new Fluent.FluentBundle('en-US'); +var errors = bundle.addMessages(ftlCode); times.format = dateNow(); -for (const [id, message] of ctx.messages) { - ctx.format(message, args, errors); +for (const [id, message] of bundle.messages) { + bundle.format(message, args, errors); if (message.attrs) { for (const name in message.attrs) { - ctx.format(message.attrs[name], args, errors) + bundle.format(message.attrs[name], args, errors) } } } diff --git a/tools/perf/benchmark.node.js b/tools/perf/benchmark.node.js index 6cca05b96..571020d58 100644 --- a/tools/perf/benchmark.node.js +++ b/tools/perf/benchmark.node.js @@ -23,15 +23,15 @@ cumulative.ftlEntriesParseStart = process.hrtime(start); var [entries] = Fluent._parse(ftlCode); cumulative.ftlEntriesParseEnd = process.hrtime(start); -var ctx = new Fluent.MessageContext('en-US'); -var errors = ctx.addMessages(ftlCode); +var bundle = new Fluent.FluentBundle('en-US'); +var errors = bundle.addMessages(ftlCode); cumulative.format = process.hrtime(start); -for (const [id, message] of ctx.messages) { - ctx.format(message, args, errors); +for (const [id, message] of bundle.messages) { + bundle.format(message, args, errors); if (message.attrs) { for (const name in message.attrs) { - ctx.format(message.attrs[name], args, errors) + bundle.format(message.attrs[name], args, errors) } } }