diff --git a/packages/ckeditor5-dev-translations/lib/movetranslations.js b/packages/ckeditor5-dev-translations/lib/movetranslations.js index 6ea417e05..8f8a7f826 100644 --- a/packages/ckeditor5-dev-translations/lib/movetranslations.js +++ b/packages/ckeditor5-dev-translations/lib/movetranslations.js @@ -3,6 +3,7 @@ * For licensing, see LICENSE.md. */ +import upath from 'upath'; import fs from 'fs-extra'; import { logger } from '@ckeditor/ckeditor5-dev-utils'; import getPackageContext from './utils/getpackagecontext.js'; @@ -17,11 +18,11 @@ import moveTranslationsBetweenPackages from './utils/movetranslationsbetweenpack * * If there are no validation errors, move the requested translations between packages: the context and the translation * messages for each language found in the source package. * - * @param {object} options - * @param {Array.} options.config Configuration that defines the messages to move. + * @param {MoveTranslationsOptions} options */ export default function moveTranslations( options ) { - const { config } = options; + const { config } = normalizeOptions( options ); + const log = logger(); log.info( '📍 Loading translations contexts...' ); @@ -112,10 +113,38 @@ function assertContextsExist( { packageContexts, config } ) { .map( entry => `Missing context: the "${ entry.messageId }" message does not exist in "${ entry.source }" package.` ); } +/** + * @param {MoveTranslationsOptions} options + */ +function normalizeOptions( options ) { + const { config } = options; + + const cwd = options.cwd || process.cwd(); + const toAbsolute = path => upath.resolve( cwd, path ); + + return { + config: config.map( entry => { + entry.source = toAbsolute( entry.source ); + entry.destination = toAbsolute( entry.destination ); + + return entry; + } ) + }; +} + /** * @typedef {object} TranslationMoveEntry * - * @property {string} source Relative path to the source package from which the `messageId` should be moved. - * @property {string} destination Relative path to the destination package to which the `messageId` should be moved. + * @property {string} source Path to the source package from which the `messageId` should be moved. + * Path can be relative or absolute. Relative path is resolved using `options.cwd` (or `process.cwd()` if not set). + * @property {string} destination Path to the destination package to which the `messageId` should be moved. + * Path can be relative or absolute. Relative path is resolved using `options.cwd` (or `process.cwd()` if not set). * @property {string} messageId The message identifier to move. */ + +/** + * @typedef {object} MoveTranslationsOptions + * + * @property {Array.} config Configuration that defines the messages to move. + * @property {string} [cwd=process.cwd()] Current working directory used to resolve paths to packages. + */ diff --git a/packages/ckeditor5-dev-translations/lib/synchronizetranslations.js b/packages/ckeditor5-dev-translations/lib/synchronizetranslations.js index a940a1d64..781984f23 100644 --- a/packages/ckeditor5-dev-translations/lib/synchronizetranslations.js +++ b/packages/ckeditor5-dev-translations/lib/synchronizetranslations.js @@ -19,25 +19,17 @@ import synchronizeTranslationsBasedOnContext from './utils/synchronizetranslatio * * missing translation entries are added with empty string as the message translation, * * missing translation files are created for languages that do not have own "*.po" file yet. * - * @param {object} options - * @param {Array.} options.sourceFiles An array of source files that contain messages to translate. - * @param {Array.} options.packagePaths An array of paths to packages, which will be used to find message contexts. - * @param {string} options.corePackagePath A relative to `process.cwd()` path to the `@ckeditor/ckeditor5-core` package. - * @param {boolean} [options.ignoreUnusedCorePackageContexts=false] Whether to skip unused context errors related to - * the `@ckeditor/ckeditor5-core` package. - * @param {boolean} [options.validateOnly=false] If set, only validates the translations contexts against the source messages without - * synchronizing the translations. - * @param {boolean} [options.skipLicenseHeader=false] Whether to skip adding the license header to newly created translation files. + * @param {SynchronizeTranslationsOptions} options */ export default function synchronizeTranslations( options ) { const { sourceFiles, packagePaths, corePackagePath, - ignoreUnusedCorePackageContexts = false, - validateOnly = false, - skipLicenseHeader = false - } = options; + ignoreUnusedCorePackageContexts, + validateOnly, + skipLicenseHeader + } = normalizeOptions( options ); const errors = []; const log = logger(); @@ -81,7 +73,7 @@ export default function synchronizeTranslations( options ) { * @param {object} options * @param {Array.} options.packageContexts An array of language contexts. * @param {Array.} options.sourceMessages An array of i18n source messages. - * @param {string} options.corePackagePath A relative to `process.cwd()` path to the `@ckeditor/ckeditor5-core` package. + * @param {string} options.corePackagePath A path to the `@ckeditor/ckeditor5-core` package. * @returns {Array.} */ function assertNoMissingContext( { packageContexts, sourceMessages, corePackagePath } ) { @@ -107,7 +99,7 @@ function assertNoMissingContext( { packageContexts, sourceMessages, corePackageP * @param {object} options * @param {Array.} options.packageContexts An array of language contexts. * @param {Array.} options.sourceMessages An array of i18n source messages. - * @param {string} options.corePackagePath A relative to `process.cwd()` path to the `@ckeditor/ckeditor5-core` package. + * @param {string} options.corePackagePath A path to the `@ckeditor/ckeditor5-core` package. * @param {boolean} options.ignoreUnusedCorePackageContexts Whether to skip unused context errors related to the `@ckeditor/ckeditor5-core` * package. * @returns {Array.} @@ -176,3 +168,46 @@ function assertNoRepeatedContext( { packageContexts } ) { return `Duplicated context "${ messageId }" in "${ contextFilePaths.join( '", "' ) }".`; } ); } + +/** + * @param {SynchronizeTranslationsOptions} options + */ +function normalizeOptions( options ) { + const { + sourceFiles, + packagePaths, + corePackagePath, + ignoreUnusedCorePackageContexts = false, + validateOnly = false, + skipLicenseHeader = false + } = options; + + const cwd = options.cwd || process.cwd(); + const toAbsolute = path => upath.resolve( cwd, path ); + + return { + sourceFiles: sourceFiles.map( toAbsolute ), + packagePaths: packagePaths.map( toAbsolute ), + corePackagePath: toAbsolute( corePackagePath ), + ignoreUnusedCorePackageContexts, + validateOnly, + skipLicenseHeader + }; +} + +/** + * @typedef {object} SynchronizeTranslationsOptions + * + * @property {Array.} sourceFiles An array of source files that contain messages to translate. + * Path can be relative or absolute. Relative path is resolved using `options.cwd` (or `process.cwd()` if not set). + * @property {Array.} packagePaths An array of paths to packages, which will be used to find message contexts. + * Path can be relative or absolute. Relative path is resolved using `options.cwd` (or `process.cwd()` if not set). + * @property {string} corePackagePath A path to the `@ckeditor/ckeditor5-core` package. + * Path can be relative or absolute. Relative path is resolved using `options.cwd` (or `process.cwd()` if not set). + * @property {string} [cwd=process.cwd()] Current working directory used to resolve paths to packages and source files. + * @property {boolean} [ignoreUnusedCorePackageContexts=false] Whether to skip unused context errors related to the + * `@ckeditor/ckeditor5-core` package. + * @property {boolean} [validateOnly=false] If set, only validates the translations contexts against the source messages without + * synchronizing the translations. + * @property {boolean} [skipLicenseHeader=false] Whether to skip adding the license header to newly created translation files. + */ diff --git a/packages/ckeditor5-dev-translations/lib/utils/getsourcemessages.js b/packages/ckeditor5-dev-translations/lib/utils/getsourcemessages.js index 6336774e5..12b0c9a53 100644 --- a/packages/ckeditor5-dev-translations/lib/utils/getsourcemessages.js +++ b/packages/ckeditor5-dev-translations/lib/utils/getsourcemessages.js @@ -5,6 +5,7 @@ import fs from 'fs-extra'; import findMessages from '../findmessages.js'; +import isFileInDirectory from './isfileindirectory.js'; /** * @param {object} options @@ -15,10 +16,10 @@ import findMessages from '../findmessages.js'; */ export default function getSourceMessages( { packagePaths, sourceFiles, onErrorCallback } ) { return sourceFiles - .filter( filePath => packagePaths.some( packagePath => filePath.includes( `/${ packagePath }/` ) ) ) + .filter( filePath => packagePaths.some( packagePath => isFileInDirectory( filePath, packagePath ) ) ) .flatMap( filePath => { const fileContent = fs.readFileSync( filePath, 'utf-8' ); - const packagePath = packagePaths.find( packagePath => filePath.includes( `/${ packagePath }/` ) ); + const packagePath = packagePaths.find( packagePath => isFileInDirectory( filePath, packagePath ) ); const sourceMessages = []; const onMessageCallback = message => { diff --git a/packages/ckeditor5-dev-translations/lib/utils/isfileindirectory.js b/packages/ckeditor5-dev-translations/lib/utils/isfileindirectory.js new file mode 100644 index 000000000..d7048f59a --- /dev/null +++ b/packages/ckeditor5-dev-translations/lib/utils/isfileindirectory.js @@ -0,0 +1,17 @@ +/** + * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import upath from 'upath'; + +/** + * @param {string} languageCode + * @param {string} localeCode + * @returns {object} + */ +export default function isFileInDirectory( filePath, directoryPath ) { + const directoryPathNormalized = upath.normalizeTrim( directoryPath ) + '/'; + + return filePath.startsWith( directoryPathNormalized ); +} diff --git a/packages/ckeditor5-dev-translations/tests/movetranslations.js b/packages/ckeditor5-dev-translations/tests/movetranslations.js index b5f381bd2..54e3d0efb 100644 --- a/packages/ckeditor5-dev-translations/tests/movetranslations.js +++ b/packages/ckeditor5-dev-translations/tests/movetranslations.js @@ -44,11 +44,11 @@ describe( 'moveTranslations()', () => { vi.mocked( getPackageContext ).mockImplementation( ( { packagePath } ) => { const contextContent = {}; - if ( packagePath === 'packages/ckeditor5-foo' ) { + if ( packagePath === '/absolute/path/to/packages/ckeditor5-foo' ) { contextContent.id1 = 'Context for message id1 from "ckeditor5-foo".'; } - if ( packagePath === 'packages/ckeditor5-bar' ) { + if ( packagePath === '/absolute/path/to/packages/ckeditor5-bar' ) { contextContent.id2 = 'Context for message id2 from "ckeditor5-bar".'; } @@ -60,6 +60,7 @@ describe( 'moveTranslations()', () => { } ); vi.spyOn( process, 'exit' ).mockImplementation( () => {} ); + vi.spyOn( process, 'cwd' ).mockReturnValue( '/absolute/path/to' ); } ); it( 'should be a function', () => { @@ -70,12 +71,22 @@ describe( 'moveTranslations()', () => { moveTranslations( defaultOptions ); expect( getPackageContext ).toHaveBeenCalledTimes( 2 ); - expect( getPackageContext ).toHaveBeenCalledWith( { packagePath: 'packages/ckeditor5-foo' } ); - expect( getPackageContext ).toHaveBeenCalledWith( { packagePath: 'packages/ckeditor5-bar' } ); + expect( getPackageContext ).toHaveBeenCalledWith( { packagePath: '/absolute/path/to/packages/ckeditor5-foo' } ); + expect( getPackageContext ).toHaveBeenCalledWith( { packagePath: '/absolute/path/to/packages/ckeditor5-bar' } ); expect( stubs.logger.info ).toHaveBeenCalledWith( '📍 Loading translations contexts...' ); } ); + it( 'should resolve paths to packages using custom cwd', () => { + defaultOptions.cwd = '/another/workspace'; + + moveTranslations( defaultOptions ); + + expect( getPackageContext ).toHaveBeenCalledTimes( 2 ); + expect( getPackageContext ).toHaveBeenCalledWith( { packagePath: '/another/workspace/packages/ckeditor5-foo' } ); + expect( getPackageContext ).toHaveBeenCalledWith( { packagePath: '/another/workspace/packages/ckeditor5-bar' } ); + } ); + it( 'should move translations between packages', () => { moveTranslations( defaultOptions ); @@ -86,21 +97,21 @@ describe( 'moveTranslations()', () => { contextContent: { id1: 'Context for message id1 from "ckeditor5-foo".' }, - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', - packagePath: 'packages/ckeditor5-foo' + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo' }, { contextContent: { id2: 'Context for message id2 from "ckeditor5-bar".' }, - contextFilePath: 'packages/ckeditor5-bar/lang/contexts.json', - packagePath: 'packages/ckeditor5-bar' + contextFilePath: '/absolute/path/to/packages/ckeditor5-bar/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-bar' } ], config: [ { - source: 'packages/ckeditor5-foo', - destination: 'packages/ckeditor5-bar', + source: '/absolute/path/to/packages/ckeditor5-foo', + destination: '/absolute/path/to/packages/ckeditor5-bar', messageId: 'id1' } ] @@ -211,13 +222,13 @@ describe( 'moveTranslations()', () => { it( 'should return error if there is missing package (missing source package)', () => { vi.mocked( fs.existsSync ).mockImplementation( path => { - return path !== 'packages/ckeditor5-foo'; + return path !== '/absolute/path/to/packages/ckeditor5-foo'; } ); moveTranslations( defaultOptions ); expect( stubs.logger.error ).toHaveBeenCalledWith( - ' - Missing package: the "packages/ckeditor5-foo" package does not exist.' + ' - Missing package: the "/absolute/path/to/packages/ckeditor5-foo" package does not exist.' ); expect( process.exit ).toHaveBeenCalledWith( 1 ); @@ -225,13 +236,13 @@ describe( 'moveTranslations()', () => { it( 'should return error if there is missing package (missing destination package)', () => { vi.mocked( fs.existsSync ).mockImplementation( path => { - return path !== 'packages/ckeditor5-bar'; + return path !== '/absolute/path/to/packages/ckeditor5-bar'; } ); moveTranslations( defaultOptions ); expect( stubs.logger.error ).toHaveBeenCalledWith( - ' - Missing package: the "packages/ckeditor5-bar" package does not exist.' + ' - Missing package: the "/absolute/path/to/packages/ckeditor5-bar" package does not exist.' ); expect( process.exit ).toHaveBeenCalledWith( 1 ); @@ -243,11 +254,11 @@ describe( 'moveTranslations()', () => { moveTranslations( defaultOptions ); expect( stubs.logger.error ).toHaveBeenCalledWith( - ' - Missing package: the "packages/ckeditor5-foo" package does not exist.' + ' - Missing package: the "/absolute/path/to/packages/ckeditor5-foo" package does not exist.' ); expect( stubs.logger.error ).toHaveBeenCalledWith( - ' - Missing package: the "packages/ckeditor5-bar" package does not exist.' + ' - Missing package: the "/absolute/path/to/packages/ckeditor5-bar" package does not exist.' ); expect( process.exit ).toHaveBeenCalledWith( 1 ); @@ -273,7 +284,7 @@ describe( 'moveTranslations()', () => { moveTranslations( defaultOptions ); expect( stubs.logger.error ).toHaveBeenCalledWith( - ' - Missing context: the "id100" message does not exist in "packages/ckeditor5-foo" package.' + ' - Missing context: the "id100" message does not exist in "/absolute/path/to/packages/ckeditor5-foo" package.' ); expect( process.exit ).toHaveBeenCalledWith( 1 ); @@ -291,7 +302,7 @@ describe( 'moveTranslations()', () => { moveTranslations( defaultOptions ); expect( stubs.logger.error ).toHaveBeenCalledWith( - ' - Missing context: the "id2" message does not exist in "packages/ckeditor5-foo" package.' + ' - Missing context: the "id2" message does not exist in "/absolute/path/to/packages/ckeditor5-foo" package.' ); expect( process.exit ).toHaveBeenCalledWith( 1 ); diff --git a/packages/ckeditor5-dev-translations/tests/synchronizetranslations.js b/packages/ckeditor5-dev-translations/tests/synchronizetranslations.js index 86e8e3c60..0cc521ac8 100644 --- a/packages/ckeditor5-dev-translations/tests/synchronizetranslations.js +++ b/packages/ckeditor5-dev-translations/tests/synchronizetranslations.js @@ -48,6 +48,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [] ); vi.spyOn( process, 'exit' ).mockImplementation( () => {} ); + vi.spyOn( process, 'cwd' ).mockReturnValue( '/absolute/path/to' ); } ); it( 'should be a function', () => { @@ -60,23 +61,38 @@ describe( 'synchronizeTranslations()', () => { expect( getPackageContexts ).toHaveBeenCalledTimes( 1 ); expect( getPackageContexts ).toHaveBeenCalledWith( { packagePaths: [ - 'packages/ckeditor5-foo', - 'packages/ckeditor5-bar' + '/absolute/path/to/packages/ckeditor5-foo', + '/absolute/path/to/packages/ckeditor5-bar' ], - corePackagePath: 'packages/ckeditor5-core' + corePackagePath: '/absolute/path/to/packages/ckeditor5-core' } ); expect( stubs.logger.info ).toHaveBeenCalledWith( '📍 Loading translations contexts...' ); } ); + it( 'should resolve paths to packages using custom cwd', () => { + defaultOptions.cwd = '/another/workspace'; + + synchronizeTranslations( defaultOptions ); + + expect( getPackageContexts ).toHaveBeenCalledTimes( 1 ); + expect( getPackageContexts ).toHaveBeenCalledWith( { + packagePaths: [ + '/another/workspace/packages/ckeditor5-foo', + '/another/workspace/packages/ckeditor5-bar' + ], + corePackagePath: '/another/workspace/packages/ckeditor5-core' + } ); + } ); + it( 'should load messages from source files', () => { synchronizeTranslations( defaultOptions ); expect( getSourceMessages ).toHaveBeenCalledTimes( 1 ); expect( getSourceMessages ).toHaveBeenCalledWith( { packagePaths: [ - 'packages/ckeditor5-foo', - 'packages/ckeditor5-bar' + '/absolute/path/to/packages/ckeditor5-foo', + '/absolute/path/to/packages/ckeditor5-bar' ], sourceFiles: [ '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts', @@ -143,13 +159,13 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if there is no missing context (no context, no message)', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: {} }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -164,15 +180,15 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if there is no missing context (context in "foo", no message)', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -187,8 +203,8 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if there is no missing context (context in "core", no message)', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id1: 'Example message 1.' } @@ -205,15 +221,15 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if there is no missing context (context in "foo", message in "foo")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -221,7 +237,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', filePath: '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts' } ] ); @@ -234,13 +250,13 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if there is no missing context (context in "core", message in "foo")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: {} }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id1: 'Example message 1.' } @@ -250,7 +266,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', filePath: '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts' } ] ); @@ -263,13 +279,13 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if there is no missing context (context in "core", message in "core")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: {} }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id1: 'Example message 1.' } @@ -279,7 +295,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-core', + packagePath: '/absolute/path/to/packages/ckeditor5-core', filePath: '/absolute/path/to/packages/ckeditor5-core/src/utils/file.ts' } ] ); @@ -292,15 +308,15 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if there is no missing context (context in "foo" and "core", messages in "foo")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id2: 'Example message 2.' } @@ -310,12 +326,12 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', filePath: '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts' }, { id: 'id2', - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', filePath: '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts' } ] ); @@ -328,13 +344,13 @@ describe( 'synchronizeTranslations()', () => { it( 'should return error if there is missing context (no context, message in "foo")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: {} }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -342,7 +358,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', filePath: '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts' } ] ); @@ -359,20 +375,20 @@ describe( 'synchronizeTranslations()', () => { it( 'should return error if there is missing context (context in "foo", message in "bar")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-bar', - contextFilePath: 'packages/ckeditor5-bar/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-bar', + contextFilePath: '/absolute/path/to/packages/ckeditor5-bar/lang/contexts.json', contextContent: {} }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -380,7 +396,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-bar', + packagePath: '/absolute/path/to/packages/ckeditor5-bar', filePath: '/absolute/path/to/packages/ckeditor5-bar/src/utils/file.ts' } ] ); @@ -397,15 +413,15 @@ describe( 'synchronizeTranslations()', () => { it( 'should return error if there is missing context (context in "foo", message in "core")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -413,7 +429,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-core', + packagePath: '/absolute/path/to/packages/ckeditor5-core', filePath: '/absolute/path/to/packages/ckeditor5-core/src/utils/file.ts' } ] ); @@ -432,13 +448,13 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if all context is used (no context, no message)', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: {} }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -453,15 +469,15 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if all context is used (context in "foo", message in "foo")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -469,7 +485,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', filePath: '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts' } ] ); @@ -482,13 +498,13 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if all context is used (context in "core", message in "foo")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: {} }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id1: 'Example message 1.' } @@ -498,7 +514,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', filePath: '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts' } ] ); @@ -511,8 +527,8 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if all context is used (context in "core", message in "core")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id1: 'Example message 1.' } @@ -522,7 +538,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-core', + packagePath: '/absolute/path/to/packages/ckeditor5-core', filePath: '/absolute/path/to/packages/ckeditor5-core/src/utils/file.ts' } ] ); @@ -535,15 +551,15 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if all context is used (context in "foo" and "core", messages in "foo")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id2: 'Example message 2.' } @@ -553,12 +569,12 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', filePath: '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts' }, { id: 'id2', - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', filePath: '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts' } ] ); @@ -571,8 +587,8 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if all context is used (context in "core", no message, ignore core)', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id1: 'Example message 1.' } @@ -591,15 +607,15 @@ describe( 'synchronizeTranslations()', () => { it( 'should return error if there is unused context (context in "foo", no message)', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -609,7 +625,7 @@ describe( 'synchronizeTranslations()', () => { synchronizeTranslations( defaultOptions ); expect( stubs.logger.error ).toHaveBeenCalledWith( - ' - Unused context "id1" in "packages/ckeditor5-foo/lang/contexts.json".' + ' - Unused context "id1" in "/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json".' ); expect( process.exit ).toHaveBeenCalledWith( 1 ); @@ -618,20 +634,20 @@ describe( 'synchronizeTranslations()', () => { it( 'should return error if there is unused context (context in "foo", message in "bar")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-bar', - contextFilePath: 'packages/ckeditor5-bar/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-bar', + contextFilePath: '/absolute/path/to/packages/ckeditor5-bar/lang/contexts.json', contextContent: {} }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -639,7 +655,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-bar', + packagePath: '/absolute/path/to/packages/ckeditor5-bar', filePath: '/absolute/path/to/packages/ckeditor5-bar/src/utils/file.ts' } ] ); @@ -647,7 +663,7 @@ describe( 'synchronizeTranslations()', () => { synchronizeTranslations( defaultOptions ); expect( stubs.logger.error ).toHaveBeenCalledWith( - ' - Unused context "id1" in "packages/ckeditor5-foo/lang/contexts.json".' + ' - Unused context "id1" in "/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json".' ); expect( process.exit ).toHaveBeenCalledWith( 1 ); @@ -656,15 +672,15 @@ describe( 'synchronizeTranslations()', () => { it( 'should return error if there is unused context (context in "foo", message in "core")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -672,7 +688,7 @@ describe( 'synchronizeTranslations()', () => { vi.mocked( getSourceMessages ).mockReturnValue( [ { id: 'id1', - packagePath: 'packages/ckeditor5-core', + packagePath: '/absolute/path/to/packages/ckeditor5-core', filePath: '/absolute/path/to/packages/ckeditor5-core/src/utils/file.ts' } ] ); @@ -680,7 +696,7 @@ describe( 'synchronizeTranslations()', () => { synchronizeTranslations( defaultOptions ); expect( stubs.logger.error ).toHaveBeenCalledWith( - ' - Unused context "id1" in "packages/ckeditor5-foo/lang/contexts.json".' + ' - Unused context "id1" in "/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json".' ); expect( process.exit ).toHaveBeenCalledWith( 1 ); @@ -689,8 +705,8 @@ describe( 'synchronizeTranslations()', () => { it( 'should return error if there is unused context (context in "core", no message)', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id1: 'Example message 1.' } @@ -702,7 +718,7 @@ describe( 'synchronizeTranslations()', () => { synchronizeTranslations( defaultOptions ); expect( stubs.logger.error ).toHaveBeenCalledWith( - ' - Unused context "id1" in "packages/ckeditor5-core/lang/contexts.json".' + ' - Unused context "id1" in "/absolute/path/to/packages/ckeditor5-core/lang/contexts.json".' ); expect( process.exit ).toHaveBeenCalledWith( 1 ); @@ -713,13 +729,13 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if there is no duplicated context (no context)', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: {} }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: {} } ] ); @@ -732,13 +748,13 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if there is no duplicated context (no context in "foo", context in "core")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: {} }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id1: 'Example message 1.' } @@ -753,15 +769,15 @@ describe( 'synchronizeTranslations()', () => { it( 'should return no error if there is no duplicated context (context in "foo", another context in "core")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id2: 'Example message 2.' } @@ -776,15 +792,15 @@ describe( 'synchronizeTranslations()', () => { it( 'should return error if there is duplicated context (the same context in "foo" and "core")', () => { vi.mocked( getPackageContexts ).mockReturnValue( [ { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Example message 1.' } }, { - packagePath: 'packages/ckeditor5-core', - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core', + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', contextContent: { id1: 'Example message 1.' } @@ -797,7 +813,8 @@ describe( 'synchronizeTranslations()', () => { expect( stubs.logger.error ).toHaveBeenCalledWith( ' - Duplicated context "id1" in ' + - '"packages/ckeditor5-foo/lang/contexts.json", "packages/ckeditor5-core/lang/contexts.json".' + '"/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json", ' + + '"/absolute/path/to/packages/ckeditor5-core/lang/contexts.json".' ); expect( process.exit ).toHaveBeenCalledWith( 1 ); diff --git a/packages/ckeditor5-dev-translations/tests/utils/createmissingpackagetranslations.js b/packages/ckeditor5-dev-translations/tests/utils/createmissingpackagetranslations.js index 14ef9312b..5f8bce22d 100644 --- a/packages/ckeditor5-dev-translations/tests/utils/createmissingpackagetranslations.js +++ b/packages/ckeditor5-dev-translations/tests/utils/createmissingpackagetranslations.js @@ -26,7 +26,7 @@ describe( 'createMissingPackageTranslations()', () => { }; defaultOptions = { - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', skipLicenseHeader: false }; @@ -50,7 +50,7 @@ describe( 'createMissingPackageTranslations()', () => { } ); vi.mocked( fs.existsSync ).mockImplementation( path => { - if ( path === 'packages/ckeditor5-foo/lang/translations/en.po' ) { + if ( path === '/absolute/path/to/packages/ckeditor5-foo/lang/translations/en.po' ) { return true; } @@ -73,8 +73,8 @@ describe( 'createMissingPackageTranslations()', () => { createMissingPackageTranslations( defaultOptions ); expect( fs.existsSync ).toHaveBeenCalledTimes( 2 ); - expect( fs.existsSync ).toHaveBeenCalledWith( 'packages/ckeditor5-foo/lang/translations/en.po' ); - expect( fs.existsSync ).toHaveBeenCalledWith( 'packages/ckeditor5-foo/lang/translations/zh-tw.po' ); + expect( fs.existsSync ).toHaveBeenCalledWith( '/absolute/path/to/packages/ckeditor5-foo/lang/translations/en.po' ); + expect( fs.existsSync ).toHaveBeenCalledWith( '/absolute/path/to/packages/ckeditor5-foo/lang/translations/zh-tw.po' ); } ); it( 'should create missing translation files from the template', () => { @@ -108,7 +108,7 @@ describe( 'createMissingPackageTranslations()', () => { expect( fs.outputFileSync ).toHaveBeenCalledTimes( 1 ); expect( fs.outputFileSync ).toHaveBeenCalledWith( - 'packages/ckeditor5-foo/lang/translations/zh-tw.po', + '/absolute/path/to/packages/ckeditor5-foo/lang/translations/zh-tw.po', 'Clean PO file content.', 'utf-8' ); diff --git a/packages/ckeditor5-dev-translations/tests/utils/getpackagecontext.js b/packages/ckeditor5-dev-translations/tests/utils/getpackagecontext.js index 1e0465ae9..3c548e40f 100644 --- a/packages/ckeditor5-dev-translations/tests/utils/getpackagecontext.js +++ b/packages/ckeditor5-dev-translations/tests/utils/getpackagecontext.js @@ -14,11 +14,11 @@ describe( 'getPackageContext()', () => { beforeEach( () => { defaultOptions = { - packagePath: 'packages/ckeditor5-foo' + packagePath: '/absolute/path/to/packages/ckeditor5-foo' }; vi.mocked( fs.readJsonSync ).mockImplementation( path => { - if ( path === 'packages/ckeditor5-foo/lang/contexts.json' ) { + if ( path === '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json' ) { return { id1: 'Context for message id1 from "ckeditor5-foo".' }; @@ -36,7 +36,7 @@ describe( 'getPackageContext()', () => { getPackageContext( defaultOptions ); expect( fs.readJsonSync ).toHaveBeenCalledTimes( 1 ); - expect( fs.readJsonSync ).toHaveBeenCalledWith( 'packages/ckeditor5-foo/lang/contexts.json', { throws: false } ); + expect( fs.readJsonSync ).toHaveBeenCalledWith( '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', { throws: false } ); } ); it( 'should return package contexts', () => { @@ -46,20 +46,20 @@ describe( 'getPackageContext()', () => { contextContent: { id1: 'Context for message id1 from "ckeditor5-foo".' }, - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', - packagePath: 'packages/ckeditor5-foo' + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo' } ) ); } ); it( 'should return empty context if package does not have context file', () => { - defaultOptions.packagePath = 'packages/ckeditor5-bar'; + defaultOptions.packagePath = '/absolute/path/to/packages/ckeditor5-bar'; const result = getPackageContext( defaultOptions ); expect( result ).toEqual( expect.objectContaining( { contextContent: {}, - contextFilePath: 'packages/ckeditor5-bar/lang/contexts.json', - packagePath: 'packages/ckeditor5-bar' + contextFilePath: '/absolute/path/to/packages/ckeditor5-bar/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-bar' } ) ); } ); } ); diff --git a/packages/ckeditor5-dev-translations/tests/utils/getpackagecontexts.js b/packages/ckeditor5-dev-translations/tests/utils/getpackagecontexts.js index 471860d78..1e26f3aeb 100644 --- a/packages/ckeditor5-dev-translations/tests/utils/getpackagecontexts.js +++ b/packages/ckeditor5-dev-translations/tests/utils/getpackagecontexts.js @@ -14,18 +14,18 @@ describe( 'getPackageContexts()', () => { beforeEach( () => { defaultOptions = { - packagePaths: [ 'packages/ckeditor5-foo' ], - corePackagePath: 'packages/ckeditor5-core' + packagePaths: [ '/absolute/path/to/packages/ckeditor5-foo' ], + corePackagePath: '/absolute/path/to/packages/ckeditor5-core' }; vi.mocked( getPackageContext ).mockImplementation( ( { packagePath } ) => { const contextContent = {}; - if ( packagePath === 'packages/ckeditor5-foo' ) { + if ( packagePath === '/absolute/path/to/packages/ckeditor5-foo' ) { contextContent.id1 = 'Context for message id1 from "ckeditor5-foo".'; } - if ( packagePath === 'packages/ckeditor5-core' ) { + if ( packagePath === '/absolute/path/to/packages/ckeditor5-core' ) { contextContent.id2 = 'Context for message id2 from "ckeditor5-core".'; } @@ -45,19 +45,19 @@ describe( 'getPackageContexts()', () => { getPackageContexts( defaultOptions ); expect( defaultOptions.packagePaths ).toEqual( [ - 'packages/ckeditor5-foo', - 'packages/ckeditor5-core' + '/absolute/path/to/packages/ckeditor5-foo', + '/absolute/path/to/packages/ckeditor5-core' ] ); } ); it( 'should not duplicate core package if it is already included in the packages', () => { - defaultOptions.packagePaths.push( 'packages/ckeditor5-core' ); + defaultOptions.packagePaths.push( '/absolute/path/to/packages/ckeditor5-core' ); getPackageContexts( defaultOptions ); expect( defaultOptions.packagePaths ).toEqual( [ - 'packages/ckeditor5-foo', - 'packages/ckeditor5-core' + '/absolute/path/to/packages/ckeditor5-foo', + '/absolute/path/to/packages/ckeditor5-core' ] ); } ); @@ -71,8 +71,8 @@ describe( 'getPackageContexts()', () => { contextContent: { id1: 'Context for message id1 from "ckeditor5-foo".' }, - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', - packagePath: 'packages/ckeditor5-foo' + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo' } ] ) ); expect( result ).toEqual( expect.arrayContaining( [ @@ -80,14 +80,14 @@ describe( 'getPackageContexts()', () => { contextContent: { id2: 'Context for message id2 from "ckeditor5-core".' }, - contextFilePath: 'packages/ckeditor5-core/lang/contexts.json', - packagePath: 'packages/ckeditor5-core' + contextFilePath: '/absolute/path/to/packages/ckeditor5-core/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-core' } ] ) ); } ); it( 'should return empty context if package does not have context file', () => { - defaultOptions.packagePaths.push( 'packages/ckeditor5-bar' ); + defaultOptions.packagePaths.push( '/absolute/path/to/packages/ckeditor5-bar' ); const result = getPackageContexts( defaultOptions ); @@ -96,8 +96,8 @@ describe( 'getPackageContexts()', () => { expect( result ).toEqual( expect.arrayContaining( [ { contextContent: {}, - contextFilePath: 'packages/ckeditor5-bar/lang/contexts.json', - packagePath: 'packages/ckeditor5-bar' + contextFilePath: '/absolute/path/to/packages/ckeditor5-bar/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-bar' } ] ) ); } ); diff --git a/packages/ckeditor5-dev-translations/tests/utils/getsourcemessages.js b/packages/ckeditor5-dev-translations/tests/utils/getsourcemessages.js index 58ec47070..6a65bdc9b 100644 --- a/packages/ckeditor5-dev-translations/tests/utils/getsourcemessages.js +++ b/packages/ckeditor5-dev-translations/tests/utils/getsourcemessages.js @@ -6,9 +6,11 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import fs from 'fs-extra'; import findMessages from '../../lib/findmessages.js'; +import isFileInDirectory from '../../lib/utils/isfileindirectory.js'; import getSourceMessages from '../../lib/utils/getsourcemessages.js'; vi.mock( 'fs-extra' ); +vi.mock( '../../lib/utils/isfileindirectory.js' ); vi.mock( '../../lib/findmessages.js' ); describe( 'getSourceMessages()', () => { @@ -16,7 +18,7 @@ describe( 'getSourceMessages()', () => { beforeEach( () => { defaultOptions = { - packagePaths: [ 'packages/ckeditor5-foo' ], + packagePaths: [ '/absolute/path/to/packages/ckeditor5-foo' ], sourceFiles: [ '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts', '/absolute/path/to/packages/ckeditor5-bar/src/utils/file.ts' @@ -31,6 +33,8 @@ describe( 'getSourceMessages()', () => { throw new Error( `ENOENT: no such file or directory, open ${ path }` ); } ); + + vi.mocked( isFileInDirectory ).mockImplementation( ( filePath, directoryPath ) => filePath.startsWith( directoryPath ) ); } ); it( 'should be a function', () => { @@ -67,13 +71,13 @@ describe( 'getSourceMessages()', () => { expect( result ).toEqual( [ { filePath: '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts', - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', id: 'id1', string: 'Example message 1.' }, { filePath: '/absolute/path/to/packages/ckeditor5-foo/src/utils/file.ts', - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', id: 'id2', string: 'Example message 2.' } @@ -81,9 +85,7 @@ describe( 'getSourceMessages()', () => { } ); it( 'should not find messages if package paths do not match exactly the file path', () => { - defaultOptions.sourceFiles = [ - '/absolute/path/to/packages/ckeditor5-foo-bar/src/utils/file.ts' - ]; + vi.mocked( isFileInDirectory ).mockReturnValue( false ); getSourceMessages( defaultOptions ); diff --git a/packages/ckeditor5-dev-translations/tests/utils/isfileindirectory.js b/packages/ckeditor5-dev-translations/tests/utils/isfileindirectory.js new file mode 100644 index 000000000..376faf551 --- /dev/null +++ b/packages/ckeditor5-dev-translations/tests/utils/isfileindirectory.js @@ -0,0 +1,25 @@ +/** + * @license Copyright (c) 2003-2024, CKSource Holding sp. z o.o. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import { describe, expect, it } from 'vitest'; +import isFileInDirectory from '../../lib/utils/isfileindirectory.js'; + +describe( 'isFileInDirectory()', () => { + it( 'should be a function', () => { + expect( isFileInDirectory ).toBeInstanceOf( Function ); + } ); + + it( 'should properly calculate if the file path is inside the defined directory', () => { + expect( isFileInDirectory( '/absolute/path/to/directory/src/file.ts', '/absolute/path/to/directory' ) ).toEqual( true ); + expect( isFileInDirectory( '/absolute/path/to/directory/src/file.ts', '/absolute/path/to/directory/' ) ).toEqual( true ); + + expect( isFileInDirectory( '/absolute/path/to/directory/src/file.ts', '/another/path/to/directory' ) ).toEqual( false ); + expect( isFileInDirectory( '/absolute/path/to/directory/src/file.ts', '/another/path/to/directory/' ) ).toEqual( false ); + expect( isFileInDirectory( '/absolute/path/to/directory/src/file.ts', '/absolute/path/to/dir' ) ).toEqual( false ); + expect( isFileInDirectory( '/absolute/path/to/directory/src/file.ts', '/absolute/path/to/dir/' ) ).toEqual( false ); + expect( isFileInDirectory( '/absolute/path/to/directory/src/file.ts', 'directory' ) ).toEqual( false ); + expect( isFileInDirectory( '/absolute/path/to/directory/src/file.ts', 'directory/' ) ).toEqual( false ); + } ); +} ); diff --git a/packages/ckeditor5-dev-translations/tests/utils/movetranslationsbetweenpackages.js b/packages/ckeditor5-dev-translations/tests/utils/movetranslationsbetweenpackages.js index 4f40ebde9..43eb1d652 100644 --- a/packages/ckeditor5-dev-translations/tests/utils/movetranslationsbetweenpackages.js +++ b/packages/ckeditor5-dev-translations/tests/utils/movetranslationsbetweenpackages.js @@ -28,14 +28,14 @@ describe( 'moveTranslationsBetweenPackages()', () => { ]; packageContextFoo = { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: Object.fromEntries( packageTranslationsFoo ) }; packageContextBar = { - packagePath: 'packages/ckeditor5-bar', - contextFilePath: 'packages/ckeditor5-bar/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-bar', + contextFilePath: '/absolute/path/to/packages/ckeditor5-bar/lang/contexts.json', contextContent: Object.fromEntries( packageTranslationsBar ) }; @@ -43,8 +43,8 @@ describe( 'moveTranslationsBetweenPackages()', () => { packageContexts: [ packageContextFoo, packageContextBar ], config: [ { - source: 'packages/ckeditor5-foo', - destination: 'packages/ckeditor5-bar', + source: '/absolute/path/to/packages/ckeditor5-foo', + destination: '/absolute/path/to/packages/ckeditor5-bar', messageId: 'id1' } ] @@ -53,13 +53,13 @@ describe( 'moveTranslationsBetweenPackages()', () => { vi.mocked( fs.existsSync ).mockReturnValue( true ); vi.mocked( fs.readFileSync ).mockImplementation( path => { - if ( path.startsWith( 'packages/ckeditor5-foo/lang/translations/' ) ) { + if ( path.startsWith( '/absolute/path/to/packages/ckeditor5-foo/lang/translations/' ) ) { return JSON.stringify( { items: packageTranslationsFoo.map( ( [ msgid, msgctxt ] ) => ( { msgid, msgctxt } ) ) } ); } - if ( path.startsWith( 'packages/ckeditor5-bar/lang/translations/' ) ) { + if ( path.startsWith( '/absolute/path/to/packages/ckeditor5-bar/lang/translations/' ) ) { return JSON.stringify( { items: packageTranslationsBar.map( ( [ msgid, msgctxt ] ) => ( { msgid, msgctxt } ) ) } ); @@ -86,24 +86,24 @@ describe( 'moveTranslationsBetweenPackages()', () => { it( 'should not move translations between packages if source and destination are the same', () => { defaultOptions.config = [ { - source: 'packages/ckeditor5-foo', - destination: 'packages/ckeditor5-foo', + source: '/absolute/path/to/packages/ckeditor5-foo', + destination: '/absolute/path/to/packages/ckeditor5-foo', messageId: 'id1' } ]; moveTranslationsBetweenPackages( defaultOptions ); expect( packageContextFoo ).toEqual( { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: { id1: 'Context for message id1 from "ckeditor5-foo".' } } ); expect( packageContextBar ).toEqual( { - packagePath: 'packages/ckeditor5-bar', - contextFilePath: 'packages/ckeditor5-bar/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-bar', + contextFilePath: '/absolute/path/to/packages/ckeditor5-bar/lang/contexts.json', contextContent: { id2: 'Context for message id2 from "ckeditor5-bar".' } @@ -117,14 +117,14 @@ describe( 'moveTranslationsBetweenPackages()', () => { moveTranslationsBetweenPackages( defaultOptions ); expect( packageContextFoo ).toEqual( { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: {} } ); expect( packageContextBar ).toEqual( { - packagePath: 'packages/ckeditor5-bar', - contextFilePath: 'packages/ckeditor5-bar/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-bar', + contextFilePath: '/absolute/path/to/packages/ckeditor5-bar/lang/contexts.json', contextContent: { id1: 'Context for message id1 from "ckeditor5-foo".', id2: 'Context for message id2 from "ckeditor5-bar".' @@ -138,14 +138,14 @@ describe( 'moveTranslationsBetweenPackages()', () => { moveTranslationsBetweenPackages( defaultOptions ); expect( packageContextFoo ).toEqual( { - packagePath: 'packages/ckeditor5-foo', - contextFilePath: 'packages/ckeditor5-foo/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', + contextFilePath: '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', contextContent: {} } ); expect( packageContextBar ).toEqual( { - packagePath: 'packages/ckeditor5-bar', - contextFilePath: 'packages/ckeditor5-bar/lang/contexts.json', + packagePath: '/absolute/path/to/packages/ckeditor5-bar', + contextFilePath: '/absolute/path/to/packages/ckeditor5-bar/lang/contexts.json', contextContent: { id1: 'Context for message id1 from "ckeditor5-foo".', id2: 'Context for message id2 from "ckeditor5-bar".' @@ -158,13 +158,13 @@ describe( 'moveTranslationsBetweenPackages()', () => { expect( fs.outputJsonSync ).toHaveBeenCalledTimes( 2 ); expect( fs.outputJsonSync ).toHaveBeenCalledWith( - 'packages/ckeditor5-foo/lang/contexts.json', + '/absolute/path/to/packages/ckeditor5-foo/lang/contexts.json', {}, { spaces: '\t' } ); expect( fs.outputJsonSync ).toHaveBeenCalledWith( - 'packages/ckeditor5-bar/lang/contexts.json', + '/absolute/path/to/packages/ckeditor5-bar/lang/contexts.json', { id1: 'Context for message id1 from "ckeditor5-foo".', id2: 'Context for message id2 from "ckeditor5-bar".' @@ -177,17 +177,17 @@ describe( 'moveTranslationsBetweenPackages()', () => { moveTranslationsBetweenPackages( defaultOptions ); expect( glob.sync ).toHaveBeenCalledTimes( 1 ); - expect( glob.sync ).toHaveBeenCalledWith( 'packages/ckeditor5-foo/lang/translations/*.po' ); + expect( glob.sync ).toHaveBeenCalledWith( '/absolute/path/to/packages/ckeditor5-foo/lang/translations/*.po' ); } ); it( 'should parse each translation file', () => { moveTranslationsBetweenPackages( defaultOptions ); expect( fs.readFileSync ).toHaveBeenCalledTimes( 4 ); - expect( fs.readFileSync ).toHaveBeenCalledWith( 'packages/ckeditor5-foo/lang/translations/en.po', 'utf-8' ); - expect( fs.readFileSync ).toHaveBeenCalledWith( 'packages/ckeditor5-foo/lang/translations/pl.po', 'utf-8' ); - expect( fs.readFileSync ).toHaveBeenCalledWith( 'packages/ckeditor5-bar/lang/translations/en.po', 'utf-8' ); - expect( fs.readFileSync ).toHaveBeenCalledWith( 'packages/ckeditor5-bar/lang/translations/pl.po', 'utf-8' ); + expect( fs.readFileSync ).toHaveBeenCalledWith( '/absolute/path/to/packages/ckeditor5-foo/lang/translations/en.po', 'utf-8' ); + expect( fs.readFileSync ).toHaveBeenCalledWith( '/absolute/path/to/packages/ckeditor5-foo/lang/translations/pl.po', 'utf-8' ); + expect( fs.readFileSync ).toHaveBeenCalledWith( '/absolute/path/to/packages/ckeditor5-bar/lang/translations/en.po', 'utf-8' ); + expect( fs.readFileSync ).toHaveBeenCalledWith( '/absolute/path/to/packages/ckeditor5-bar/lang/translations/pl.po', 'utf-8' ); expect( PO.parse ).toHaveBeenCalledTimes( 4 ); expect( PO.parse ).toHaveBeenNthCalledWith( @@ -260,7 +260,7 @@ describe( 'moveTranslationsBetweenPackages()', () => { it( 'should use the source translation file as a base if the destination file does not exist', () => { vi.mocked( fs.existsSync ).mockImplementation( path => { - return path !== 'packages/ckeditor5-bar/lang/translations/pl.po'; + return path !== '/absolute/path/to/packages/ckeditor5-bar/lang/translations/pl.po'; } ); moveTranslationsBetweenPackages( defaultOptions ); @@ -309,22 +309,22 @@ describe( 'moveTranslationsBetweenPackages()', () => { expect( fs.outputFileSync ).toHaveBeenCalledTimes( 4 ); expect( fs.outputFileSync ).toHaveBeenCalledWith( - 'packages/ckeditor5-foo/lang/translations/en.po', + '/absolute/path/to/packages/ckeditor5-foo/lang/translations/en.po', 'Clean PO file content.', 'utf-8' ); expect( fs.outputFileSync ).toHaveBeenCalledWith( - 'packages/ckeditor5-foo/lang/translations/pl.po', + '/absolute/path/to/packages/ckeditor5-foo/lang/translations/pl.po', 'Clean PO file content.', 'utf-8' ); expect( fs.outputFileSync ).toHaveBeenCalledWith( - 'packages/ckeditor5-bar/lang/translations/en.po', + '/absolute/path/to/packages/ckeditor5-bar/lang/translations/en.po', 'Clean PO file content.', 'utf-8' ); expect( fs.outputFileSync ).toHaveBeenCalledWith( - 'packages/ckeditor5-bar/lang/translations/pl.po', + '/absolute/path/to/packages/ckeditor5-bar/lang/translations/pl.po', 'Clean PO file content.', 'utf-8' ); diff --git a/packages/ckeditor5-dev-translations/tests/utils/synchronizetranslationsbasedoncontext.js b/packages/ckeditor5-dev-translations/tests/utils/synchronizetranslationsbasedoncontext.js index a98fefe6b..045327cb7 100644 --- a/packages/ckeditor5-dev-translations/tests/utils/synchronizetranslationsbasedoncontext.js +++ b/packages/ckeditor5-dev-translations/tests/utils/synchronizetranslationsbasedoncontext.js @@ -30,7 +30,7 @@ describe( 'synchronizeTranslationsBasedOnContext()', () => { defaultOptions = { packageContexts: [ { - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', contextContent: { id1: 'Context for example message 1', id2: 'Context for example message 2' @@ -114,7 +114,7 @@ describe( 'synchronizeTranslationsBasedOnContext()', () => { expect( createMissingPackageTranslations ).toHaveBeenCalledTimes( 1 ); expect( createMissingPackageTranslations ).toHaveBeenCalledWith( { - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', skipLicenseHeader: false } ); } ); @@ -126,7 +126,7 @@ describe( 'synchronizeTranslationsBasedOnContext()', () => { expect( createMissingPackageTranslations ).toHaveBeenCalledTimes( 1 ); expect( createMissingPackageTranslations ).toHaveBeenCalledWith( { - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', skipLicenseHeader: true } ); } ); @@ -134,7 +134,7 @@ describe( 'synchronizeTranslationsBasedOnContext()', () => { it( 'should not update any files when package does not contain translation context', () => { defaultOptions.packageContexts = [ { - packagePath: 'packages/ckeditor5-foo', + packagePath: '/absolute/path/to/packages/ckeditor5-foo', contextContent: {} } ]; @@ -149,7 +149,7 @@ describe( 'synchronizeTranslationsBasedOnContext()', () => { synchronizeTranslationsBasedOnContext( defaultOptions ); expect( glob.sync ).toHaveBeenCalledTimes( 1 ); - expect( glob.sync ).toHaveBeenCalledWith( 'packages/ckeditor5-foo/lang/translations/*.po' ); + expect( glob.sync ).toHaveBeenCalledWith( '/absolute/path/to/packages/ckeditor5-foo/lang/translations/*.po' ); } ); it( 'should parse each translation file', () => { @@ -160,8 +160,8 @@ describe( 'synchronizeTranslationsBasedOnContext()', () => { synchronizeTranslationsBasedOnContext( defaultOptions ); expect( fs.readFileSync ).toHaveBeenCalledTimes( 2 ); - expect( fs.readFileSync ).toHaveBeenCalledWith( 'packages/ckeditor5-foo/lang/translations/en.po', 'utf-8' ); - expect( fs.readFileSync ).toHaveBeenCalledWith( 'packages/ckeditor5-foo/lang/translations/zh-tw.po', 'utf-8' ); + expect( fs.readFileSync ).toHaveBeenCalledWith( '/absolute/path/to/packages/ckeditor5-foo/lang/translations/en.po', 'utf-8' ); + expect( fs.readFileSync ).toHaveBeenCalledWith( '/absolute/path/to/packages/ckeditor5-foo/lang/translations/zh-tw.po', 'utf-8' ); } ); it( 'should update file header', () => { @@ -308,7 +308,7 @@ describe( 'synchronizeTranslationsBasedOnContext()', () => { expect( fs.writeFileSync ).toHaveBeenCalledTimes( 1 ); expect( fs.writeFileSync ).toHaveBeenCalledWith( - 'packages/ckeditor5-foo/lang/translations/en.po', + '/absolute/path/to/packages/ckeditor5-foo/lang/translations/en.po', 'Clean PO file content.', 'utf-8' );