123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679 |
- const SpellCheckTask = require('../lib/spell-check-task');
- const env = require('../lib/checker-env');
- const { sep } = require('path');
- const {
- it,
- fit,
- ffit,
- beforeEach,
- afterEach,
- conditionPromise,
- timeoutPromise,
- } = require('./async-spec-helpers');
- describe('Spell check', function () {
- let workspaceElement, editor, editorElement, spellCheckModule;
- const textForMarker = (marker) =>
- editor.getTextInBufferRange(marker.getBufferRange());
- const getMisspellingMarkers = () =>
- spellCheckModule.misspellingMarkersForEditor(editor);
- beforeEach(async function () {
- jasmine.useRealClock();
- workspaceElement = atom.views.getView(atom.workspace);
- await atom.packages.activatePackage('language-text');
- await atom.packages.activatePackage('language-javascript');
- await atom.workspace.open(`${__dirname}${sep}sample.js`);
- const pack = await atom.packages.activatePackage('spell-check');
- spellCheckModule = pack.mainModule;
- // Disable the grammers so nothing is done until we turn it back on.
- atom.config.set('spell-check.grammars', []);
- // Set the settings to a specific setting to avoid side effects.
- atom.config.set('spell-check.useSystem', false);
- atom.config.set('spell-check.useLocales', false);
- atom.config.set('spell-check.locales', ['en-US']);
- // Attach everything and ready to test.
- jasmine.attachToDOM(workspaceElement);
- editor = atom.workspace.getActiveTextEditor();
- editorElement = atom.views.getView(editor);
- });
- afterEach(() => SpellCheckTask.clear());
- it('decorates all misspelled words', async function () {
- atom.config.set('spell-check.useLocales', true);
- editor.insertText(
- 'This middle of thiss\nsentencts\n\nhas issues and the "edn" \'dsoe\' too'
- );
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 4);
- const misspellingMarkers = getMisspellingMarkers();
- expect(textForMarker(misspellingMarkers[0])).toEqual('thiss');
- expect(textForMarker(misspellingMarkers[1])).toEqual('sentencts');
- expect(textForMarker(misspellingMarkers[2])).toEqual('edn');
- expect(textForMarker(misspellingMarkers[3])).toEqual('dsoe');
- });
- it('decorates misspelled words with a leading space', async function () {
- atom.config.set('spell-check.useLocales', true);
- editor.setText('\nchok bok');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 2);
- const misspellingMarkers = getMisspellingMarkers();
- expect(textForMarker(misspellingMarkers[0])).toEqual('chok');
- expect(textForMarker(misspellingMarkers[1])).toEqual('bok');
- });
- it('allows certains scopes to be excluded from spell checking', async function () {
- editor.setText(
- 'speledWrong = 5;\n' +
- 'function speledWrong() {}\n' +
- 'class SpeledWrong {}'
- );
- atom.config.set('spell-check.useLocales', true);
- atom.config.set('spell-check.grammars', [
- 'source.js',
- 'text.plain.null-grammar',
- ]);
- atom.config.set('spell-check.excludedScopes', ['.function.entity']);
- {
- await conditionPromise(() => getMisspellingMarkers().length > 0);
- const markers = getMisspellingMarkers();
- expect(markers.map((marker) => marker.getBufferRange())).toEqual([
- [
- [0, 0],
- [0, 11],
- ],
- [
- [2, 6],
- [2, 17],
- ],
- ]);
- }
- {
- atom.config.set('spell-check.excludedScopes', ['.functio.entity']);
- await conditionPromise(() => getMisspellingMarkers().length === 3);
- const markers = getMisspellingMarkers();
- expect(markers.map((marker) => marker.getBufferRange())).toEqual([
- [
- [0, 0],
- [0, 11],
- ],
- [
- [1, 9],
- [1, 20],
- ],
- [
- [2, 6],
- [2, 17],
- ],
- ]);
- }
- {
- atom.config.set('spell-check.excludedScopes', ['.meta.class']);
- await conditionPromise(() => getMisspellingMarkers().length === 2);
- const markers = getMisspellingMarkers();
- expect(markers.map((marker) => marker.getBufferRange())).toEqual([
- [
- [0, 0],
- [0, 11],
- ],
- [
- [1, 9],
- [1, 20],
- ],
- ]);
- }
- {
- atom.grammars.assignLanguageMode(editor, null);
- await conditionPromise(() => getMisspellingMarkers().length === 3);
- const markers = getMisspellingMarkers();
- expect(markers.map((marker) => marker.getBufferRange())).toEqual([
- [
- [0, 0],
- [0, 11],
- ],
- [
- [1, 9],
- [1, 20],
- ],
- [
- [2, 6],
- [2, 17],
- ],
- ]);
- }
- });
- it('allow entering of known words', async function () {
- atom.config.set('spell-check.knownWords', [
- 'GitHub',
- '!github',
- 'codez',
- ]);
- atom.config.set('spell-check.useLocales', true);
- editor.setText('GitHub (aka github): Where codez are builz.');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 1);
- const misspellingMarkers = getMisspellingMarkers();
- expect(textForMarker(misspellingMarkers[0])).toBe('builz');
- });
- it('hides decorations when a misspelled word is edited', async function () {
- editor.setText('notaword');
- advanceClock(editor.getBuffer().getStoppedChangingDelay());
- atom.config.set('spell-check.useLocales', true);
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 1);
- editor.moveToEndOfLine();
- editor.insertText('a');
- await conditionPromise(() => {
- const misspellingMarkers = getMisspellingMarkers();
- return (
- misspellingMarkers.length === 1 &&
- !misspellingMarkers[0].isValid()
- );
- });
- });
- describe('when spell checking for a grammar is removed', () =>
- it('removes all the misspellings', async function () {
- atom.config.set('spell-check.useLocales', true);
- editor.setText('notaword');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 1);
- atom.config.set('spell-check.grammars', []);
- expect(getMisspellingMarkers().length).toBe(0);
- }));
- describe('when spell checking for a grammar is toggled off', () =>
- it('removes all the misspellings', async function () {
- atom.config.set('spell-check.useLocales', true);
- editor.setText('notaword');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 1);
- atom.commands.dispatch(workspaceElement, 'spell-check:toggle');
- expect(getMisspellingMarkers().length).toBe(0);
- }));
- describe("when the editor's grammar changes to one that does not have spell check enabled", () =>
- it('removes all the misspellings', async function () {
- atom.config.set('spell-check.useLocales', true);
- editor.setText('notaword');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 1);
- const misspellingMarkers = getMisspellingMarkers();
- editor.setGrammar(atom.grammars.selectGrammar('.txt'));
- expect(getMisspellingMarkers().length).toBe(0);
- }));
- describe("when 'spell-check:correct-misspelling' is triggered on the editor", function () {
- describe('when the cursor touches a misspelling that has corrections', () =>
- it('displays the corrections for the misspelling and replaces the misspelling when a correction is selected', async function () {
- atom.config.set('spell-check.useLocales', true);
- editor.setText('tofether');
- atom.config.set('spell-check.grammars', ['source.js']);
- let correctionsElement = null;
- await conditionPromise(
- () => getMisspellingMarkers().length === 1
- );
- expect(getMisspellingMarkers()[0].isValid()).toBe(true);
- atom.commands.dispatch(
- editorElement,
- 'spell-check:correct-misspelling'
- );
- correctionsElement = editorElement.querySelector(
- '.corrections'
- );
- expect(correctionsElement).toBeDefined();
- expect(
- correctionsElement.querySelectorAll('li').length
- ).toBeGreaterThan(0);
- expect(
- correctionsElement.querySelectorAll('li')[0].textContent
- ).toBe('together');
- atom.commands.dispatch(correctionsElement, 'core:confirm');
- expect(editor.getText()).toBe('together');
- expect(editor.getCursorBufferPosition()).toEqual([0, 8]);
- expect(getMisspellingMarkers()[0].isValid()).toBe(false);
- expect(editorElement.querySelector('.corrections')).toBeNull();
- }));
- describe('when the cursor touches a misspelling that has no corrections', () =>
- it('displays a message saying no corrections found', async function () {
- atom.config.set('spell-check.useLocales', true);
- editor.setText('zxcasdfysyadfyasdyfasdfyasdfyasdfyasydfasdf');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(
- () => getMisspellingMarkers().length > 0
- );
- atom.commands.dispatch(
- editorElement,
- 'spell-check:correct-misspelling'
- );
- expect(
- editorElement.querySelectorAll('.corrections').length
- ).toBe(1);
- expect(
- editorElement.querySelectorAll('.corrections li').length
- ).toBe(0);
- expect(
- editorElement.querySelector('.corrections').textContent
- ).toMatch(/No corrections/);
- }));
- });
- describe('when a right mouse click is triggered on the editor', function () {
- describe('when the cursor touches a misspelling that has corrections', () =>
- it('displays the context menu items for the misspelling and replaces the misspelling when a correction is selected', async function () {
- atom.config.set('spell-check.useLocales', true);
- editor.setText('tofether');
- advanceClock(editor.getBuffer().getStoppedChangingDelay());
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(
- () => getMisspellingMarkers().length === 1
- );
- expect(getMisspellingMarkers()[0].isValid()).toBe(true);
- editorElement.dispatchEvent(new MouseEvent('contextmenu'));
- // Check that the proper context menu entries are created for the misspelling.
- // A misspelling will have atleast 2 context menu items for the lines separating
- // the corrections.
- expect(
- spellCheckModule.contextMenuEntries.length
- ).toBeGreaterThan(2);
- const commandName = 'spell-check:correct-misspelling-0';
- const menuItemLabel = 'together';
- {
- const editorCommands = atom.commands.findCommands({
- target: editorElement,
- });
- const correctionCommand = editorCommands.filter(
- (command) => command.name === commandName
- )[0];
- const correctionMenuItem = atom.contextMenu.itemSets.filter(
- (item) => item.items[0].label === menuItemLabel
- )[0];
- expect(correctionCommand).toBeDefined();
- expect(correctionMenuItem).toBeDefined();
- }
- atom.commands.dispatch(editorElement, commandName);
- // Check that the misspelling is corrected and the context menu entries are properly disposed.
- expect(editor.getText()).toBe('together');
- expect(editor.getCursorBufferPosition()).toEqual([0, 8]);
- expect(getMisspellingMarkers()[0].isValid()).toBe(false);
- expect(spellCheckModule.contextMenuEntries.length).toBe(0);
- {
- const editorCommands = atom.commands.findCommands({
- target: editorElement,
- });
- const correctionCommand = editorCommands.filter(
- (command) => command.name === commandName
- )[0];
- const correctionMenuItem = atom.contextMenu.itemSets.filter(
- (item) => item.items[0].label === menuItemLabel
- )[0];
- expect(correctionCommand).toBeUndefined();
- expect(correctionMenuItem).toBeUndefined();
- }
- }));
- describe('when the cursor touches a misspelling and adding known words is enabled', () =>
- it("displays the 'Add to Known Words' option and adds that word when the option is selected", async function () {
- atom.config.set('spell-check.useLocales', true);
- editor.setText('zxcasdfysyadfyasdyfasdfyasdfyasdfyasydfasdf');
- advanceClock(editor.getBuffer().getStoppedChangingDelay());
- atom.config.set('spell-check.grammars', ['source.js']);
- atom.config.set('spell-check.addKnownWords', true);
- expect(atom.config.get('spell-check.knownWords').length).toBe(
- 0
- );
- await conditionPromise(
- () => getMisspellingMarkers().length === 1
- );
- expect(getMisspellingMarkers()[0].isValid()).toBe(true);
- editorElement.dispatchEvent(new MouseEvent('contextmenu'));
- // Check that the 'Add to Known Words' entry is added to the context menu.
- // There should be 1 entry for 'Add to Known Words' and 2 entries for the line separators.
- expect(spellCheckModule.contextMenuEntries.length).toBe(3);
- const commandName = 'spell-check:correct-misspelling-0';
- const menuItemLabel = 'together';
- {
- const editorCommands = atom.commands.findCommands({
- target: editorElement,
- });
- const correctionCommand = editorCommands.filter(
- (command) => command.name === commandName
- )[0];
- const correctionMenuItem = atom.contextMenu.itemSets.filter(
- (item) => item.items[0].label === menuItemLabel
- )[0];
- expect(correctionCommand).toBeDefined;
- expect(correctionMenuItem).toBeDefined;
- }
- atom.commands.dispatch(editorElement, commandName);
- // Check that the misspelling is added as a known word, that there are no more misspelling
- // markers in the editor, and that the context menu entries are properly disposed.
- waitsFor(() => getMisspellingMarkers().length === 0);
- expect(atom.config.get('spell-check.knownWords').length).toBe(
- 1
- );
- expect(spellCheckModule.contextMenuEntries.length).toBe(0);
- {
- const editorCommands = atom.commands.findCommands({
- target: editorElement,
- });
- const correctionCommand = editorCommands.filter(
- (command) => command.name === commandName
- )[0];
- const correctionMenuItem = atom.contextMenu.itemSets.filter(
- (item) => item.items[0].label === menuItemLabel
- )[0];
- expect(correctionCommand).toBeUndefined();
- expect(correctionMenuItem).toBeUndefined();
- }
- }));
- });
- describe('when the editor is destroyed', () =>
- it('destroys all misspelling markers', async function () {
- atom.config.set('spell-check.useLocales', true);
- editor.setText('mispelling');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length > 0);
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- // Check that all the views have been cleaned up.
- expect(spellCheckModule.updateViews().length).toBe(0);
- }));
- describe('when using checker plugins', function () {
- it('no opinion on input means correctly spells', async function () {
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-1-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-2-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-3-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-4-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./eot-spec-checker')
- );
- editor.setText('eot');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 1);
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- });
- it('correctly spelling k1a', async function () {
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-1-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-2-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-3-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-4-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./eot-spec-checker')
- );
- editor.setText('k1a eot');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 1);
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- });
- it('correctly mispelling k2a', async function () {
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-1-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-2-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-3-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-4-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./eot-spec-checker')
- );
- editor.setText('k2a eot');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 2);
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- });
- it('correctly mispelling k2a with text in middle', async function () {
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-1-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-2-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-3-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-4-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./eot-spec-checker')
- );
- editor.setText('k2a good eot');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 2);
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- });
- it('word is both correct and incorrect is correct', async function () {
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-1-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-2-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-3-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-4-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./eot-spec-checker')
- );
- editor.setText('k0a eot');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 1);
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- });
- it('word is correct twice is correct', async function () {
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-1-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-2-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-3-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-4-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./eot-spec-checker')
- );
- editor.setText('k0b eot');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 1);
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- });
- it('word is incorrect twice is incorrect', async function () {
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-1-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-2-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-3-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-4-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./eot-spec-checker')
- );
- editor.setText('k0c eot');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => getMisspellingMarkers().length === 2);
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- });
- it('treats unknown Unicode words as incorrect', async function () {
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./eot-spec-checker')
- );
- editor.setText('абырг eot');
- atom.config.set('spell-check.grammars', ['source.js']);
- expect(atom.config.get('spell-check.knownWords').length).toBe(0);
- await conditionPromise(() => getMisspellingMarkers().length > 0);
- const markers = getMisspellingMarkers();
- expect(markers[0].getBufferRange()).toEqual({
- start: { row: 0, column: 6 },
- end: { row: 0, column: 9 },
- });
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- });
- it('treats known Unicode words as correct', async function () {
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./known-unicode-spec-checker')
- );
- spellCheckModule.consumeSpellCheckers(
- require.resolve('./eot-spec-checker')
- );
- editor.setText('абырг eot');
- atom.config.set('spell-check.grammars', ['source.js']);
- expect(atom.config.get('spell-check.knownWords').length).toBe(0);
- await conditionPromise(() => getMisspellingMarkers().length === 1);
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- });
- });
- // These tests are only run on Macs because the CI for Windows doesn't have
- // spelling provided.
- if (env.isSystemSupported() && env.isDarwin()) {
- describe('when using system checker plugin', function () {
- it('marks chzz as not a valid word but cheese is', async function () {
- atom.config.set('spell-check.useSystem', true);
- editor.setText('cheese chzz');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => {
- markers = getMisspellingMarkers();
- console.log(markers);
- return (
- markers.length === 1 &&
- markers[0].getBufferRange().start.column === 7 &&
- markers[0].getBufferRange().end.column === 11
- );
- });
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- });
- it('marks multiple words as wrong', async function () {
- atom.config.set('spell-check.useSystem', true);
- editor.setText('cheese chz chzz chzzz');
- atom.config.set('spell-check.grammars', ['source.js']);
- await conditionPromise(() => {
- markers = getMisspellingMarkers();
- return (
- markers.length === 3 &&
- markers[0].getBufferRange().start.column === 7 &&
- markers[0].getBufferRange().end.column === 10 &&
- markers[1].getBufferRange().start.column === 11 &&
- markers[1].getBufferRange().end.column === 15 &&
- markers[2].getBufferRange().start.column === 16 &&
- markers[2].getBufferRange().end.column === 21
- );
- });
- editor.destroy();
- expect(getMisspellingMarkers().length).toBe(0);
- });
- });
- } else {
- console.log(
- "Skipping system checker tests because they don't run on Windows CI or Linux"
- );
- }
- });
|