mediawiki-extensions-Templa.../tests/ext.templateData.tests.js
Ed Sanders 5c7f50de62 Show param label in list if available
It looks like this is how the code was originally intended,
but 'name' and 'key' are the same thing.

Move the key to the 'alias' list where CSS already exists to
colour it differently.

Change-Id: Ieade122633cec14203f7959121e9cd7250bb9f7a
2016-02-21 02:43:54 +00:00

643 lines
17 KiB
JavaScript

/**
* TemplateData Generator GUI Unit Tests
*/
( function () {
'use strict';
var i, testVars, finalJsonStringParams, finalJsonStringOnly,
resultDescCurrLang, resultDescMockLang, resultDescBothLang, currLanguage, originalWikitext;
QUnit.module( 'ext.templateData', QUnit.newMwEnvironment() );
resultDescCurrLang = {};
resultDescMockLang = {};
resultDescBothLang = {};
currLanguage = mw.config.get( 'wgContentLanguage' ) || 'en';
originalWikitext = 'Some text here that is not templatedata information.' +
'<templatedata>' +
'{' +
' "description": {\n' +
' "' + currLanguage + '": "Label unsigned comments in a conversation.",\n' +
' "blah": "Template description in some blah language."\n' +
' },' +
' "params": {' +
' "user": {' +
' "label": "Username",' +
' "type": "wiki-user-name",' +
' "required": true,' +
' "description": "User name of person who forgot to sign their comment.",' +
' "aliases": ["1"]' +
' },' +
' "date": {' +
' "label": "Date",' +
' "description": {' +
' "en": "Timestamp of when the comment was posted, in YYYY-MM-DD format."' +
' },' +
' "aliases": ["2"],' +
' "autovalue": "{{subst:CURRENTMONTHNAME}}",' +
' "suggested": true' +
' },' +
' "year": {' +
' "label": "Year",' +
' "type": "number"' +
' },' +
' "month": {' +
' "label": "Month",' +
' "inherits": "year"' +
' },' +
' "day": {' +
' "label": "Day",' +
' "inherits": "year"' +
' },' +
' "comment": {' +
' "required": false' +
' }' +
' },' +
' "sets": [' +
' {' +
' "label": "Date",' +
' "params": ["year", "month", "day"]' +
' }' +
' ]' +
'}' +
'</templatedata>' +
'Trailing text at the end.';
// Prepare description language objects
resultDescCurrLang[ currLanguage ] = 'Some string here in ' + currLanguage + ' language.';
resultDescMockLang.blah = 'Some string here in blah language.';
resultDescBothLang = $.extend( {}, resultDescCurrLang, resultDescMockLang );
finalJsonStringParams = ' "params": {\n' +
' "user": {\n' +
' "label": "Username",\n' +
' "type": "wiki-user-name",\n' +
' "required": true,\n' +
' "description": "User name of person who forgot to sign their comment.",\n' +
' "aliases": [\n' +
' "1"\n' +
' ]\n' +
' },\n' +
' "date": {\n' +
' "label": "Date",\n' +
' "description": {\n' +
' "en": "Timestamp of when the comment was posted, in YYYY-MM-DD format."\n' +
' },\n' +
' "aliases": [\n' +
' "2"\n' +
' ],\n' +
' "autovalue": "{{subst:CURRENTMONTHNAME}}",\n' +
' "suggested": true\n' +
' },\n' +
' "year": {\n' +
' "label": "Year",\n' +
' "type": "number"\n' +
' },\n' +
' "month": {\n' +
' "label": "Month",\n' +
' "inherits": "year"\n' +
' },\n' +
' "comment": {\n' +
' "required": false,\n' +
' "type": "wiki-page-name"\n' +
' },\n' +
' "newParam1": {\n' +
' "description": {\n' +
' "' + currLanguage + '": "Some string here in ' + currLanguage + ' language.",\n' +
' "blah": "Some string here in blah language."\n' +
' },\n' +
' "required": true\n' +
' },\n' +
' "newParam2": {},\n' +
' "newParam3": {\n' +
' "description": "Some string here in ' + currLanguage + ' language.",\n' +
' "deprecated": "This is deprecated."\n' +
' },\n' +
' "newParam4": {\n' +
' "description": {\n' +
' "' + currLanguage + '": "' + resultDescBothLang[ currLanguage ] + '",\n' +
' "blah": "' + resultDescBothLang.blah + '"\n' +
' }\n' +
' }\n' +
' },\n';
finalJsonStringOnly = '{\n' +
' "description": {\n' +
' "' + currLanguage + '": "Label unsigned comments in a conversation.",\n' +
' "blah": "Template description in some blah language."\n' +
' },\n' + finalJsonStringParams +
' "sets": [\n' +
' {\n' +
' "label": "Date",\n' +
' "params": [\n' +
' "year",\n' +
' "month",\n' +
' "day"\n' +
' ]\n' +
' }\n' +
' ],\n' +
' "format": "inline"\n' +
'}';
// Test validation tools
QUnit.test( 'Validation tools', function ( assert ) {
var tests = {
compare: [
{
obj1: {},
obj2: [],
result: false,
msg: 'Compare: object vs array'
},
{
obj1: null,
obj2: undefined,
result: false,
msg: 'Compare: null vs undefined'
},
{
obj1: 'string',
obj2: undefined,
result: false,
msg: 'Compare: string vs undefined'
},
{
obj1: undefined,
obj2: undefined,
result: true,
msg: 'Compare: undefined vs undefined'
},
{
obj1: null,
obj2: null,
result: true,
msg: 'Compare: null vs null'
},
{
obj1: 'A proper string.',
obj2: 'A proper string.',
result: true,
msg: 'Compare: strings'
},
{
obj1: true,
obj2: true,
result: true,
msg: 'Compare: booleans'
},
{
obj1: { 1: 'string', 2: 'another', 4: 'and another' },
obj2: { 1: 'string', 2: 'another', 4: 'and another' },
result: true,
allowSubset: true,
msg: 'Compare: plain object full equality'
},
{
obj1: { 1: 'string', 2: 'another', 4: 'and another' },
obj2: { 1: 'another', 2: 'and another', 4: 'string' },
result: false,
allowSubset: true,
msg: 'Compare: plain object full inequality'
},
{
obj1: { 1: 'string', 2: 'another', 4: 'and another' },
obj2: { 4: 'and another' },
result: true,
allowSubset: true,
msg: 'Compare: plain object subset equality'
},
{
obj1: [ 'val1', 'val2', 'val3' ],
obj2: [ 'val1', 'val2', 'val3' ],
result: true,
msg: 'Compare: arrays'
},
{
obj1: [ 'val1', 'val2', 'val3' ],
obj2: [ 'val1' ],
result: true,
allowSubset: true,
msg: 'Compare: array subset: true'
},
{
obj1: [ 'val1', 'val2', 'val3' ],
obj2: [ 'val1' ],
result: false,
allowSubset: false,
msg: 'Compare: array subset: false'
},
{
obj1: {
param1: {
type: 'undefined',
aliases: [ 'alias2', 'alias1', 'alias3' ],
description: 'Some description',
required: true,
suggested: false
},
param2: {
required: true
}
},
obj2: {
param1: {
type: 'undefined',
aliases: [ 'alias2', 'alias1', 'alias3' ],
description: 'Some description',
required: true,
suggested: false
},
param2: {
required: true
}
},
result: true,
allowSubset: true,
msg: 'Compare: complex objects'
},
{
obj1: {
param1: {
type: 'undefined',
aliases: [ 'alias1', 'alias2', 'alias3' ],
description: 'Some description',
required: true,
suggested: false
},
param2: {
required: true
}
},
obj2: {
param1: {
aliases: [ 'alias1', 'alias2', 'alias3' ],
suggested: false
}
},
result: true,
allowSubset: true,
msg: 'Compare: complex objects subset'
}
],
splitAndTrimArray: [
{
string: 'str1 , str2 ',
delim: ',',
result: [ 'str1', 'str2' ],
msg: 'splitAndTrimArray: split and trim'
},
{
string: 'str1, str2, , , , str3',
delim: ',',
result: [ 'str1', 'str2', 'str3' ],
msg: 'splitAndTrimArray: remove empty values'
},
{
string: 'str1|str2|str3',
delim: '|',
result: [ 'str1', 'str2', 'str3' ],
msg: 'splitAndTrimArray: different delimeter'
}
],
arrayUnionWithoutEmpty: [
{
arrays: [ [ 'en', 'he', '' ], [ 'he', 'de', '' ], [ 'en', 'de' ] ],
result: [ 'en', 'he', 'de' ],
msg: 'arrayUnionWithoutEmpty: Remove duplications'
},
{
arrays: [ [ 'en', '', '' ], [ 'he', '', '' ], [ 'de', '' ] ],
result: [ 'en', 'he', 'de' ],
msg: 'arrayUnionWithoutEmpty: Remove empty values'
}
],
props: {
all: [
'name',
'aliases',
'label',
'description',
'example',
'type',
'default',
'autovalue',
'deprecated',
'deprecatedValue',
'required',
'suggested'
],
language: [
'label',
'description',
'example',
'default'
]
}
};
QUnit.expect(
tests.compare.length +
tests.splitAndTrimArray.length +
tests.arrayUnionWithoutEmpty.length +
Object.keys( tests.props ).length
);
// Compare
for ( i = 0; i < tests.compare.length; i++ ) {
testVars = tests.compare[ i ];
assert.equal(
mw.TemplateData.Model.static.compare( testVars.obj1, testVars.obj2, testVars.allowSubset ),
testVars.result,
testVars.msg
);
}
// Split and trim
for ( i = 0; i < tests.splitAndTrimArray.length; i++ ) {
testVars = tests.splitAndTrimArray[ i ];
assert.deepEqual(
mw.TemplateData.Model.static.splitAndTrimArray( testVars.string, testVars.delim ),
testVars.result,
testVars.msg
);
}
// arrayUnionWithoutEmpty
for ( i = 0; i < tests.arrayUnionWithoutEmpty.length; i++ ) {
testVars = tests.arrayUnionWithoutEmpty[ i ];
assert.deepEqual(
mw.TemplateData.Model.static.arrayUnionWithoutEmpty.apply( testVars, testVars.arrays ),
testVars.result,
testVars.msg
);
}
// Props
assert.deepEqual(
mw.TemplateData.Model.static.getAllProperties( false ),
tests.props.all,
'All properties'
);
assert.deepEqual(
mw.TemplateData.Model.static.getPropertiesWithLanguage(),
tests.props.language,
'Language properties'
);
} );
// Test model load
QUnit.asyncTest( 'TemplateData model', function ( assert ) {
var i,
sourceHandler = new mw.TemplateData.SourceHandler(),
paramAddTest = [
{
key: 'newParam1',
data: { required: true },
result: { name: 'newParam1', required: true },
description: '',
msg: 'Adding a simple parameter.'
},
{
key: 'newParam2',
data: null,
result: { name: 'newParam2' },
description: '',
msg: 'Adding new parameter without data.'
},
{
key: 'newParam3',
data: { description: 'Some string here in ' + currLanguage + ' language.' },
result: { name: 'newParam3', description: resultDescCurrLang },
description: 'Some string here in ' + currLanguage + ' language.',
msg: 'Adding parameter with language prop: original without language.'
},
{
key: 'newParam4',
data: {
description: resultDescBothLang
},
result: { name: 'newParam4', description: resultDescBothLang },
description: 'Some string here in ' + currLanguage + ' language.',
msg: 'Adding parameter with language prop: original with multiple languages.'
}
],
paramChangeTest = [
{
key: 'newParam1',
property: 'description',
language: 'en',
value: resultDescCurrLang[ currLanguage ],
result: $.extend( {}, paramAddTest[ 0 ].result, {
description: resultDescCurrLang
} ),
msg: 'Adding description in current language.'
},
{
key: 'newParam1',
property: 'description',
language: 'blah',
value: resultDescMockLang.blah,
result: $.extend( {}, paramAddTest[ 0 ].result, {
description: $.extend( {}, resultDescCurrLang, resultDescMockLang )
} ),
msg: 'Adding description in mock language.'
},
{
key: 'comment',
property: 'type',
value: 'wiki-page-name',
result: {
name: 'comment',
type: 'wiki-page-name',
required: false
},
msg: 'Adding type to comment.'
},
{
key: 'newParam2',
property: 'description',
language: 'blah',
value: '',
result: $.extend( {}, paramAddTest[ 1 ].result, {
description: { blah: '' }
} ),
msg: 'Adding empty description in mock language.'
},
{
key: 'newParam3',
property: 'deprecated',
value: true,
result: $.extend( {}, paramAddTest[ 2 ].result, {
deprecated: true
} ),
msg: 'Adding deprecated property (boolean).'
},
{
key: 'newParam3',
property: 'deprecatedValue',
value: 'This is deprecated.',
result: $.extend( {}, paramAddTest[ 2 ].result, {
deprecated: true,
deprecatedValue: 'This is deprecated.'
} ),
msg: 'Adding deprecated property (string).'
}
];
QUnit.expect(
// Description and parameter list
3 +
// Add parameter tests
2 * paramAddTest.length +
// Change properties tests
paramChangeTest.length +
// Json output
3
);
sourceHandler.buildModel( originalWikitext )
.done( function ( model ) {
// Check description
assert.equal(
model.getTemplateDescription(),
'Label unsigned comments in a conversation.',
'Description in default language.'
);
assert.equal(
model.getTemplateDescription( 'blah' ),
'Template description in some blah language.',
'Description in mock language.'
);
// Check parameters
assert.deepEqual(
Object.keys( model.getParams() ),
[ 'user', 'date', 'year', 'month', 'day', 'comment' ],
'Parameters retention.'
);
for ( i = 0; i < paramAddTest.length; i++ ) {
// Add parameter
model.addParam( paramAddTest[ i ].key, paramAddTest[ i ].data );
// Test new param data
assert.deepEqual(
model.getParamData( paramAddTest[ i ].key ),
paramAddTest[ i ].result,
paramAddTest[ i ].msg + ' (parameter data)'
);
// Check description in current language
assert.equal(
model.getParamValue( paramAddTest[ i ].key, 'description', currLanguage ),
paramAddTest[ i ].description,
paramAddTest[ i ].msg + ' (description in current language)'
);
}
// Change parameter properties
for ( i = 0; i < paramChangeTest.length; i++ ) {
testVars = paramChangeTest[ i ];
model.setParamProperty( testVars.key, testVars.property, testVars.value, testVars.language );
assert.deepEqual(
model.getParamData( testVars.key ),
paramChangeTest[ i ].result,
paramChangeTest[ i ].msg
);
}
// Delete parameter
model.deleteParam( 'day' );
// Ouput a final templatedata string
assert.equal(
model.outputTemplateDataString(),
finalJsonStringOnly,
'Final templatedata output'
);
// Move 'user' to offset 3 (in original array), i.e. after 'year'
model.reorderParamOrderKey( 'user', 3 );
assert.deepEqual(
model.paramOrder,
[ 'date', 'year', 'user', 'month', 'comment', 'newParam1', 'newParam2', 'newParam3', 'newParam4' ],
'Final templatedata output with paramOrder'
);
// Move 'month' to offset 2, i.e. after 'year'
model.reorderParamOrderKey( 'month', 2 );
assert.deepEqual(
model.paramOrder,
[ 'date', 'year', 'month', 'user', 'comment', 'newParam1', 'newParam2', 'newParam3', 'newParam4' ],
'Final templatedata output with paramOrder'
);
} )
.always( function () {
QUnit.start();
} );
} );
// Test model fail
QUnit.asyncTest( 'TemplateData sourceHandler', function ( assert ) {
var sourceHandler = new mw.TemplateData.SourceHandler(),
erronousString = '<templatedata>{\n' +
' "params": {\n' +
// Open quote
' "user: {\n' +
' "label": "Username",\n' +
' "type": "wiki-user-name",\n' +
' "required": true,\n' +
' "description": "User name of person who forgot to sign their comment.",\n' +
' "aliases": [\n' +
' "1"\n' +
' ]\n' +
' },\n' +
' "date": {\n' +
' "label": "Date",\n' +
' "description": {\n' +
// Forgotten quotes
' en: "Timestamp of when the comment was posted, in YYYY-MM-DD format."\n' +
' }\n' +
' "suggested": true\n' +
' }\n' +
' }\n' +
'}</templatedata>';
QUnit.expect( 1 );
sourceHandler.buildModel( erronousString )
.always( function () {
assert.ok( this.state() === 'rejected', 'Promise rejected on erronous json string.' );
QUnit.start();
} );
} );
// Test model gets default format
QUnit.asyncTest( 'TemplateData sourceHandler adding default format', function ( assert ) {
var sourceHandler = new mw.TemplateData.SourceHandler(),
simpleTemplateDataNoFormat = '<templatedata>{\n' +
' "params": {}\n' +
'}</templatedata>',
simpleTemplateDataDefaultFormat = '{\n' +
' "params": {},\n' +
' "format": "inline"\n' + // default format
'}';
QUnit.expect( 1 );
sourceHandler.buildModel( simpleTemplateDataNoFormat )
.done( function ( model ) {
assert.equal(
model.outputTemplateDataString(),
simpleTemplateDataDefaultFormat,
'Final templatedata output'
);
} )
.always( function () {
QUnit.start();
} );
} );
}() );