Add localization test to a module
It is a good idea to test completeness of localization files. Such tests prevent incomplete and incorrect app localization.
In CzechIdM, we use localization files <language>.json
to define text descriptions in application for different languages.
When we write localization messages for more than one language, one common mistake usually appears: missing path to localization message in one of the languages.
To prevent this we use our own TestHelper.js
utility. You can find it here. TODO:link czechidm-core/src/utils/TestHelper.js
Path to a localization message
This is how <language>.json
file looks like:
{ "app": { "name": "CzechIdM", "author": { "name": "BCV solutions s.r.o.", "homePage": "http://www.bcvsolutions.eu" } } }
A file contains a number of "paths" to localization messages (we extract them with a help of JSONPath
library). Paths for the file above look like:
['app'] ['app']['name'] ['app']['author'] ['app']['author']['name'] ['app']['author']['homePage']
Localization test
Whole test runs on lists of localization paths. Those lists are built from the root of JSON document, depth-first.
This test works specifically with CS.json
and EN.json
files. The utility, basically, compares paths to every single localization message.
Test runs when you start building frontend part of CzechIdM (using gulp). If there is a localization missing in one of JSON files (and, therefore, in a paths list), frontend app build will fail and the utility will show missing localization paths. Successful test result is similar to the output below:
[2018-03-09 13:35:46.277] [DEBUG] [default] - acc: Comparing JSON catalogs - ok [2018-03-09 13:35:46.480] [DEBUG] [default] - core: Comparing JSON catalogs - ok [2018-03-09 13:35:46.658] [DEBUG] [default] - example: Comparing JSON catalogs - ok [2018-03-09 13:35:46.663] [DEBUG] [default] - vs: Comparing JSON catalogs - ok [2018-03-09 13:35:46.667] [DEBUG] [default] - rpt: Comparing JSON catalogs - ok
Localization of singulars
When we translate a singular noun, paths lists are checked whether they both contain particular localization path (e.g. "[app][roles][user]"). If they do, everything is OK. If they do not contain the localization path, a message is logged. Because localization paths lists are ordered, the algorithm marks the positions in lists where the paths match again. Everything on positions between two matching paths is logged.
Plural localizations
Exception is in singular and plural description. When the plural is recognized, it will check if CS and EN are in match despite different properties. CS messages are specified by number behind underscore and EN messages ends with word plural behind the underscore. If it has plural amount, paths to localizations should end in this forms:
CS
example_0 (optional) example_1 example_2 example_5
EN
example_0 (optional) example example_plural
Comparison
*Table: how program compares plural messages*
Messages that ends with _0 are optional but if its found in CS or EN language, it's also checked for pair in other language.
Adding localization test to a module
Not every application module contains messages that need to be translated. On the other hand, some of the modules do. That is why you have to explicitly add the localization test to a module.
- Create file
Localization-test.js
in "<module>/test/localization/". - Constants "cs" and "en" should point to localization files in the module. The path in example code (below) should fit most cases.
- Insert following code into
Localization-test.js
file:
- Localization-test.js
import chai, { expect } from 'chai'; import dirtyChai from 'dirty-chai'; import { LocalizationTester } from 'czechidm-core/src/utils/TestHelper'; chai.use(dirtyChai); /** * Validate localization * * @author Radek Tomiška */ describe('Comparing JSON catalogs', function test() { it('- vs', function validate() { const cs = require('../../src/locales/cs.json'); const en = require('../../src/locales/en.json'); // const localizationTester = new LocalizationTester(); expect(localizationTester.compareMessages(cs, en)).to.be.true(); LOGGER.debug('vs: Comparing JSON catalogs - ok'); }); });