feat(i18n/build): add grunt task for translation extraction

Use `grunt extract-translations` to run extraction.
Will run all test cases to extract the available translations.

Closes #497
This commit is contained in:
Vladimirs Katusenoks 2016-05-03 16:23:31 +02:00 committed by Nico Rehwaldt
parent 30e3fdd81c
commit 28cc4e8e10
10 changed files with 202 additions and 3 deletions

View File

@ -50,6 +50,23 @@ module.exports = function(grunt) {
browsers: TEST_BROWSERS
},
unit: {
browsers: TEST_BROWSERS
},
translations: {
singleRun: true,
autoWatch: false,
reporters: [ 'dots', 'translation-reporter' ],
plugins: [
'karma-*',
require('./test/config/translation-reporter')
],
envPreprocessor: [
'TRANSLATIONS'
],
browsers: TEST_BROWSERS
}
},
@ -91,6 +108,7 @@ module.exports = function(grunt) {
// tasks
grunt.registerTask('extract-translations', [ 'karma:translations' ]);
grunt.registerTask('test', [ 'karma:single' ]);

98
docs/translations.json Normal file
View File

@ -0,0 +1,98 @@
[
"Activate the create/remove space tool",
"Activate the global connect tool",
"Activate the hand tool",
"Activate the lasso tool",
"Ad-hoc",
"Append compensation activity",
"Append {type}",
"Business Rule Task",
"Call Activity",
"Cancel Boundary Event",
"Cancel End Event",
"Change type",
"Compensation Boundary Event",
"Compensation End Event",
"Compensation Intermediate Throw Event",
"Compensation Start Event",
"Complex Gateway",
"Conditional Boundary Event",
"Conditional Boundary Event (non-interrupting)",
"Conditional Flow",
"Conditional Intermediate Catch Event",
"Conditional Start Event",
"Conditional Start Event (non-interrupting)",
"Connect using Association",
"Connect using DataInputAssociation",
"Connect using Sequence/MessageFlow or Association",
"Create IntermediateThrowEvent/BoundaryEvent",
"Create Pool/Participant",
"Create expanded SubProcess",
"Create {type}",
"Default Flow",
"End Event",
"Error Boundary Event",
"Error End Event",
"Error Start Event",
"Escalation Boundary Event",
"Escalation Boundary Event (non-interrupting)",
"Escalation End Event",
"Escalation Intermediate Throw Event",
"Escalation Start Event",
"Escalation Start Event (non-interrupting)",
"Event Sub Process",
"Exclusive Gateway",
"HELLO {you}!",
"Inclusive Gateway",
"Intermediate Throw Event",
"Link Intermediate Catch Event",
"Link Intermediate Throw Event",
"Loop",
"Manual Task",
"Message Boundary Event",
"Message Boundary Event (non-interrupting)",
"Message End Event",
"Message Intermediate Catch Event",
"Message Intermediate Throw Event",
"Message Start Event",
"Message Start Event (non-interrupting)",
"Parallel Gateway",
"Parallel Multi Instance",
"Receive Task",
"Remove",
"Script Task",
"Send Task",
"Sequence Flow",
"Sequential Multi Instance",
"Service Task",
"Signal Boundary Event",
"Signal Boundary Event (non-interrupting)",
"Signal End Event",
"Signal Intermediate Catch Event",
"Signal Intermediate Throw Event",
"Signal Start Event",
"Signal Start Event (non-interrupting)",
"Start Event",
"Sub Process",
"Sub Process (collapsed)",
"Sub Process (expanded)",
"Task",
"Terminate End Event",
"Timer Boundary Event",
"Timer Boundary Event (non-interrupting)",
"Timer Intermediate Catch Event",
"Timer Start Event",
"Timer Start Event (non-interrupting)",
"Transaction",
"User Task",
"correcting missing bpmnElement on {plane} to {rootElement}",
"element {element} referenced by {referenced}#{property} not yet drawn",
"failed to import {element}",
"flow elements must be children of pools/participants",
"missing {semantic}#attachedToRef",
"multiple DI elements defined for {element}",
"no bpmnElement referenced in {element}",
"no diagram to display",
"no process or collaboration to display",
"participants cannot be pasted onto a non-empty process diagram"
]

View File

@ -45,6 +45,7 @@
"karma-browserify": "^5.0.1",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^0.2.2",
"karma-env-preprocessor": "^0.1.1",
"karma-firefox-launcher": "^0.1.3",
"karma-ie-launcher": "^0.2.0",
"karma-mocha": "~0.1.0",

View File

@ -24,7 +24,7 @@ module.exports = function(karma) {
],
preprocessors: {
'test/**/*Spec.js': [ 'browserify' ]
'test/**/*Spec.js': [ 'browserify', 'env' ]
},
reporters: [ 'dots' ],

View File

@ -0,0 +1,48 @@
'use strict';
var fs = require( 'fs' );
var path = require('path');
var unique = require('lodash/array/unique');
var sortBy = require('lodash/collection/sortBy');
var TranslationReporter = function() {
process.env.TRANSLATIONS = 'enabled';
var outputFile = path.join(__dirname, '../../docs/translations.json');
var translations = [];
this.onBrowserLog = function(browser, log, type) {
if ( log === undefined || typeof log !== 'string' ) {
return;
}
if ( log.substring( 0, 1 ) === '\'' ) {
log = log.substring( 1, log.length - 1 );
}
try {
var obj = JSON.parse(log);
if (obj.type === 'translations') {
translations.push(obj.msg);
}
} catch (e) {
return;
}
};
this.onRunComplete = function () {
translations = unique(translations);
translations = sortBy(translations);
fs.writeFileSync(outputFile, JSON.stringify(translations, null, 2));
};
};
module.exports = {
'reporter:translation-reporter' : [ 'type', TranslationReporter ]
};

View File

@ -0,0 +1,18 @@
'use strict';
var translate = require('diagram-js/lib/i18n/translate/translate');
function collectTranslations(template, replacements) {
var log = {
type: 'translations',
msg: template
};
console.log(JSON.stringify(log));
return translate(template, replacements);
}
module.exports = {
translate: [ 'value', collectTranslations ]
};

View File

@ -40,6 +40,9 @@ var Modeler = require('../../lib/Modeler'),
var OPTIONS, BPMN_JS;
var translationModule = require('./TranslationCollector');
function bootstrapBpmnJS(BpmnJS, diagram, options, locals) {
return function(done) {
@ -99,6 +102,12 @@ function bootstrapBpmnJS(BpmnJS, diagram, options, locals) {
_options.modules = undefined;
}
// used to extract translations used during tests
if (window.__env__ && window.__env__.TRANSLATIONS === 'enabled') {
_options.additionalModules = [].concat(_options.additionalModules || [], [ translationModule ]);
_options.additionalModules = unique(_options.additionalModules);
}
BPMN_JS = new BpmnJS(_options);
BPMN_JS.importXML(diagram, done);

View File

@ -1,7 +1,8 @@
'use strict';
/* global inject, bootstrapModeler */
require('../../../../TestHelper');
/* global inject, bootstrapModeler */
var modelingModule = require('../../../../../lib/features/modeling');

View File

@ -1,6 +1,6 @@
'use strict';
var TestHelper = require('../../../../TestHelper');
require('../../../../TestHelper');
/* global bootstrapModeler, inject */

View File

@ -1,5 +1,10 @@
'use strict';
if (window.__env__ && window.__env__.TRANSLATIONS === 'enabled') {
// skipping during translation extraction
return;
}
require('test/TestHelper');
/* global bootstrapModeler, inject */
@ -16,6 +21,7 @@ var diagramXML = require('test/fixtures/bpmn/simple.bpmn');
describe('i18n - translate', function() {
beforeEach(bootstrapModeler(diagramXML, {
modules: [
coreModule,