mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
Spellcheck - liveSpellcheck
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user