mediawiki-extensions-Visual.../modules/ve-mw/tests/dm/models/ve.dm.MWTemplateModel.test.js
Thiemo Kreuz d59a4366db Change TransclusionModel.nextUniquePartId() to return a string
The numeric part of these ids is never used on it's own. There is no
need to expose it.

Note we renamed the method not long ago in I6eeab8b to reflect better
what it does. This is the next step. We just forgot it back then.

Change-Id: I5da82855e99ea3a42a5d91379c6974ae9c154518
2022-04-19 13:48:30 +02:00

512 lines
12 KiB
JavaScript

/*!
* VisualEditor DataModel MWTemplateModel tests.
*
* @copyright 2011-2020 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
{
const transclusionData = {
params: {
foo: { wt: 'Foo value' },
bar: { wt: 'Bar value' },
Bar: { wt: 'Bar value' },
empty: { wt: '' },
'': { wt: '' }
},
target: {
href: './Template:Test',
wt: 'Test'
}
};
QUnit.module( 've.dm.MWTemplateModel' );
/**
* Create a new MWTemplateModel initialized with a static transclusion data fixture.
*
* @return {ve.dm.MWTemplateModel}
*/
const newTemplateModel = function () {
const doc = ve.dm.Document.static.newBlankDocument(),
transclusion = new ve.dm.MWTransclusionModel( doc ),
clonedTransclusionData = ve.extendObject( {}, transclusionData );
return ve.dm.MWTemplateModel.newFromData( transclusion, clonedTransclusionData );
};
/* Tests */
[
[ undefined, null ],
[ '', null ],
[ 'no_prefix', 'no prefix' ],
[ '/unexpected_prefix', '/unexpected prefix' ],
[ './Template:%C3%9Cnicode%5Fexample/subpage', 'Template:Ünicode example/subpage' ],
[ './Template:Possibly_invalid%5B%5D', 'Template:Possibly invalid[]' ]
].forEach( ( [ href, expected ] ) =>
QUnit.test( 'getTitle: ' + href, ( assert ) => {
const transclusion = { nextUniquePartId: () => '' },
template = new ve.dm.MWTemplateModel( transclusion, { href } );
assert.strictEqual( template.getTitle(), expected );
} )
);
QUnit.test( 'hasParameter', ( assert ) => {
const template = newTemplateModel();
// All parameters are primary as long as the TemplateData documentation isn't known
assert.strictEqual( template.hasParameter( 'bar' ), true );
assert.strictEqual( template.hasParameter( 'resolved-bar' ), false );
assert.strictEqual( template.hasParameter( 'alternative-bar' ), false );
template.getSpec().setTemplateData( { params: {
'resolved-bar': { aliases: [ 'bar', 'alternative-bar' ] }
} } );
// Now "bar" and "alternative-bar" are aliases, and "resolved-bar" is the primary name
assert.strictEqual( template.hasParameter( 'bar' ), true );
assert.strictEqual( template.hasParameter( 'resolved-bar' ), true );
assert.strictEqual( template.hasParameter( 'alternative-bar' ), true );
} );
QUnit.test( 'getOriginalParameterName', ( assert ) => {
const template = newTemplateModel();
template.addParameter( new ve.dm.MWParameterModel( template, 'p1' ) );
template.addParameter( new ve.dm.MWParameterModel( template, 'p2-alias' ) );
// These are all independent parameters as long as we don't know anything about aliases
assert.strictEqual( template.getOriginalParameterName( 'p1' ), 'p1' );
assert.strictEqual( template.getOriginalParameterName( 'p1-alias' ), 'p1-alias' );
assert.strictEqual( template.getOriginalParameterName( 'p2' ), 'p2' );
assert.strictEqual( template.getOriginalParameterName( 'p2-alias' ), 'p2-alias' );
assert.strictEqual( template.getOriginalParameterName( 'p3' ), 'p3' );
assert.strictEqual( template.getOriginalParameterName( 'p3-alias' ), 'p3-alias' );
template.getSpec().setTemplateData( { params: {
p1: { aliases: [ 'p1-alias' ] },
p2: { aliases: [ 'p2-alias' ] },
p3: { aliases: [ 'p3-alias' ] }
} } );
assert.strictEqual( template.getOriginalParameterName( 'p1' ), 'p1' );
assert.strictEqual( template.getOriginalParameterName( 'p1-alias' ), 'p1' );
assert.strictEqual( template.getOriginalParameterName( 'p2' ), 'p2-alias' );
assert.strictEqual( template.getOriginalParameterName( 'p2-alias' ), 'p2-alias' );
assert.strictEqual( template.getOriginalParameterName( 'p3' ), 'p3' );
assert.strictEqual( template.getOriginalParameterName( 'p3-alias' ), 'p3' );
} );
QUnit.test( 'serialize input parameters', ( assert ) => {
const template = newTemplateModel();
const serialization = template.serialize();
assert.deepEqual( serialization, { template: {
params: {
foo: { wt: 'Foo value' },
bar: { wt: 'Bar value' },
Bar: { wt: 'Bar value' },
empty: { wt: '' }
},
target: { href: './Template:Test', wt: 'Test' }
} } );
} );
QUnit.test( 'serialize changed input parameters', ( assert ) => {
const template = newTemplateModel(),
newParameter = new ve.dm.MWParameterModel( template, 'baz', 'Baz value' );
template.addParameter( newParameter );
const serialization = template.serialize();
assert.deepEqual( serialization.template.params.baz, { wt: 'Baz value' } );
} );
// T75134
QUnit.test( 'serialize after parameter was removed', ( assert ) => {
const template = newTemplateModel(),
existingParameter = template.getParameter( 'bar' );
template.removeParameter( existingParameter );
const serialization = template.serialize();
assert.deepEqual( serialization.template.params, {
foo: { wt: 'Foo value' },
Bar: { wt: 'Bar value' },
empty: { wt: '' }
} );
} );
// T101075
QUnit.test( 'serialize without empty parameter not present in original parameter set', ( assert ) => {
const template = newTemplateModel(),
parameterWithoutValue = new ve.dm.MWParameterModel( template, 'new_empty', '' );
template.addParameter( parameterWithoutValue );
const serialization = template.serialize();
assert.deepEqual( serialization.template.params, {
foo: { wt: 'Foo value' },
bar: { wt: 'Bar value' },
Bar: { wt: 'Bar value' },
empty: { wt: '' }
} );
} );
[
{
name: 'serialize with explicit parameter order',
spec: {
params: {
foo: {},
empty: {},
bar: {},
Bar: {}
},
paramOrder: [ 'bar', 'foo', 'empty', 'Bar' ]
},
expected: [ 'foo', 'bar', 'Bar', 'empty' ]
},
{
name: 'serialize with no parameter order',
spec: {
params: {
foo: {},
empty: {},
bar: {},
Bar: {}
}
},
expected: [ 'foo', 'bar', 'Bar', 'empty' ]
},
{
name: 'serialize with aliases',
spec: {
params: {
foo: {},
Bar: {},
empty: {},
hasaliases: { aliases: [ 'bar', 'baz' ] }
}
},
expected: [ 'foo', 'bar', 'Bar', 'empty' ]
},
{
name: 'serialize with unknown params',
spec: {
params: {
bar: {}
}
},
expected: [ 'foo', 'bar', 'Bar', 'empty' ]
}
].forEach( ( { name, spec, expected } ) =>
QUnit.test( name, ( assert ) => {
const template = newTemplateModel();
template.getSpec().setTemplateData( spec );
const serialization = template.serialize();
assert.deepEqual( Object.keys( serialization.template.params ), expected );
} )
);
[
{
name: 'no spec retrieved',
spec: null,
expected: [
'bar',
'Bar',
'empty',
'foo',
''
]
},
{
name: 'empty spec',
spec: {},
expected: [
'bar',
'Bar',
'empty',
'foo',
''
]
},
{
name: 'spec with explicit paramOrder and all known params',
spec: {
params: {
bar: {},
Bar: {},
empty: {},
unused: {},
foo: {}
},
paramOrder: [ 'foo', 'Bar', 'empty', 'bar', 'unused' ]
},
expected: [
'foo',
'Bar',
'empty',
'bar',
''
]
},
{
name: 'spec with explicit paramOrder and some unknown params',
spec: {
params: {
empty: {},
unused: {},
foo: {}
},
paramOrder: [ 'foo', 'empty', 'unused' ]
},
expected: [
'foo',
'empty',
'bar',
'Bar',
''
]
},
{
name: 'spec with explicit paramOrder but all unknown params',
spec: {
params: {},
paramOrder: []
},
expected: [
'bar',
'Bar',
'empty',
'foo',
''
]
},
{
name: 'spec with no paramOrder, all known params',
spec: {
params: {
bar: {},
Bar: {},
foo: {},
unused: {},
empty: {}
}
},
expected: [
'bar',
'Bar',
'foo',
'empty',
''
]
},
{
name: 'spec with no paramOrder and some unknown params',
spec: {
params: {
empty: {},
unused: {},
foo: {}
}
},
expected: [
'empty',
'foo',
'bar',
'Bar',
''
]
}
].forEach( ( { name, spec, expected } ) =>
QUnit.test( 'getOrderedParameterNames: ' + name, ( assert ) => {
const template = newTemplateModel();
if ( spec ) {
template.getSpec().setTemplateData( spec );
}
assert.deepEqual( template.getOrderedParameterNames(), expected );
} )
);
[
{
name: 'no spec retrieved',
spec: null,
expected: [
'bar',
'Bar',
'empty',
'foo',
''
]
},
{
name: 'spec with explicit paramOrder and all known params',
spec: {
params: {
bar: {},
Bar: {},
empty: {},
unused: {},
foo: {}
},
paramOrder: [ 'foo', 'Bar', 'empty', 'unused', 'bar' ]
},
expected: [
'foo',
'Bar',
'empty',
'unused',
'bar',
''
]
},
{
name: 'spec with explicit paramOrder and some unknown params',
spec: {
params: {
empty: {},
unused: {},
foo: {}
},
paramOrder: [ 'foo', 'empty', 'unused' ]
},
expected: [
'foo',
'empty',
'unused',
'bar',
'Bar',
''
]
},
{
name: 'spec with explicit paramOrder but all unknown params',
spec: {
params: {},
paramOrder: []
},
expected: [
'bar',
'Bar',
'empty',
'foo',
''
]
},
{
name: 'spec with no paramOrder, all known params',
spec: {
params: {
bar: {},
Bar: {},
foo: {},
unused: {},
empty: {}
}
},
expected: [
'bar',
'Bar',
'foo',
'unused',
'empty',
''
]
},
{
name: 'spec with no paramOrder and some unknown params',
spec: {
params: {
empty: {},
unused: {},
foo: {}
}
},
expected: [
'empty',
'unused',
'foo',
'bar',
'Bar',
''
]
},
{
name: 'spec with explicit paramOrder and aliases',
spec: {
params: {
empty: {},
unused: {},
hasalias: {
aliases: [ 'bar', 'baz' ]
}
},
paramOrder: [ 'hasalias', 'empty', 'unused' ]
},
expected: [
'bar',
'empty',
'unused',
'Bar',
'foo',
''
]
}
].forEach( ( { name, spec, expected } ) =>
QUnit.test( 'getAllParametersOrdered: ' + name, ( assert ) => {
const template = newTemplateModel();
if ( spec ) {
template.getSpec().setTemplateData( spec );
}
assert.deepEqual( template.getAllParametersOrdered(), expected );
} )
);
[
[ 'a', 'b', 'Template:A', 'prefers .wt when it is a valid title' ],
[ '{{a}}', 'subst:b', 'subst:b', 'falls back to unmodified getTitle' ],
[ 'subst:a', 'b', 'Template:A', 'strips subst:' ],
[ 'safesubst:a', 'b', 'Template:A', 'strips safesubst:' ],
[ ' SUBST: a', 'b', 'Template:A', 'ignores capitalization and whitespace' ],
[ 'subst :a', 'b', 'Template:Subst :a', 'leaves bad whitespace untouched' ],
[ 'int:a', 'b', 'Template:Int:a', 'leaves other prefixes untouched' ]
].forEach( ( [ wt, href, expected, message ] ) =>
QUnit.test( 'getTemplateDataQueryTitle: ' + message, ( assert ) => {
const transclusion = { nextUniquePartId: () => '' },
data = { target: { wt, href } },
model = ve.dm.MWTemplateModel.newFromData( transclusion, data );
assert.strictEqual( model.getTemplateDataQueryTitle(), expected );
} )
);
[
[ {}, false, 'no parameters' ],
[ { p1: {}, p2: { wt: 'foo' } }, true, 'multiple parameters' ],
[ { p1: {} }, false, 'undefined' ],
[ { p1: { wt: null } }, false, 'null' ],
[ { p1: { wt: '' } }, false, 'empty string' ],
[ { p1: { wt: ' ' } }, true, 'space' ],
[ { p1: { wt: '0' } }, true, '0' ],
[ { p1: { wt: '\nfoo' } }, true, 'newline' ]
].forEach( ( [ params, expected, message ] ) =>
QUnit.test( 'containsValuableData: ' + message, ( assert ) => {
const transclusion = { nextUniquePartId: () => '' },
data = { target: {}, params },
model = ve.dm.MWTemplateModel.newFromData( transclusion, data );
assert.strictEqual( model.containsValuableData(), expected );
} )
);
}