mediawiki-extensions-CodeMi.../tests/jest/codemirror.test.js
MusikAnimal ca02360228 CM6: Switch to using Rollup instead of Webpack; make RL-compatible
See https://w.wiki/9Twh for example usage with ResourceLoader.

Webpack is retired in favor of Rollup, which allows us to convert the
ECMAScript Modules into CommonJS modules for use by ResourceLoader.
We now have a file in dist/ for each RL module that we want to offer,
including the 'lib' module which includes the CM library itself.

Because Rollup has no knowledge of the ResourceLoader module registry,
the generated output requires other modules via relative path, when it
needs to be the RL module name. To get around this, we do a crude
find/replace after the files are generated. Hacky, but necessary to make
CodeMirror usable by gadgets and scripts that don't also want
WikiEditor.

Add new RL modules 'ext.CodeMirror.v6.lib' (vendor code) and
'ext.CodeMirror.v6' (the main CodeMirror class, sans WikiEditor).

Clean up extension.json, listing the v6 modules beneath the old ones.

Bug: T214989
Change-Id: Ide716247e545cf2bdd977bea645729564ebbe6e2
2024-03-19 22:48:52 -04:00

99 lines
3.2 KiB
JavaScript

import { EditorView } from '@codemirror/view';
import CodeMirror from '../../src/codemirror.js';
const $textarea = $( '<textarea>' ),
cm = new CodeMirror( $textarea );
describe( 'initialize', () => {
const initializeWithForm = () => {
const form = document.createElement( 'form' );
form.append( cm.$textarea[ 0 ] );
cm.$textarea[ 0 ].form.addEventListener = jest.fn();
cm.initialize();
};
it( 'should create the EditorState with the value of the textarea', () => {
cm.$textarea.val( 'foobar' );
cm.$textarea.textSelection = jest.fn().mockReturnValue( 'foobar' );
cm.initialize();
expect( cm.view.state.doc.toString() ).toStrictEqual( 'foobar' );
} );
it( 'should set the height to the same as the textarea', () => {
$textarea.css( 'height', '100px' );
cm.initialize();
// 100 + 6 (padding/border) = 106
expect( $( cm.view.dom ).height() ).toStrictEqual( 106 );
} );
it( 'should instantiate an EditorView and add .cm-editor to the DOM', () => {
initializeWithForm();
expect( cm.view ).toBeInstanceOf( EditorView );
expect( cm.view.dom ).toBeInstanceOf( HTMLDivElement );
expect( cm.$textarea[ 0 ].nextSibling ).toStrictEqual( cm.view.dom );
} );
it( 'should hide the native textarea', () => {
cm.initialize();
expect( cm.$textarea[ 0 ].style.display ).toStrictEqual( 'none' );
} );
it( 'should add a listener for form submission', () => {
initializeWithForm();
expect( cm.$textarea[ 0 ].form.addEventListener ).toHaveBeenCalledTimes( 1 );
} );
it( 'should retain the mw-editfont- class present on the textarea', () => {
cm.$textarea.addClass( 'mw-editfont-monospace' );
cm.initialize();
expect( cm.view.dom.querySelector( '.cm-content' ).classList ).toContain( 'mw-editfont-monospace' );
} );
it( "should copy the 'dir' and 'lang' attributes of the textarea to .cm-editor", () => {
cm.$textarea.prop( 'dir', 'rtl' )
.prop( 'lang', 'ar' );
cm.initialize();
expect( cm.view.dom.getAttribute( 'dir' ) ).toStrictEqual( 'rtl' );
expect( cm.view.dom.getAttribute( 'lang' ) ).toStrictEqual( 'ar' );
} );
} );
describe( 'logUsage', () => {
it( 'should track usage of CodeMirror with the correct data', () => {
cm.logUsage( {
editor: 'wikitext',
enabled: true,
toggled: false
} );
expect( mw.track ).toBeCalledWith( 'event.CodeMirrorUsage', {
editor: 'wikitext',
enabled: true,
// eslint-disable-next-line camelcase
session_token: 'abc',
toggled: false,
// eslint-disable-next-line camelcase
user_edit_count_bucket: '1000+ edits',
// eslint-disable-next-line camelcase
user_id: 123
} );
} );
} );
describe( 'setCodeMirrorPreference', () => {
beforeEach( () => {
cm.initialize();
} );
it( 'should save using the API with the correct value', () => {
cm.setCodeMirrorPreference( true );
expect( mw.Api.prototype.saveOption ).toHaveBeenCalledWith( 'usecodemirror', 1 );
expect( mw.user.options.set ).toHaveBeenCalledWith( 'usecodemirror', 1 );
} );
it( 'should not save preferences if the user is not named', () => {
mw.user.isNamed = jest.fn().mockReturnValue( false );
cm.setCodeMirrorPreference( true );
expect( mw.Api.prototype.saveOption ).toHaveBeenCalledTimes( 0 );
expect( mw.user.options.set ).toHaveBeenCalledTimes( 0 );
} );
} );