1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 17:56:25 +00:00

Spellcheck - liveSpellcheck

This commit is contained in:
ehhc
2018-06-23 18:15:16 +02:00
parent 82178055af
commit 785272540e
3 changed files with 430 additions and 36 deletions

View File

@@ -322,7 +322,7 @@ export default class CodeEditor extends React.Component {
} }
handleChange (editor, changeObject) { handleChange (editor, changeObject) {
spellcheck.handleChange(editor, changeObject) spellcheck.liveSpellcheck(editor, changeObject)
this.value = editor.getValue() this.value = editor.getValue()
if (this.props.onChange) { if (this.props.onChange) {
this.props.onChange(editor) this.props.onChange(editor)

View File

@@ -75,7 +75,7 @@ function checkMultiLineRange (thisReference, editor, from, to) {
} }
while (w < wEnd) { while (w < wEnd) {
const wordRange = editor.findWordAt({line: l, ch: w}) const wordRange = editor.findWordAt({line: l, ch: w})
thisReference.checkRange(editor, wordRange) thisReference.checkWord(editor, wordRange)
w += (wordRange.head.ch - wordRange.anchor.ch) + 1 w += (wordRange.head.ch - wordRange.anchor.ch) + 1
} }
} }
@@ -89,7 +89,7 @@ function checkMultiLineRange (thisReference, editor, from, to) {
* @param wordRange Object specifying the range that should be checked. * @param wordRange Object specifying the range that should be checked.
* Having the following structure: <code>{anchor: {line: integer, ch: integer}, head: {line: integer, ch: integer}}</code> * Having the following structure: <code>{anchor: {line: integer, ch: integer}, head: {line: integer, ch: integer}}</code>
*/ */
function checkRange (editor, wordRange) { function checkWord (editor, wordRange) {
const word = editor.getRange(wordRange.anchor, wordRange.head) const word = editor.getRange(wordRange.anchor, wordRange.head)
if (word == null || word.length <= 3) { if (word == null || word.length <= 3) {
return return
@@ -99,16 +99,21 @@ function checkRange (editor, wordRange) {
} }
} }
function handleChange (editor, changeObject) { /**
* Checks the changes recently made (aka live check)
* @param {Codemirror} editor CodeMirror-Editor
* @param changeObject codeMirror changeObject
*/
function liveSpellcheck (editor, changeObject) {
/** /**
* Returns the range that is smaller (i.e. that is before the other in the editor) * Returns the range that is smaller (i.e. that is before the other in the editor)
*/ */
function getLesserRange (from, to) { function getLesserRange (from, to) {
if (from.line > to.line) { if (from.line > to.line) {
from = to return to
} else { } else {
if (from.ch > to.ch) { if (from.ch > to.ch) {
from = to return to
} }
} }
return from return from
@@ -118,11 +123,7 @@ function handleChange (editor, changeObject) {
let to = {line: from.line, ch: from.ch} let to = {line: from.line, ch: from.ch}
const changeArray = changeObject.text || [''] const changeArray = changeObject.text || ['']
to.line += changeArray.length - 1 to.line += changeArray.length - 1
let charactersInLastLineOfChange = changeArray[changeArray.length - 1].length const charactersInLastLineOfChange = changeArray[changeArray.length - 1].length
// If the new text is not empty we need to subtract one from the length due to the counting starting at 0
if (changeArray[changeArray.length - 1] !== '') {
charactersInLastLineOfChange -= 1
}
if (from.line === to.line) { if (from.line === to.line) {
to.ch += charactersInLastLineOfChange to.ch += charactersInLastLineOfChange
} else { } else {
@@ -131,20 +132,34 @@ function handleChange (editor, changeObject) {
return to return to
} }
if (dictionary !== null) { if (dictionary === null || editor == null) { return }
try {
let rangeCheck = true
let from = getLesserRange(changeObject.from, changeObject.to) let from = getLesserRange(changeObject.from, changeObject.to)
let to = calcTo(from) let to = calcTo(from)
if (from.line === to.line && from.ch === to.ch) { const newTextLastLine = changeObject.text[changeObject.text.length - 1]
if (changeObject.text[changeObject.text.length - 1] !== '') { if (from.line === to.line && newTextLastLine.length <= 1) {
from.ch -= 1 if (newTextLastLine === '' || newTextLastLine === ' ') {
from.ch = Math.max(0, from.ch - 1)
} }
const wordRange = editor.findWordAt({line: from.line, ch: from.ch})
from = wordRange.anchor
to = wordRange.head
rangeCheck = false
} }
const existingMarks = editor.findMarks(from, to) || [] const existingMarks = editor.findMarks(from, to) || []
for (const mark of existingMarks) { for (const mark of existingMarks) {
mark.clear() mark.clear()
} }
checkMultiLineRange(this, editor, from, to)
if (rangeCheck) {
this.checkMultiLineRange(this, editor, from, to)
} else {
this.checkWord(editor, {anchor: from, head: to})
}
} catch (e) {
console.info('Error during the spell check. It might be due to problems figuring out the range of the new text..', e)
} }
} }
@@ -154,8 +169,8 @@ module.exports = {
SPELLCHECK_DISABLED, SPELLCHECK_DISABLED,
getAvailableDictionaries, getAvailableDictionaries,
initialize, initialize,
handleChange, liveSpellcheck,
checkRange, checkWord,
checkMultiLineRange, checkMultiLineRange,
checkWholeDocument, checkWholeDocument,
setDictionaryForTestsOnly setDictionaryForTestsOnly

View File

@@ -8,7 +8,7 @@ beforeEach(() => {
Typo.mockClear() Typo.mockClear()
}) })
it('should test that checkRange does not marks words that do not contain a typo', function () { it('should test that checkWord does not marks words that do not contain a typo', function () {
const testWord = 'testWord' const testWord = 'testWord'
const editor = jest.fn() const editor = jest.fn()
editor.getRange = jest.fn(() => testWord) editor.getRange = jest.fn(() => testWord)
@@ -18,14 +18,14 @@ it('should test that checkRange does not marks words that do not contain a typo'
mockDictionary.check = jest.fn(() => true) mockDictionary.check = jest.fn(() => true)
systemUnderTest.setDictionaryForTestsOnly(mockDictionary) systemUnderTest.setDictionaryForTestsOnly(mockDictionary)
systemUnderTest.checkRange(editor, range) systemUnderTest.checkWord(editor, range)
expect(editor.getRange).toHaveBeenCalledWith(range.anchor, range.head) expect(editor.getRange).toHaveBeenCalledWith(range.anchor, range.head)
expect(mockDictionary.check).toHaveBeenCalledWith(testWord) expect(mockDictionary.check).toHaveBeenCalledWith(testWord)
expect(editor.markText).not.toHaveBeenCalled() expect(editor.markText).not.toHaveBeenCalled()
}) })
it('should test that checkRange should marks words that contain a typo', function () { it('should test that checkWord should marks words that contain a typo', function () {
const testWord = 'testWord' const testWord = 'testWord'
const editor = jest.fn() const editor = jest.fn()
editor.getRange = jest.fn(() => testWord) editor.getRange = jest.fn(() => testWord)
@@ -35,7 +35,7 @@ it('should test that checkRange should marks words that contain a typo', functio
mockDictionary.check = jest.fn(() => false) mockDictionary.check = jest.fn(() => false)
systemUnderTest.setDictionaryForTestsOnly(mockDictionary) systemUnderTest.setDictionaryForTestsOnly(mockDictionary)
systemUnderTest.checkRange(editor, range) systemUnderTest.checkWord(editor, range)
expect(editor.getRange).toHaveBeenCalledWith(range.anchor, range.head) expect(editor.getRange).toHaveBeenCalledWith(range.anchor, range.head)
expect(mockDictionary.check).toHaveBeenCalledWith(testWord) expect(mockDictionary.check).toHaveBeenCalledWith(testWord)
@@ -117,7 +117,7 @@ it('should test that checkMultiLineRange performs checks for each word in the st
editor.findWordAt.mockReturnValueOnce(ranges[8]) editor.findWordAt.mockReturnValueOnce(ranges[8])
editor.findWordAt.mockReturnValueOnce(ranges[9]) editor.findWordAt.mockReturnValueOnce(ranges[9])
editor.findWordAt.mockReturnValueOnce(ranges[10]) editor.findWordAt.mockReturnValueOnce(ranges[10])
const checkRangeSpy = jest.spyOn(systemUnderTest, 'checkRange').mockImplementation() const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
systemUnderTest.checkMultiLineRange(systemUnderTest, editor, rangeFrom, rangeTo) systemUnderTest.checkMultiLineRange(systemUnderTest, editor, rangeFrom, rangeTo)
@@ -134,18 +134,397 @@ it('should test that checkMultiLineRange performs checks for each word in the st
expect(editor.findWordAt.mock.calls[8][0]).toEqual({line: 3, ch: 0}) expect(editor.findWordAt.mock.calls[8][0]).toEqual({line: 3, ch: 0})
expect(editor.findWordAt.mock.calls[9][0]).toEqual({line: 3, ch: 11}) expect(editor.findWordAt.mock.calls[9][0]).toEqual({line: 3, ch: 11})
expect(editor.findWordAt.mock.calls[10][0]).toEqual({line: 3, ch: 12}) expect(editor.findWordAt.mock.calls[10][0]).toEqual({line: 3, ch: 12})
expect(checkRangeSpy).toHaveBeenCalledTimes(11) expect(checkWordSpy).toHaveBeenCalledTimes(11)
expect(checkRangeSpy.mock.calls[0][1]).toEqual(ranges[0]) expect(checkWordSpy.mock.calls[0][1]).toEqual(ranges[0])
expect(checkRangeSpy.mock.calls[1][1]).toEqual(ranges[1]) expect(checkWordSpy.mock.calls[1][1]).toEqual(ranges[1])
expect(checkRangeSpy.mock.calls[2][1]).toEqual(ranges[2]) expect(checkWordSpy.mock.calls[2][1]).toEqual(ranges[2])
expect(checkRangeSpy.mock.calls[3][1]).toEqual(ranges[3]) expect(checkWordSpy.mock.calls[3][1]).toEqual(ranges[3])
expect(checkRangeSpy.mock.calls[4][1]).toEqual(ranges[4]) expect(checkWordSpy.mock.calls[4][1]).toEqual(ranges[4])
expect(checkRangeSpy.mock.calls[5][1]).toEqual(ranges[5]) expect(checkWordSpy.mock.calls[5][1]).toEqual(ranges[5])
expect(checkRangeSpy.mock.calls[6][1]).toEqual(ranges[6]) expect(checkWordSpy.mock.calls[6][1]).toEqual(ranges[6])
expect(checkRangeSpy.mock.calls[7][1]).toEqual(ranges[7]) expect(checkWordSpy.mock.calls[7][1]).toEqual(ranges[7])
expect(checkRangeSpy.mock.calls[8][1]).toEqual(ranges[8]) expect(checkWordSpy.mock.calls[8][1]).toEqual(ranges[8])
expect(checkRangeSpy.mock.calls[9][1]).toEqual(ranges[9]) expect(checkWordSpy.mock.calls[9][1]).toEqual(ranges[9])
expect(checkRangeSpy.mock.calls[10][1]).toEqual(ranges[10]) expect(checkWordSpy.mock.calls[10][1]).toEqual(ranges[10])
checkRangeSpy.mockRestore() checkWordSpy.mockRestore()
})
it('should make sure that liveSpellcheck dont work if the spellcheck is not enabled', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const editor = jest.fn()
editor.findMarks = jest.fn()
systemUnderTest.setDictionaryForTestsOnly(null)
systemUnderTest.liveSpellcheck(editor, {})
expect(checkWordSpy).not.toHaveBeenCalled()
expect(checkMultiLineRangeSpy).not.toHaveBeenCalled()
expect(editor.findMarks).not.toHaveBeenCalled()
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
})
it('should make sure that liveSpellcheck works for a range of changes', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const editor = jest.fn()
editor.findMarks = jest.fn()
const dummyDictionary = jest.fn()
const changeObject = {
from: {line: 2, ch: 0},
to: {line: 7, ch: 13},
text: [
'first line',
'second line',
'third line'
]
}
const expectedFrom = changeObject.from
const expectedTo = {line: 4, ch: 10}
systemUnderTest.setDictionaryForTestsOnly(dummyDictionary)
systemUnderTest.liveSpellcheck(editor, changeObject)
expect(checkWordSpy).not.toHaveBeenCalled()
expect(checkMultiLineRangeSpy).toHaveBeenCalledTimes(1)
expect(checkMultiLineRangeSpy.mock.calls[0][1]).toEqual(editor)
expect(checkMultiLineRangeSpy.mock.calls[0][2]).toEqual(expectedFrom)
expect(checkMultiLineRangeSpy.mock.calls[0][3]).toEqual(expectedTo)
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
})
it('should make sure that liveSpellcheck works for a range of changes with inverted from to range (due to paste action)', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const editor = jest.fn()
editor.findMarks = jest.fn()
const dummyDictionary = jest.fn()
const changeObject = {
from: {line: 7, ch: 12},
to: {line: 2, ch: 0},
text: [
'first line',
'second line',
'third line'
]
}
const expectedFrom = changeObject.to
const expectedTo = {line: 4, ch: 10}
systemUnderTest.setDictionaryForTestsOnly(dummyDictionary)
systemUnderTest.liveSpellcheck(editor, changeObject)
expect(checkWordSpy).not.toHaveBeenCalled()
expect(checkMultiLineRangeSpy).toHaveBeenCalledTimes(1)
expect(checkMultiLineRangeSpy.mock.calls[0][1]).toEqual(editor)
expect(checkMultiLineRangeSpy.mock.calls[0][2]).toEqual(expectedFrom)
expect(checkMultiLineRangeSpy.mock.calls[0][3]).toEqual(expectedTo)
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
})
it('should make sure that liveSpellcheck deletes all existing marks in the given range', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const editor = jest.fn()
const dummyMarks = [
{clear: jest.fn()},
{clear: jest.fn()},
{clear: jest.fn()}
]
editor.findMarks = jest.fn(() => dummyMarks)
const dummyDictionary = jest.fn()
const changeObject = {
from: {line: 7, ch: 12},
to: {line: 2, ch: 0},
text: [
'first line',
'second line',
'third line'
]
}
const expectedFrom = changeObject.to
const expectedTo = {line: 4, ch: 10}
systemUnderTest.setDictionaryForTestsOnly(dummyDictionary)
systemUnderTest.liveSpellcheck(editor, changeObject)
expect(editor.findMarks).toHaveBeenCalledWith(expectedFrom, expectedTo)
for (const dummyMark of dummyMarks) {
expect(dummyMark.clear).toHaveBeenCalled()
}
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
})
it('should make sure that liveSpellcheck works when adding a sign', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const dummyWordRangeResult = {anchor: {line: 33, ch: 33}, head: {line: 33, ch: 34}}
const editor = jest.fn()
editor.findMarks = jest.fn()
editor.findWordAt = jest.fn(() => dummyWordRangeResult)
const dummyDictionary = jest.fn()
const changeObject = {
from: {line: 2, ch: 0},
to: {line: 2, ch: 1},
text: [
'a'
]
}
systemUnderTest.setDictionaryForTestsOnly(dummyDictionary)
systemUnderTest.liveSpellcheck(editor, changeObject)
expect(checkMultiLineRangeSpy).not.toHaveBeenCalled()
expect(checkWordSpy).toHaveBeenCalledTimes(1)
expect(editor.findWordAt).toHaveBeenCalledWith(changeObject.from)
expect(checkWordSpy.mock.calls[0][0]).toEqual(editor)
expect(checkWordSpy.mock.calls[0][1]).toEqual(dummyWordRangeResult)
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
})
it('should make sure that liveSpellcheck deletes the correct mark when adding a sign', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const dummyWordRangeResult = {anchor: {line: 33, ch: 33}, head: {line: 33, ch: 34}}
const editor = jest.fn()
const dummyMarks = [
{clear: jest.fn()},
{clear: jest.fn()},
{clear: jest.fn()}
]
editor.findMarks = jest.fn(() => dummyMarks)
editor.findWordAt = jest.fn(() => dummyWordRangeResult)
const dummyDictionary = jest.fn()
const changeObject = {
from: {line: 2, ch: 0},
to: {line: 2, ch: 1},
text: [
'a'
]
}
systemUnderTest.setDictionaryForTestsOnly(dummyDictionary)
systemUnderTest.liveSpellcheck(editor, changeObject)
expect(checkMultiLineRangeSpy).not.toHaveBeenCalled()
expect(checkWordSpy).toHaveBeenCalledTimes(1)
expect(editor.findWordAt).toHaveBeenCalledWith(changeObject.from)
expect(editor.findMarks).toHaveBeenCalledWith(dummyWordRangeResult.anchor, dummyWordRangeResult.head)
for (const dummyMark of dummyMarks) {
expect(dummyMark.clear).toHaveBeenCalled()
}
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
})
it('should make sure that liveSpellcheck works when deleting a sign', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const dummyWordRangeResult = {anchor: {line: 33, ch: 33}, head: {line: 33, ch: 34}}
const editor = jest.fn()
editor.findMarks = jest.fn()
editor.findWordAt = jest.fn(() => dummyWordRangeResult)
const dummyDictionary = jest.fn()
const changeObject = {
from: {line: 2, ch: 10},
to: {line: 2, ch: 10},
text: [
''
]
}
const expectedFrom = {line: 2, ch: 9}
systemUnderTest.setDictionaryForTestsOnly(dummyDictionary)
systemUnderTest.liveSpellcheck(editor, changeObject)
expect(checkMultiLineRangeSpy).not.toHaveBeenCalled()
expect(checkWordSpy).toHaveBeenCalledTimes(1)
expect(editor.findWordAt).toHaveBeenCalledWith(expectedFrom)
expect(checkWordSpy.mock.calls[0][0]).toEqual(editor)
expect(checkWordSpy.mock.calls[0][1]).toEqual(dummyWordRangeResult)
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
})
it('should make sure that liveSpellcheck deletes the right marks when deleting a sign', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const dummyWordRangeResult = {anchor: {line: 33, ch: 33}, head: {line: 33, ch: 34}}
const editor = jest.fn()
const dummyMarks = [
{clear: jest.fn()},
{clear: jest.fn()},
{clear: jest.fn()}
]
editor.findMarks = jest.fn(() => dummyMarks)
editor.findWordAt = jest.fn(() => dummyWordRangeResult)
const dummyDictionary = jest.fn()
const changeObject = {
from: {line: 2, ch: 10},
to: {line: 2, ch: 10},
text: [
''
]
}
systemUnderTest.setDictionaryForTestsOnly(dummyDictionary)
systemUnderTest.liveSpellcheck(editor, changeObject)
expect(checkMultiLineRangeSpy).not.toHaveBeenCalled()
expect(checkWordSpy).toHaveBeenCalledTimes(1)
expect(editor.findMarks).toHaveBeenCalledWith(dummyWordRangeResult.anchor, dummyWordRangeResult.head)
for (const dummyMark of dummyMarks) {
expect(dummyMark.clear).toHaveBeenCalled()
}
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
})
it('should make sure that liveSpellcheck works when inserting a space', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const dummyWordRangeResult = {anchor: {line: 33, ch: 33}, head: {line: 33, ch: 34}}
const editor = jest.fn()
editor.findMarks = jest.fn()
editor.findWordAt = jest.fn(() => dummyWordRangeResult)
const dummyDictionary = jest.fn()
const changeObject = {
from: {line: 2, ch: 10},
to: {line: 2, ch: 10},
text: [
' '
]
}
const expectedFrom = {line: 2, ch: 9}
systemUnderTest.setDictionaryForTestsOnly(dummyDictionary)
systemUnderTest.liveSpellcheck(editor, changeObject)
expect(checkMultiLineRangeSpy).not.toHaveBeenCalled()
expect(checkWordSpy).toHaveBeenCalledTimes(1)
expect(editor.findWordAt).toHaveBeenCalledWith(expectedFrom)
expect(checkWordSpy.mock.calls[0][0]).toEqual(editor)
expect(checkWordSpy.mock.calls[0][1]).toEqual(dummyWordRangeResult)
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
})
it('should make sure that liveSpellcheck deletes the right marks when inserting a space', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const dummyWordRangeResult = {anchor: {line: 33, ch: 33}, head: {line: 33, ch: 34}}
const editor = jest.fn()
const dummyMarks = [
{clear: jest.fn()},
{clear: jest.fn()},
{clear: jest.fn()}
]
editor.findMarks = jest.fn(() => dummyMarks)
editor.findWordAt = jest.fn(() => dummyWordRangeResult)
const dummyDictionary = jest.fn()
const changeObject = {
from: {line: 2, ch: 10},
to: {line: 2, ch: 10},
text: [
' '
]
}
systemUnderTest.setDictionaryForTestsOnly(dummyDictionary)
systemUnderTest.liveSpellcheck(editor, changeObject)
expect(checkMultiLineRangeSpy).not.toHaveBeenCalled()
expect(checkWordSpy).toHaveBeenCalledTimes(1)
expect(editor.findMarks).toHaveBeenCalledWith(dummyWordRangeResult.anchor, dummyWordRangeResult.head)
for (const dummyMark of dummyMarks) {
expect(dummyMark.clear).toHaveBeenCalled()
}
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
})
it('should make sure that liveSpellcheck works when a character is replaced', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const dummyWordRangeResult = {anchor: {line: 33, ch: 33}, head: {line: 33, ch: 34}}
const editor = jest.fn()
editor.findMarks = jest.fn()
editor.findWordAt = jest.fn(() => dummyWordRangeResult)
const dummyDictionary = jest.fn()
const changeObject = {
from: {line: 2, ch: 9},
to: {line: 2, ch: 8},
text: [
'a'
]
}
const expectedFrom = {line: 2, ch: 8}
systemUnderTest.setDictionaryForTestsOnly(dummyDictionary)
systemUnderTest.liveSpellcheck(editor, changeObject)
expect(checkMultiLineRangeSpy).not.toHaveBeenCalled()
expect(checkWordSpy).toHaveBeenCalledTimes(1)
expect(editor.findWordAt).toHaveBeenCalledWith(expectedFrom)
expect(checkWordSpy.mock.calls[0][0]).toEqual(editor)
expect(checkWordSpy.mock.calls[0][1]).toEqual(dummyWordRangeResult)
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
})
it('should make sure that liveSpellcheck deletes the right marks when a character is replaced', function () {
const checkMultiLineRangeSpy = jest.spyOn(systemUnderTest, 'checkMultiLineRange').mockImplementation()
const checkWordSpy = jest.spyOn(systemUnderTest, 'checkWord').mockImplementation()
const dummyWordRangeResult = {anchor: {line: 33, ch: 33}, head: {line: 33, ch: 34}}
const editor = jest.fn()
const dummyMarks = [
{clear: jest.fn()},
{clear: jest.fn()},
{clear: jest.fn()}
]
editor.findMarks = jest.fn(() => dummyMarks)
editor.findWordAt = jest.fn(() => dummyWordRangeResult)
const dummyDictionary = jest.fn()
const changeObject = {
from: {line: 2, ch: 9},
to: {line: 2, ch: 8},
text: [
'b'
]
}
systemUnderTest.setDictionaryForTestsOnly(dummyDictionary)
systemUnderTest.liveSpellcheck(editor, changeObject)
expect(checkMultiLineRangeSpy).not.toHaveBeenCalled()
expect(checkWordSpy).toHaveBeenCalledTimes(1)
expect(editor.findMarks).toHaveBeenCalledWith(dummyWordRangeResult.anchor, dummyWordRangeResult.head)
for (const dummyMark of dummyMarks) {
expect(dummyMark.clear).toHaveBeenCalled()
}
checkWordSpy.mockRestore()
checkMultiLineRangeSpy.mockRestore()
}) })