mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-12-21 02:22:51 +00:00
6cbedbf9d2
* Remove need for manual hacking of sub groups via "msg" strings carefully prepended to every assertion. * Improve CI details, by reporting the specific case that failed, and local dev via ability to re-run each case, and reporting names directly in the HTML Reporter and CLI summary. * Reduce need for assert.async() and tracking of callbacks, especially to improve failure details in case of Promise rejection. Current logic was likely to cause a confusing timeout instead of a clear failure if the promise ends up rejected. QUnit propagates these as part of awaiting and asserting the test closure's promise value (as async fn) automatically. This approach also avoids the pitfal of a falsely passing test when an assertion inside a done() handler was never reached. * Use modern for-of where possible to remove need for closures and arrow functions. Thus reducing complexity of test code, where complexity should be kept lowest to avoid false confidence. * Use plain for-in instead of overly complex Object.keys().forEach(). Change-Id: I934a266e75e64371081f104cfb867fb2c282c84a
229 lines
5.4 KiB
JavaScript
229 lines
5.4 KiB
JavaScript
{
|
|
const toggleCirrusSearchLookup = ( enabled ) =>
|
|
mw.config.set( 'wgVisualEditorConfig', ve.extendObject( {}, mw.config.get( 'wgVisualEditorConfig' ), {
|
|
cirrusSearchLookup: enabled !== false
|
|
} ) );
|
|
|
|
const makeFakeApi = () => {
|
|
return {
|
|
defaults: { parameters: {} },
|
|
get: () => {
|
|
return {
|
|
abort: { bind: () => {} },
|
|
then: () => {}
|
|
};
|
|
}
|
|
};
|
|
};
|
|
|
|
QUnit.module( 've.ui.MWTemplateTitleInputWidget', ve.test.utils.newMwEnvironment( {
|
|
// Config will be reset by newMwEnvironment's teardown
|
|
beforeEach: toggleCirrusSearchLookup
|
|
} ) );
|
|
|
|
QUnit.test( 'default prefixsearch', ( assert ) => {
|
|
toggleCirrusSearchLookup( false );
|
|
|
|
const widget = new ve.ui.MWTemplateTitleInputWidget();
|
|
const query = 'a';
|
|
const apiParams = widget.getApiParams( query );
|
|
|
|
assert.deepEqual( apiParams, {
|
|
action: 'query',
|
|
generator: 'prefixsearch',
|
|
gpslimit: 10,
|
|
gpsnamespace: 10,
|
|
gpssearch: 'a',
|
|
ppprop: 'disambiguation',
|
|
prop: [ 'info', 'pageprops' ],
|
|
redirects: true
|
|
} );
|
|
} );
|
|
|
|
QUnit.test( 'CirrusSearch: all API parameters', ( assert ) => {
|
|
const widget = new ve.ui.MWTemplateTitleInputWidget();
|
|
const query = 'a';
|
|
const apiParams = widget.getApiParams( query );
|
|
|
|
assert.deepEqual( apiParams, {
|
|
action: 'query',
|
|
generator: 'search',
|
|
gsrlimit: 10,
|
|
gsrnamespace: 10,
|
|
gsrprop: 'redirecttitle',
|
|
gsrsearch: 'a*',
|
|
ppprop: 'disambiguation',
|
|
prop: [ 'info', 'pageprops' ],
|
|
redirects: true
|
|
} );
|
|
} );
|
|
|
|
QUnit.test( 'CirrusSearch: showRedirectTargets disabled', ( assert ) => {
|
|
const widget = new ve.ui.MWTemplateTitleInputWidget( { showRedirectTargets: false } ),
|
|
apiParams = widget.getApiParams();
|
|
|
|
assert.false( 'gsrprop' in apiParams );
|
|
} );
|
|
|
|
QUnit.test.each( 'CirrusSearch: prefixsearch behavior', [
|
|
{
|
|
query: 'a',
|
|
expected: 'a*'
|
|
},
|
|
{
|
|
query: 'a ',
|
|
expected: 'a '
|
|
},
|
|
{
|
|
query: 'ü',
|
|
expected: 'ü*'
|
|
},
|
|
{
|
|
query: '3',
|
|
expected: '3*'
|
|
},
|
|
{
|
|
query: '!!',
|
|
expected: '!!'
|
|
},
|
|
{
|
|
query: 'Foo:',
|
|
expected: 'Foo:'
|
|
},
|
|
{
|
|
query: 'Foo:Bar',
|
|
expected: 'Foo:Bar*'
|
|
},
|
|
{
|
|
query: 'foo_',
|
|
expected: 'foo_'
|
|
},
|
|
{
|
|
query: 'foo-',
|
|
expected: 'foo-'
|
|
},
|
|
{
|
|
query: 'foo+',
|
|
expected: 'foo+'
|
|
},
|
|
{
|
|
query: 'foo/',
|
|
expected: 'foo/'
|
|
},
|
|
{
|
|
query: 'foo~',
|
|
expected: 'foo~'
|
|
},
|
|
{
|
|
query: 'foo*',
|
|
expected: 'foo*'
|
|
},
|
|
{
|
|
query: '(foo)',
|
|
expected: '(foo)'
|
|
},
|
|
{
|
|
query: '[foo]',
|
|
expected: '[foo]'
|
|
},
|
|
{
|
|
query: '{foo}',
|
|
expected: '{foo}'
|
|
},
|
|
{
|
|
query: '"foo"',
|
|
expected: '"foo"'
|
|
},
|
|
{
|
|
query: 'foß',
|
|
expected: 'foß*'
|
|
},
|
|
{
|
|
query: '中文字',
|
|
expected: '中文字*'
|
|
},
|
|
{
|
|
query: 'zhōngwénzì',
|
|
expected: 'zhōngwénzì*'
|
|
}
|
|
], ( assert, data ) => {
|
|
const widget = new ve.ui.MWTemplateTitleInputWidget();
|
|
const apiParams = widget.getApiParams( data.query );
|
|
|
|
assert.strictEqual(
|
|
apiParams.gsrsearch,
|
|
data.expected,
|
|
'Searching for ' + data.query
|
|
);
|
|
} );
|
|
|
|
QUnit.test( 'CirrusSearch with prefixsearch fallback', async function ( assert ) {
|
|
const api = makeFakeApi();
|
|
this.sandbox.stub( api, 'get' )
|
|
.onFirstCall().returns( ve.createDeferred()
|
|
.resolve( { query: {
|
|
pages: [
|
|
{ pageid: 101, title: 'B' },
|
|
{ pageid: 102, title: 'A' },
|
|
// Documentation subpage, expected to be stripped
|
|
{ pageid: 103, title: 'A/(templatedata-doc-subpage)' }
|
|
],
|
|
redirects: [
|
|
// Alternative source for indexes, expected to be copied to the pages array
|
|
{ from: '', to: 'B', index: 1 },
|
|
{ from: '', to: 'A', index: 0 }
|
|
]
|
|
} } )
|
|
.promise( { abort: () => {} } )
|
|
)
|
|
.onSecondCall().returns( ve.createDeferred()
|
|
.resolve( { query: { pages: [
|
|
// Duplicate found by CirrusSearch (above) and prefixsearch
|
|
{ pageid: 102, title: 'A', index: 2 },
|
|
// New prefixsearch matches, expected to be prepended, in order of relevance
|
|
{ pageid: 201, title: 'D', index: 1 },
|
|
{ pageid: 202, title: 'C', index: 0 }
|
|
] } } )
|
|
)
|
|
.onThirdCall().returns( ve.createDeferred()
|
|
.resolve( /* we can skip the templatedata request for this test */ )
|
|
);
|
|
|
|
const widget = new ve.ui.MWTemplateTitleInputWidget( { api, showDescriptions: true } );
|
|
widget.setValue( 'something' );
|
|
|
|
const response = await widget.getLookupRequest();
|
|
assert.deepEqual( response.query.pages, [
|
|
{ pageid: 202, title: 'C', index: -10 },
|
|
{ pageid: 201, title: 'D', index: -9 },
|
|
{ pageid: 102, title: 'A', index: 0 },
|
|
{ pageid: 101, title: 'B', index: 1 }
|
|
] );
|
|
} );
|
|
|
|
QUnit.test( 'CirrusSearch: redirect is forwarded to the TitleOptionWidget', ( assert ) => {
|
|
const widget = new ve.ui.MWTemplateTitleInputWidget();
|
|
const originalData = { redirecttitle: 'Template:From' };
|
|
const data = widget.getOptionWidgetData( 'Template:To', { originalData } );
|
|
|
|
assert.strictEqual( data.redirecttitle, 'Template:From' );
|
|
} );
|
|
|
|
QUnit.test( 'CirrusSearch: redirect appears in the description', ( assert ) => {
|
|
const widget = new ve.ui.MWTemplateTitleInputWidget();
|
|
|
|
let option = widget.createOptionWidget( { redirecttitle: 'Template:From' } );
|
|
assert.strictEqual(
|
|
option.$element.find( '.ve-ui-mwTemplateTitleInputWidget-redirectedfrom' ).text(),
|
|
'(redirectedfrom: From)'
|
|
);
|
|
|
|
widget.relative = false;
|
|
option = widget.createOptionWidget( { redirecttitle: 'Template:From' } );
|
|
assert.strictEqual(
|
|
option.$element.find( '.ve-ui-mwTemplateTitleInputWidget-redirectedfrom' ).text(),
|
|
'(redirectedfrom: Template:From)'
|
|
);
|
|
} );
|
|
}
|