ensuring internal variables of common module are not changed by providing getter functions, splitting out I18n tests
This commit is contained in:
parent
dfd906900b
commit
3fed63ce28
3 changed files with 174 additions and 42 deletions
96
js/common.js
96
js/common.js
|
@ -1,43 +1,12 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
exports.a2zString = ['a','b','c','d','e','f','g','h','i','j','k','l','m',
|
// testing prerequisites
|
||||||
'n','o','p','q','r','s','t','u','v','w','x','y','z'];
|
|
||||||
exports.alnumString = exports.a2zString.concat(['0','1','2','3','4','5','6','7','8','9']);
|
|
||||||
exports.queryString = exports.alnumString.concat(['+','%','&','.','*','-','_']);
|
|
||||||
exports.base64String = exports.alnumString.concat(['+','/','=']).concat(
|
|
||||||
exports.a2zString.map(function(c) {
|
|
||||||
return c.toUpperCase();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
// schemas supported by the whatwg-url library
|
|
||||||
exports.schemas = ['ftp','gopher','http','https','ws','wss'];
|
|
||||||
exports.supportedLanguages = ['de', 'es', 'fr', 'it', 'no', 'pl', 'pt', 'oc', 'ru', 'sl', 'zh'];
|
|
||||||
exports.mimeTypes = ['image/png', 'application/octet-stream'];
|
|
||||||
|
|
||||||
global.jsc = require('jsverify');
|
global.jsc = require('jsverify');
|
||||||
global.jsdom = require('jsdom-global');
|
global.jsdom = require('jsdom-global');
|
||||||
global.cleanup = global.jsdom();
|
global.cleanup = global.jsdom();
|
||||||
global.fs = require('fs');
|
global.fs = require('fs');
|
||||||
|
|
||||||
/**
|
// application libraries to test
|
||||||
* character to HTML entity lookup table
|
|
||||||
*
|
|
||||||
* @see {@link https://github.com/janl/mustache.js/blob/master/mustache.js#L60}
|
|
||||||
*/
|
|
||||||
var entityMap = {
|
|
||||||
'&': '&',
|
|
||||||
'<': '<',
|
|
||||||
'>': '>',
|
|
||||||
'"': '"',
|
|
||||||
"'": ''',
|
|
||||||
'/': '/',
|
|
||||||
'`': '`',
|
|
||||||
'=': '='
|
|
||||||
},
|
|
||||||
logFile = fs.createWriteStream('test.log'),
|
|
||||||
mimeFile = fs.createReadStream('/etc/mime.types'),
|
|
||||||
mimeLine = '';
|
|
||||||
|
|
||||||
global.$ = global.jQuery = require('./jquery-3.1.1');
|
global.$ = global.jQuery = require('./jquery-3.1.1');
|
||||||
global.sjcl = require('./sjcl-1.0.6');
|
global.sjcl = require('./sjcl-1.0.6');
|
||||||
global.Base64 = require('./base64-2.1.9').Base64;
|
global.Base64 = require('./base64-2.1.9').Base64;
|
||||||
|
@ -51,6 +20,38 @@ global.DOMPurify = require('./purify.min');
|
||||||
require('./bootstrap-3.3.7');
|
require('./bootstrap-3.3.7');
|
||||||
require('./privatebin');
|
require('./privatebin');
|
||||||
|
|
||||||
|
// internal variables
|
||||||
|
var a2zString = ['a','b','c','d','e','f','g','h','i','j','k','l','m',
|
||||||
|
'n','o','p','q','r','s','t','u','v','w','x','y','z'],
|
||||||
|
alnumString = a2zString.concat(['0','1','2','3','4','5','6','7','8','9']),
|
||||||
|
queryString = alnumString.concat(['+','%','&','.','*','-','_']),
|
||||||
|
base64String = alnumString.concat(['+','/','=']).concat(
|
||||||
|
a2zString.map(function(c) {
|
||||||
|
return c.toUpperCase();
|
||||||
|
})
|
||||||
|
),
|
||||||
|
schemas = ['ftp','gopher','http','https','ws','wss'],
|
||||||
|
supportedLanguages = ['de', 'es', 'fr', 'it', 'no', 'pl', 'pt', 'oc', 'ru', 'sl', 'zh'],
|
||||||
|
mimeTypes = ['image/png', 'application/octet-stream'],
|
||||||
|
/**
|
||||||
|
* character to HTML entity lookup table
|
||||||
|
*
|
||||||
|
* @see {@link https://github.com/janl/mustache.js/blob/master/mustache.js#L60}
|
||||||
|
*/
|
||||||
|
entityMap = {
|
||||||
|
'&': '&',
|
||||||
|
'<': '<',
|
||||||
|
'>': '>',
|
||||||
|
'"': '"',
|
||||||
|
"'": ''',
|
||||||
|
'/': '/',
|
||||||
|
'`': '`',
|
||||||
|
'=': '='
|
||||||
|
},
|
||||||
|
logFile = fs.createWriteStream('test.log'),
|
||||||
|
mimeFile = fs.createReadStream('/etc/mime.types'),
|
||||||
|
mimeLine = '';
|
||||||
|
|
||||||
// redirect console messages to log file
|
// redirect console messages to log file
|
||||||
console.info = console.warn = console.error = function () {
|
console.info = console.warn = console.error = function () {
|
||||||
logFile.write(Array.prototype.slice.call(arguments).join('') + '\n');
|
logFile.write(Array.prototype.slice.call(arguments).join('') + '\n');
|
||||||
|
@ -87,10 +88,12 @@ function parseMime(line) {
|
||||||
line = line.substring(0, index);
|
line = line.substring(0, index);
|
||||||
}
|
}
|
||||||
if (line.length > 0) {
|
if (line.length > 0) {
|
||||||
exports.mimeTypes.push(line);
|
mimeTypes.push(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// common testing helper functions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* convert all applicable characters to HTML entities
|
* convert all applicable characters to HTML entities
|
||||||
*
|
*
|
||||||
|
@ -107,3 +110,28 @@ exports.htmlEntities = function(str) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// provides random lowercase characters from a to z
|
||||||
|
exports.jscA2zString = function() {
|
||||||
|
return jsc.elements(a2zString);
|
||||||
|
}
|
||||||
|
|
||||||
|
// provides random lowercase alpha numeric characters (a to z and 0 to 9)
|
||||||
|
exports.jscAlnumString = function() {
|
||||||
|
return jsc.elements(alnumString);
|
||||||
|
}
|
||||||
|
|
||||||
|
// provides random characters allowed in GET queries
|
||||||
|
exports.jscQueryString = function() {
|
||||||
|
return jsc.elements(queryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
// provides a random URL schema supported by the whatwg-url library
|
||||||
|
exports.jscSchemas = function() {
|
||||||
|
return jsc.elements(schemas);
|
||||||
|
}
|
||||||
|
|
||||||
|
// provides a random supported language string
|
||||||
|
exports.jscSupportedLanguages = function() {
|
||||||
|
return jsc.elements(supportedLanguages);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ describe('Helper', function () {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'selection contains content of given ID',
|
'selection contains content of given ID',
|
||||||
jsc.nearray(jsc.nearray(jsc.elements(common.alnumString))),
|
jsc.nearray(jsc.nearray(common.jscAlnumString())),
|
||||||
'nearray string',
|
'nearray string',
|
||||||
function (ids, contents) {
|
function (ids, contents) {
|
||||||
var html = '',
|
var html = '',
|
||||||
|
@ -90,9 +90,9 @@ describe('Helper', function () {
|
||||||
'replaces URLs with anchors',
|
'replaces URLs with anchors',
|
||||||
'string',
|
'string',
|
||||||
jsc.elements(['http', 'https', 'ftp']),
|
jsc.elements(['http', 'https', 'ftp']),
|
||||||
jsc.nearray(jsc.elements(common.a2zString)),
|
jsc.nearray(common.jscA2zString()),
|
||||||
jsc.array(jsc.elements(common.queryString)),
|
jsc.array(common.jscQueryString()),
|
||||||
jsc.array(jsc.elements(common.queryString)),
|
jsc.array(common.jscQueryString()),
|
||||||
'string',
|
'string',
|
||||||
function (prefix, schema, address, query, fragment, postfix) {
|
function (prefix, schema, address, query, fragment, postfix) {
|
||||||
var query = query.join(''),
|
var query = query.join(''),
|
||||||
|
@ -117,7 +117,7 @@ describe('Helper', function () {
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'replaces magnet links with anchors',
|
'replaces magnet links with anchors',
|
||||||
'string',
|
'string',
|
||||||
jsc.array(jsc.elements(common.queryString)),
|
jsc.array(common.jscQueryString()),
|
||||||
'string',
|
'string',
|
||||||
function (prefix, query, postfix) {
|
function (prefix, query, postfix) {
|
||||||
var url = 'magnet:?' + query.join('').replace(/^&+|&+$/gm,''),
|
var url = 'magnet:?' + query.join('').replace(/^&+|&+$/gm,''),
|
||||||
|
@ -244,9 +244,9 @@ describe('Helper', function () {
|
||||||
|
|
||||||
jsc.property(
|
jsc.property(
|
||||||
'returns the URL without query & fragment',
|
'returns the URL without query & fragment',
|
||||||
jsc.elements(common.schemas),
|
common.jscSchemas(),
|
||||||
jsc.nearray(jsc.elements(common.a2zString)),
|
jsc.nearray(common.jscA2zString()),
|
||||||
jsc.array(jsc.elements(common.queryString)),
|
jsc.array(common.jscQueryString()),
|
||||||
'string',
|
'string',
|
||||||
function (schema, address, query, fragment) {
|
function (schema, address, query, fragment) {
|
||||||
var expected = schema + '://' + address.join('') + '/',
|
var expected = schema + '://' + address.join('') + '/',
|
||||||
|
|
104
js/test/I18n.js
Normal file
104
js/test/I18n.js
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
'use strict';
|
||||||
|
var common = require('../common');
|
||||||
|
|
||||||
|
describe('I18n', function () {
|
||||||
|
describe('translate', function () {
|
||||||
|
before(function () {
|
||||||
|
$.PrivateBin.I18n.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'returns message ID unchanged if no translation found',
|
||||||
|
'string',
|
||||||
|
function (messageId) {
|
||||||
|
messageId = messageId.replace(/%(s|d)/g, '%%');
|
||||||
|
var plurals = [messageId, messageId + 's'],
|
||||||
|
fake = [messageId],
|
||||||
|
result = $.PrivateBin.I18n.translate(messageId);
|
||||||
|
$.PrivateBin.I18n.reset();
|
||||||
|
|
||||||
|
var alias = $.PrivateBin.I18n._(messageId);
|
||||||
|
$.PrivateBin.I18n.reset();
|
||||||
|
|
||||||
|
var p_result = $.PrivateBin.I18n.translate(plurals);
|
||||||
|
$.PrivateBin.I18n.reset();
|
||||||
|
|
||||||
|
var p_alias = $.PrivateBin.I18n._(plurals);
|
||||||
|
$.PrivateBin.I18n.reset();
|
||||||
|
|
||||||
|
var f_result = $.PrivateBin.I18n.translate(fake);
|
||||||
|
$.PrivateBin.I18n.reset();
|
||||||
|
|
||||||
|
var f_alias = $.PrivateBin.I18n._(fake);
|
||||||
|
$.PrivateBin.I18n.reset();
|
||||||
|
|
||||||
|
return messageId === result && messageId === alias &&
|
||||||
|
messageId === p_result && messageId === p_alias &&
|
||||||
|
messageId === f_result && messageId === f_alias;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
jsc.property(
|
||||||
|
'replaces %s in strings with first given parameter',
|
||||||
|
'string',
|
||||||
|
'(small nearray) string',
|
||||||
|
'string',
|
||||||
|
function (prefix, params, postfix) {
|
||||||
|
prefix = prefix.replace(/%(s|d)/g, '%%');
|
||||||
|
params[0] = params[0].replace(/%(s|d)/g, '%%');
|
||||||
|
postfix = postfix.replace(/%(s|d)/g, '%%');
|
||||||
|
var translation = prefix + params[0] + postfix;
|
||||||
|
params.unshift(prefix + '%s' + postfix);
|
||||||
|
var result = $.PrivateBin.I18n.translate.apply(this, params);
|
||||||
|
$.PrivateBin.I18n.reset();
|
||||||
|
var alias = $.PrivateBin.I18n._.apply(this, params);
|
||||||
|
$.PrivateBin.I18n.reset();
|
||||||
|
return translation === result && translation === alias;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getPluralForm', function () {
|
||||||
|
before(function () {
|
||||||
|
$.PrivateBin.I18n.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'returns valid key for plural form',
|
||||||
|
common.jscSupportedLanguages(),
|
||||||
|
'integer',
|
||||||
|
function(language, n) {
|
||||||
|
$.PrivateBin.I18n.reset(language);
|
||||||
|
var result = $.PrivateBin.I18n.getPluralForm(n);
|
||||||
|
// arabic seems to have the highest plural count with 6 forms
|
||||||
|
return result >= 0 && result <= 5;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// loading of JSON via AJAX needs to be tested in the browser, this just mocks it
|
||||||
|
// TODO: This needs to be tested using a browser.
|
||||||
|
describe('loadTranslations', function () {
|
||||||
|
this.timeout(30000);
|
||||||
|
before(function () {
|
||||||
|
$.PrivateBin.I18n.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
jsc.property(
|
||||||
|
'downloads and handles any supported language',
|
||||||
|
common.jscSupportedLanguages(),
|
||||||
|
function(language) {
|
||||||
|
var clean = jsdom('', {url: 'https://privatebin.net/', cookie: ['lang=' + language]});
|
||||||
|
|
||||||
|
$.PrivateBin.I18n.reset('en');
|
||||||
|
$.PrivateBin.I18n.loadTranslations();
|
||||||
|
$.PrivateBin.I18n.reset(language, require('../../i18n/' + language + '.json'));
|
||||||
|
var result = $.PrivateBin.I18n.translate('en'),
|
||||||
|
alias = $.PrivateBin.I18n._('en');
|
||||||
|
|
||||||
|
clean();
|
||||||
|
return language === result && language === alias;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue