From 772d6bd4c0fbebb8aa9d19c9250fe87b785bbe70 Mon Sep 17 00:00:00 2001 From: Maciej Bukowski Date: Fri, 24 Nov 2017 12:38:22 +0100 Subject: [PATCH] Changed options to `language` and `additionalLanguages`. --- .../multiplelanguagetranslationservice.js | 19 +++---- .../multiplelanguagetranslationservice.js | 36 +++++++------ .../ckeditor5-dev-webpack-plugin/lib/index.js | 46 +++++++--------- .../tests/index.js | 53 +++++-------------- 4 files changed, 62 insertions(+), 92 deletions(-) diff --git a/packages/ckeditor5-dev-utils/lib/translations/multiplelanguagetranslationservice.js b/packages/ckeditor5-dev-utils/lib/translations/multiplelanguagetranslationservice.js index d78bf1e5b..78e33f82a 100644 --- a/packages/ckeditor5-dev-utils/lib/translations/multiplelanguagetranslationservice.js +++ b/packages/ckeditor5-dev-utils/lib/translations/multiplelanguagetranslationservice.js @@ -20,18 +20,19 @@ const { EventEmitter } = require( 'events' ); */ module.exports = class MultipleLanguageTranslationService extends EventEmitter { /** - * @param {Array.} languages Target languages. + * @param {String} language Main language. * @param {Object} options * @param {Boolean} [options.compileAllLanguages=false] Flag indicates whether the languages are specified * or should be found at runtime. - * @param {Boolean} [options.defaultLanguage] Default language that will be added to the main bundle (if possible). + * @param {Array.} options.additionalLanguages Additional languages. Build is optimized for this option is not set. + * When option is set to 'all' then script will be looking for all languages and according translations during the compilation. */ - constructor( languages, { compileAllLanguages = false, defaultLanguage } = {} ) { + constructor( language, { additionalLanguages, compileAllLanguages = false } = {} ) { super(); - this._languages = new Set( languages ); + this._mainLanguage = language; - this._defaultLanguage = defaultLanguage; + this._languages = new Set( [ language, ...additionalLanguages ] ); this._compileAllLanguages = compileAllLanguages; @@ -130,8 +131,8 @@ module.exports = class MultipleLanguageTranslationService extends EventEmitter { if ( compilationAssetNames.length > 1 ) { this.emit( 'warning', [ - 'Because of the many found bundles, none bundle will contain the default language.', - `You should add it directly to the application from the '${ outputDirectory }${ path.sep }${ this._defaultLanguage }.js'.` + 'Because of the many found bundles, none of the bundles will contain the main language.', + `You should add it directly to the application from the '${ outputDirectory }${ path.sep }${ this._mainLanguage }.js'.` ].join( '\n' ) ); return this._getTranslationAssets( outputDirectory, this._languages ); @@ -140,7 +141,7 @@ module.exports = class MultipleLanguageTranslationService extends EventEmitter { const mainAssetName = compilationAssetNames[ 0 ]; const mainCompilationAsset = compilationAssets[ mainAssetName ]; - const mainTranslationAsset = this._getTranslationAssets( outputDirectory, [ this._defaultLanguage ] )[ 0 ]; + const mainTranslationAsset = this._getTranslationAssets( outputDirectory, [ this._mainLanguage ] )[ 0 ]; const mergedCompilationAsset = { outputBody: mainCompilationAsset.source() + '\n;' + mainTranslationAsset.outputBody, @@ -148,7 +149,7 @@ module.exports = class MultipleLanguageTranslationService extends EventEmitter { }; const otherLanguages = Array.from( this._languages ) - .filter( lang => lang !== this._defaultLanguage ); + .filter( lang => lang !== this._mainLanguage ); return [ mergedCompilationAsset, diff --git a/packages/ckeditor5-dev-utils/tests/translations/multiplelanguagetranslationservice.js b/packages/ckeditor5-dev-utils/tests/translations/multiplelanguagetranslationservice.js index c7da4f8de..73ab2c026 100644 --- a/packages/ckeditor5-dev-utils/tests/translations/multiplelanguagetranslationservice.js +++ b/packages/ckeditor5-dev-utils/tests/translations/multiplelanguagetranslationservice.js @@ -39,7 +39,7 @@ describe( 'translations', () => { describe( 'constructor()', () => { it( 'should initialize `SingleLanguageTranslationService`', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl', 'de' ] ); + const translationService = new MultipleLanguageTranslationService( 'en', { additionalLanguages: [ 'pl', 'de' ] } ); expect( translationService ).to.be.instanceof( MultipleLanguageTranslationService ); } ); @@ -47,7 +47,7 @@ describe( 'translations', () => { describe( 'loadPackage()', () => { it( 'should load PO file from the package and load translations', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl', 'de' ] ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [ 'de' ] } ); const pathToTranslationsDirectory = path.join( 'pathToPackage', 'lang', 'translations' ); const pathToPlTranslations = path.join( 'pathToPackage', 'lang', 'translations', 'pl.po' ); const pathToDeTranslations = path.join( 'pathToPackage', 'lang', 'translations', 'de.po' ); @@ -82,7 +82,7 @@ describe( 'translations', () => { } ); it( 'should do nothing if the PO file does not exist', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl', 'de' ] ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [ 'de' ] } ); translationService.loadPackage( 'pathToPackage' ); @@ -90,7 +90,7 @@ describe( 'translations', () => { } ); it( 'should load PO file from the package only once per language', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl', 'de' ] ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [ 'de' ] } ); const loadPoFileSpy = sandbox.stub( translationService, '_loadPoFile' ); const pathToTranslationsDirectory = path.join( 'pathToPackage', 'lang', 'translations' ); @@ -105,7 +105,9 @@ describe( 'translations', () => { } ); it( 'should load all PO files for the current package and add languages to the language list', () => { - const translationService = new MultipleLanguageTranslationService( [], { compileAllLanguages: true } ); + const translationService = new MultipleLanguageTranslationService( 'pl', { + compileAllLanguages: true, additionalLanguages: [] + } ); const pathToTranslations = path.join( 'pathToPackage', 'lang', 'translations' ); const pathToPlTranslations = path.join( pathToTranslations, 'pl.po' ); @@ -149,7 +151,7 @@ describe( 'translations', () => { describe( 'translateSource()', () => { it( 'should replace t() call params with the translation key, starting with `a`', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl', 'de' ] ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [ 'de' ] } ); const source = 't( \'Cancel\' ), t( \'Save\' );'; const result = translationService.translateSource( source, 'file.js' ); @@ -162,7 +164,7 @@ describe( 'translations', () => { } ); it( 'should not create new id for the same translation key', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl', 'de' ] ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [ 'de' ] } ); const source = 't( \'Cancel\' ), t( \'Cancel\' );'; const result = translationService.translateSource( source, 'file.js' ); @@ -174,7 +176,7 @@ describe( 'translations', () => { } ); it( 'should return original source if there is no t() calls in the code', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl', 'de' ] ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [ 'de' ] } ); const source = 'translate( \'Cancel\' )'; const result = translationService.translateSource( source, 'file.js' ); @@ -187,7 +189,7 @@ describe( 'translations', () => { describe( 'getAssets()', () => { it( 'should return an array of assets', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl', 'en' ], { defaultLanguage: 'pl' } ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [ 'en' ] } ); translationService._translationIdsDictionary = { Cancel: 'a', @@ -224,7 +226,7 @@ describe( 'translations', () => { } ); it( 'should emit an error if the language is not present in language list', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl', 'xxx' ], { defaultLanguage: 'pl' } ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [ 'xxx' ] } ); const spy = sandbox.spy(); translationService.on( 'error', spy ); @@ -254,7 +256,7 @@ describe( 'translations', () => { } ); it( 'should feed missing translation with the translation key if the translated string is missing', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl', 'xxx' ], { defaultLanguage: 'pl' } ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [ 'xxx' ] } ); const spy = sandbox.spy(); translationService.on( 'error', spy ); @@ -290,7 +292,7 @@ describe( 'translations', () => { } ); it( 'should emit an error if the main translation is missing', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl' ], { defaultLanguage: 'xxx' } ); + const translationService = new MultipleLanguageTranslationService( 'xxx', { additionalLanguages: [ 'pl' ] } ); const spy = sandbox.spy(); translationService.on( 'error', spy ); @@ -320,7 +322,7 @@ describe( 'translations', () => { } ); it( 'should bound to assets only used translations', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl' ], { defaultLanguage: 'pl' } ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [] } ); translationService._translationIdsDictionary = { Cancel: 'a', @@ -351,7 +353,7 @@ describe( 'translations', () => { } ); it( 'should emit warning when many assets will be emitted by compilator and return only translation assets', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl' ], { defaultLanguage: 'pl' } ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [] } ); const spy = sandbox.spy(); translationService.on( 'warning', spy ); @@ -377,7 +379,7 @@ describe( 'translations', () => { sinon.assert.calledOnce( spy ); sinon.assert.alwaysCalledWithExactly( spy, [ - 'Because of the many found bundles, none of the bundles will contain the default language.', + 'Because of the many found bundles, none of the bundles will contain the main language.', `You should add it directly to the application from the 'lang${ path.sep }pl.js'.` ].join( '\n' ) ); @@ -398,7 +400,7 @@ describe( 'translations', () => { } } - const translationService = new CustomTranslationService( [ 'en' ], { defaultLanguage: 'en' } ); + const translationService = new CustomTranslationService( 'en', { additionalLanguages: [] } ); const pathToPlTranslations = path.join( 'custom', 'path', 'to', 'pathToPackage', 'en.po' ); const pathToTranslationDirectory = path.join( 'custom', 'path', 'to', 'pathToPackage' ); @@ -426,7 +428,7 @@ describe( 'translations', () => { describe( 'integration test', () => { it( 'test #1', () => { - const translationService = new MultipleLanguageTranslationService( [ 'pl', 'de' ], { defaultLanguage: 'pl' } ); + const translationService = new MultipleLanguageTranslationService( 'pl', { additionalLanguages: [ 'de' ] } ); const pathToPlTranslations = path.join( 'pathToPackage', 'lang', 'translations', 'pl.po' ); const pathToDeTranslations = path.join( 'pathToPackage', 'lang', 'translations', 'de.po' ); const pathToTranslationsDirectory = path.join( 'pathToPackage', 'lang', 'translations' ); diff --git a/packages/ckeditor5-dev-webpack-plugin/lib/index.js b/packages/ckeditor5-dev-webpack-plugin/lib/index.js index 3e7609362..f55cbeb02 100644 --- a/packages/ckeditor5-dev-webpack-plugin/lib/index.js +++ b/packages/ckeditor5-dev-webpack-plugin/lib/index.js @@ -17,23 +17,24 @@ const ckeditor5EnvUtils = require( './ckeditor5-env-utils' ); * Workflow: * * One entry point (or to be precise one output JS file): - * - one language in `languages` -> build optimized version - * - many languages in `languages` –> get first or `defaultLanguage` as the main language that will be built into the main bundle - * (e.g. `ckeditor.js`) (`languages` must support `all` option, that's why the `defaultLanguage` option is needed) + * - `additinalLanguages` not set -> build optimized version + * - `additinalLanguages` set –> `language` will be built into the main bundle (e.g. `ckeditor.js`). + * Translation files will be emitted in the `outputDirectory` or 'lang' directory. * * Multiple output JS files - * - one language in `languages` -> build optimized version - * - many languages in `languages` –> emit all translation files separately and warn user, - * that he needs to load translation file manually to get editor working + * - `additinalLanguages` not set -> build optimized version + * - `additinalLanguages` set –> emit all translation files separately and warn user, + * that he needs to load at least one translation file manually to get editor working */ module.exports = class CKEditorWebpackPlugin { /** * @param {Object} [options] Plugin options. - * @param {Array.|'all'} [options.languages] Target languages. Build is optimized if only one language is provided. - * When option is set to 'all' then script will be looking for all languages and according translations during the compilation. + * @param {String} options.language Main language of the build that will be added to the bundle. + * @param {Array.|'all'} [options.additinalLanguages] Additiional languages. Build is optimized when this option is not set. + * When `additinalLanguages` is set to 'all' then script will be looking for all languages and according translations during + * the compilation. * @param {String} [options.outputDirectory='lang'] Output directory for the emitted translation files, * should be relative to the webpack context. - * @param {String} [options.defaultLanguage] Default language for the build. If not set, the first language will be used. * @param {Boolean} [options.throwErrorOnMissingTranslation] Option that make the plugin throw when the translation is missing. * By default original (english translation keys) are used when the target translation is missing. */ @@ -42,41 +43,34 @@ module.exports = class CKEditorWebpackPlugin { } apply( compiler ) { - if ( !this.options.languages ) { + if ( !this.options.language ) { return; } + const language = this.options.language; let translationService; let compileAllLanguages = false; - let languages = this.options.languages; + let additinalLanguages = this.options.additinalLanguages; - if ( typeof languages == 'string' ) { - if ( languages !== 'all' ) { - throw new Error( '`languages` option should be an array of language codes or `all`.' ); + if ( typeof additinalLanguages == 'string' ) { + if ( additinalLanguages !== 'all' ) { + throw new Error( '`additinalLanguages` option should be an array of language codes or `all`.' ); } compileAllLanguages = true; - languages = []; // They will be searched in runtime. + additinalLanguages = []; // They will be searched in runtime. } - const defaultLanguage = this.options.defaultLanguage || languages[ 0 ]; - - if ( languages.length === 0 && !compileAllLanguages ) { - throw new Error( chalk.red( - 'At least one target language should be specified.' - ) ); - } - - if ( languages.length === 1 ) { + if ( !additinalLanguages ) { if ( this.options.outputDirectory ) { console.warn( chalk.red( '`outputDirectory` option does not work for one language because zero files will be emitted. It will be ignored.' ) ); } - translationService = new SingleLanguageTranslationService( languages[ 0 ] ); + translationService = new SingleLanguageTranslationService( language ); } else { - translationService = new MultipleLanguageTranslationService( languages, { compileAllLanguages, defaultLanguage } ); + translationService = new MultipleLanguageTranslationService( language, { compileAllLanguages, additinalLanguages } ); } serveTranslations( compiler, this.options, translationService, ckeditor5EnvUtils ); diff --git a/packages/ckeditor5-dev-webpack-plugin/tests/index.js b/packages/ckeditor5-dev-webpack-plugin/tests/index.js index adf388427..4394b89a3 100644 --- a/packages/ckeditor5-dev-webpack-plugin/tests/index.js +++ b/packages/ckeditor5-dev-webpack-plugin/tests/index.js @@ -44,7 +44,7 @@ describe( 'webpack-plugin/CKEditorWebpackPlugin', () => { describe( 'constructor()', () => { it( 'should initialize with passed options', () => { - const options = { languages: [] }; + const options = { language: 'pl' }; const ckeditorWebpackPlugin = new CKEditorWebpackPlugin( options ); @@ -53,17 +53,7 @@ describe( 'webpack-plugin/CKEditorWebpackPlugin', () => { } ); describe( 'apply()', () => { - it( 'should throw if language array is empty', () => { - const options = { languages: [] }; - - const ckeditorWebpackPlugin = new CKEditorWebpackPlugin( options ); - - expect( () => ckeditorWebpackPlugin.apply( {} ) ).to.throw( - 'At least one target language should be specified.' - ); - } ); - - it( 'should return and do nothing if language array is not specified', () => { + it( 'should return and do nothing if language is not specified', () => { const options = {}; const ckeditorWebpackPlugin = new CKEditorWebpackPlugin( options ); @@ -74,7 +64,7 @@ describe( 'webpack-plugin/CKEditorWebpackPlugin', () => { it( 'should call serveTranslations() if the options are correct', () => { const options = { - languages: [ 'pl' ] + language: 'pl' }; const compiler = {}; @@ -88,7 +78,7 @@ describe( 'webpack-plugin/CKEditorWebpackPlugin', () => { it( 'should serve `SingleLanguageTranslationService` if only one language is provided.', () => { const options = { - languages: [ 'pl' ] + language: 'pl' }; const compiler = {}; @@ -102,7 +92,8 @@ describe( 'webpack-plugin/CKEditorWebpackPlugin', () => { it( 'should serve `MultipleLanguageTranslationService` if more than 1 language is provided.', () => { const options = { - languages: [ 'pl', 'en' ] + language: 'pl', + additinalLanguages: [ 'en' ] }; const compiler = {}; @@ -115,14 +106,15 @@ describe( 'webpack-plugin/CKEditorWebpackPlugin', () => { sinon.assert.calledOnce( stubs.MultipleLanguageTranslationService ); sinon.assert.calledWithExactly( stubs.MultipleLanguageTranslationService, - [ 'pl', 'en' ], - { compileAllLanguages: false, defaultLanguage: 'pl' } + 'pl', + { compileAllLanguages: false, additinalLanguages: [ 'en' ] } ); } ); - it( 'should serve `MultipleLanguageTranslationService` if the `languages` is set to `all`.', () => { + it( 'should serve `MultipleLanguageTranslationService` if the `additinalLanguages` is set to `all`.', () => { const options = { - languages: 'all' + language: 'en', + additinalLanguages: 'all' }; const compiler = {}; @@ -135,27 +127,8 @@ describe( 'webpack-plugin/CKEditorWebpackPlugin', () => { sinon.assert.calledOnce( stubs.MultipleLanguageTranslationService ); sinon.assert.calledWithExactly( stubs.MultipleLanguageTranslationService, - [], - { compileAllLanguages: true, defaultLanguage: undefined } - ); - } ); - - it( 'should set default language for `MultipleLanguageTranslationService` if provided with options', () => { - const options = { - languages: 'all', - defaultLanguage: 'de' - }; - - const compiler = {}; - - const ckeditorWebpackPlugin = new CKEditorWebpackPlugin( options ); - ckeditorWebpackPlugin.apply( compiler ); - - sinon.assert.calledOnce( stubs.MultipleLanguageTranslationService ); - sinon.assert.calledWithExactly( - stubs.MultipleLanguageTranslationService, - [], - { compileAllLanguages: true, defaultLanguage: 'de' } + 'en', + { compileAllLanguages: true, additinalLanguages: [] } ); } ); } );