mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #2561 from overleaf/pr-reduce-spellcheck-initial-req
Reduce spellcheck initial (and subsequent) requests GitOrigin-RevId: 81eee359ea1bc740991ba84b0fe121c37cb4c6a2
This commit is contained in:
parent
72c5286622
commit
73defe82d9
4 changed files with 658 additions and 453 deletions
|
@ -154,12 +154,9 @@ define([
|
||||||
|
|
||||||
if (scope.spellCheck) {
|
if (scope.spellCheck) {
|
||||||
// only enable spellcheck when explicitly required
|
// only enable spellcheck when explicitly required
|
||||||
const spellCheckCache =
|
|
||||||
$cacheFactory.get(`spellCheck-${scope.name}`) ||
|
|
||||||
$cacheFactory(`spellCheck-${scope.name}`, { capacity: 1000 })
|
|
||||||
spellCheckManager = new SpellCheckManager(
|
spellCheckManager = new SpellCheckManager(
|
||||||
scope,
|
scope,
|
||||||
spellCheckCache,
|
$cacheFactory,
|
||||||
$http,
|
$http,
|
||||||
$q,
|
$q,
|
||||||
new SpellCheckAdapter(editor)
|
new SpellCheckAdapter(editor)
|
||||||
|
@ -893,63 +890,63 @@ define([
|
||||||
|
|
||||||
template: `\
|
template: `\
|
||||||
<div class="ace-editor-wrapper">
|
<div class="ace-editor-wrapper">
|
||||||
<div
|
<div
|
||||||
class="undo-conflict-warning alert alert-danger small"
|
class="undo-conflict-warning alert alert-danger small"
|
||||||
ng-show="undo.show_remote_warning"
|
ng-show="undo.show_remote_warning"
|
||||||
>
|
>
|
||||||
<strong>Watch out!</strong>
|
<strong>Watch out!</strong>
|
||||||
We had to undo some of your collaborators changes before we could undo yours.
|
We had to undo some of your collaborators changes before we could undo yours.
|
||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
class="pull-right"
|
class="pull-right"
|
||||||
ng-click="undo.show_remote_warning = false"
|
ng-click="undo.show_remote_warning = false"
|
||||||
>Dismiss</a>
|
>Dismiss</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="ace-editor-body"></div>
|
<div class="ace-editor-body"></div>
|
||||||
<spell-menu
|
<spell-menu
|
||||||
open="spellMenu.open"
|
open="spellMenu.open"
|
||||||
top="spellMenu.top"
|
top="spellMenu.top"
|
||||||
left="spellMenu.left"
|
left="spellMenu.left"
|
||||||
layout-from-bottom="spellMenu.layoutFromBottom"
|
layout-from-bottom="spellMenu.layoutFromBottom"
|
||||||
highlight="spellMenu.highlight"
|
highlight="spellMenu.highlight"
|
||||||
replace-word="replaceWord(highlight, suggestion)"
|
replace-word="replaceWord(highlight, suggestion)"
|
||||||
learn-word="learnWord(highlight)"
|
learn-word="learnWord(highlight)"
|
||||||
></spell-menu>
|
></spell-menu>
|
||||||
<div
|
<div
|
||||||
class="annotation-label"
|
class="annotation-label"
|
||||||
ng-show="annotationLabel.show"
|
ng-show="annotationLabel.show"
|
||||||
ng-style="{
|
ng-style="{
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: annotationLabel.left,
|
left: annotationLabel.left,
|
||||||
right: annotationLabel.right,
|
right: annotationLabel.right,
|
||||||
bottom: annotationLabel.bottom,
|
bottom: annotationLabel.bottom,
|
||||||
top: annotationLabel.top,
|
top: annotationLabel.top,
|
||||||
'background-color': annotationLabel.backgroundColor
|
'background-color': annotationLabel.backgroundColor
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ annotationLabel.text }}
|
{{ annotationLabel.text }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href
|
href
|
||||||
class="highlights-before-label btn btn-info btn-xs"
|
class="highlights-before-label btn btn-info btn-xs"
|
||||||
ng-show="updateLabels.highlightsBefore > 0"
|
ng-show="updateLabels.highlightsBefore > 0"
|
||||||
ng-click="gotoHighlightAbove()"
|
ng-click="gotoHighlightAbove()"
|
||||||
>
|
>
|
||||||
<i class="fa fa-fw fa-arrow-up"></i>
|
<i class="fa fa-fw fa-arrow-up"></i>
|
||||||
{{ updateLabels.highlightsBefore }} more update{{ updateLabels.highlightsBefore > 1 && "" || "s" }} above
|
{{ updateLabels.highlightsBefore }} more update{{ updateLabels.highlightsBefore > 1 && "" || "s" }} above
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href
|
href
|
||||||
class="highlights-after-label btn btn-info btn-xs"
|
class="highlights-after-label btn btn-info btn-xs"
|
||||||
ng-show="updateLabels.highlightsAfter > 0"
|
ng-show="updateLabels.highlightsAfter > 0"
|
||||||
ng-click="gotoHighlightBelow()"
|
ng-click="gotoHighlightBelow()"
|
||||||
>
|
>
|
||||||
<i class="fa fa-fw fa-arrow-down"></i>
|
<i class="fa fa-fw fa-arrow-down"></i>
|
||||||
{{ updateLabels.highlightsAfter }} more update{{ updateLabels.highlightsAfter > 1 && "" || "s" }} below
|
{{ updateLabels.highlightsAfter }} more update{{ updateLabels.highlightsAfter > 1 && "" || "s" }} below
|
||||||
|
|
||||||
</a>
|
</a>
|
||||||
</div>\
|
</div>\
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
@ -958,37 +955,37 @@ define([
|
||||||
function monkeyPatchSearch($rootScope, $compile) {
|
function monkeyPatchSearch($rootScope, $compile) {
|
||||||
const searchHtml = `\
|
const searchHtml = `\
|
||||||
<div class="ace_search right">
|
<div class="ace_search right">
|
||||||
<a href type="button" action="hide" class="ace_searchbtn_close">
|
<a href type="button" action="hide" class="ace_searchbtn_close">
|
||||||
<i class="fa fa-fw fa-times"></i>
|
<i class="fa fa-fw fa-times"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="ace_search_form">
|
<div class="ace_search_form">
|
||||||
<input class="ace_search_field form-control input-sm" placeholder="Search for" spellcheck="false"></input>
|
<input class="ace_search_field form-control input-sm" placeholder="Search for" spellcheck="false"></input>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" action="findNext" class="ace_searchbtn next btn btn-default btn-sm">
|
<button type="button" action="findNext" class="ace_searchbtn next btn btn-default btn-sm">
|
||||||
<i class="fa fa-chevron-down fa-fw"></i>
|
<i class="fa fa-chevron-down fa-fw"></i>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" action="findPrev" class="ace_searchbtn prev btn btn-default btn-sm">
|
<button type="button" action="findPrev" class="ace_searchbtn prev btn btn-default btn-sm">
|
||||||
<i class="fa fa-chevron-up fa-fw"></i>
|
<i class="fa fa-chevron-up fa-fw"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ace_replace_form">
|
<div class="ace_replace_form">
|
||||||
<input class="ace_search_field form-control input-sm" placeholder="Replace with" spellcheck="false"></input>
|
<input class="ace_search_field form-control input-sm" placeholder="Replace with" spellcheck="false"></input>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" action="replaceAndFindNext" class="ace_replacebtn btn btn-default btn-sm">Replace</button>
|
<button type="button" action="replaceAndFindNext" class="ace_replacebtn btn btn-default btn-sm">Replace</button>
|
||||||
<button type="button" action="replaceAll" class="ace_replacebtn btn btn-default btn-sm">All</button>
|
<button type="button" action="replaceAll" class="ace_replacebtn btn btn-default btn-sm">All</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ace_search_options">
|
<div class="ace_search_options">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button action="toggleRegexpMode" class="btn btn-default btn-sm" tooltip-placement="bottom" tooltip-append-to-body="true" tooltip="RegExp Search">.*</button>
|
<button action="toggleRegexpMode" class="btn btn-default btn-sm" tooltip-placement="bottom" tooltip-append-to-body="true" tooltip="RegExp Search">.*</button>
|
||||||
<button action="toggleCaseSensitive" class="btn btn-default btn-sm" tooltip-placement="bottom" tooltip-append-to-body="true" tooltip="CaseSensitive Search">Aa</button>
|
<button action="toggleCaseSensitive" class="btn btn-default btn-sm" tooltip-placement="bottom" tooltip-append-to-body="true" tooltip="CaseSensitive Search">Aa</button>
|
||||||
<button action="toggleWholeWords" class="btn btn-default btn-sm" tooltip-placement="bottom" tooltip-append-to-body="true" tooltip="Whole Word Search">"..."</button>
|
<button action="toggleWholeWords" class="btn btn-default btn-sm" tooltip-placement="bottom" tooltip-append-to-body="true" tooltip="Whole Word Search">"..."</button>
|
||||||
<button action="searchInSelection" class="btn btn-default btn-sm" tooltip-placement="bottom" tooltip-append-to-body="true" tooltip="Search Within Selection"><i class="fa fa-align-left"></i></button>
|
<button action="searchInSelection" class="btn btn-default btn-sm" tooltip-placement="bottom" tooltip-append-to-body="true" tooltip="Search Within Selection"><i class="fa fa-align-left"></i></button>
|
||||||
</div>
|
</div>
|
||||||
<span class="ace_search_counter"></span>
|
<span class="ace_search_counter"></span>
|
||||||
</div>
|
</div>
|
||||||
<div action="toggleReplace" class="hidden"></div>
|
<div action="toggleReplace" class="hidden"></div>
|
||||||
</div>\
|
</div>\
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,10 @@
|
||||||
/* eslint-disable
|
|
||||||
max-len,
|
|
||||||
no-undef,
|
|
||||||
no-unused-vars,
|
|
||||||
*/
|
|
||||||
// TODO: This file was created by bulk-decaffeinate.
|
|
||||||
// Fix any style issues and re-enable lint.
|
|
||||||
/*
|
|
||||||
* decaffeinate suggestions:
|
|
||||||
* DS102: Remove unnecessary code created because of implicit returns
|
|
||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
||||||
*/
|
|
||||||
define([
|
define([
|
||||||
'ace/ace',
|
'ace/ace',
|
||||||
'ide/editor/directives/aceEditor/spell-check/HighlightedWordManager'
|
'ide/editor/directives/aceEditor/spell-check/HighlightedWordManager'
|
||||||
], function(Ace, HighlightedWordManager) {
|
], function(Ace, HighlightedWordManager) {
|
||||||
let SpellCheckAdapter
|
|
||||||
const { Range } = ace.require('ace/range')
|
const { Range } = ace.require('ace/range')
|
||||||
|
|
||||||
return (SpellCheckAdapter = class SpellCheckAdapter {
|
class SpellCheckAdapter {
|
||||||
constructor(editor) {
|
constructor(editor) {
|
||||||
this.replaceWord = this.replaceWord.bind(this)
|
this.replaceWord = this.replaceWord.bind(this)
|
||||||
this.editor = editor
|
this.editor = editor
|
||||||
|
@ -28,6 +15,22 @@ define([
|
||||||
return this.editor.getValue().split('\n')
|
return this.editor.getValue().split('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getLineCount() {
|
||||||
|
return this.editor.session.getLength()
|
||||||
|
}
|
||||||
|
|
||||||
|
getFirstVisibleRowNum() {
|
||||||
|
return this.editor.renderer.layerConfig.firstRow
|
||||||
|
}
|
||||||
|
|
||||||
|
getLastVisibleRowNum() {
|
||||||
|
return this.editor.renderer.layerConfig.lastRow
|
||||||
|
}
|
||||||
|
|
||||||
|
getLinesByRows(rows) {
|
||||||
|
return rows.map(rowIdx => this.editor.session.doc.getLine(rowIdx))
|
||||||
|
}
|
||||||
|
|
||||||
normalizeChangeEvent(e) {
|
normalizeChangeEvent(e) {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -41,7 +44,7 @@ define([
|
||||||
}
|
}
|
||||||
|
|
||||||
preventContextMenuEventDefault(e) {
|
preventContextMenuEventDefault(e) {
|
||||||
return e.domEvent.preventDefault()
|
e.domEvent.preventDefault()
|
||||||
}
|
}
|
||||||
|
|
||||||
getHighlightFromCoords(coords) {
|
getHighlightFromCoords(coords) {
|
||||||
|
@ -68,7 +71,7 @@ define([
|
||||||
const startColumn = highlight.range.start.column
|
const startColumn = highlight.range.start.column
|
||||||
const endColumn = highlight.range.end.column
|
const endColumn = highlight.range.end.column
|
||||||
|
|
||||||
return this.editor
|
this.editor
|
||||||
.getSession()
|
.getSession()
|
||||||
.getSelection()
|
.getSelection()
|
||||||
.setSelectionRange(new Range(row, startColumn, row, endColumn))
|
.setSelectionRange(new Range(row, startColumn, row, endColumn))
|
||||||
|
@ -84,7 +87,9 @@ define([
|
||||||
.replace(new Range(row, startColumn, row, endColumn), newWord)
|
.replace(new Range(row, startColumn, row, endColumn), newWord)
|
||||||
|
|
||||||
// Bring editor back into focus after clicking on suggestion
|
// Bring editor back into focus after clicking on suggestion
|
||||||
return this.editor.focus()
|
this.editor.focus()
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
return SpellCheckAdapter
|
||||||
})
|
})
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -15,7 +15,6 @@ define([
|
||||||
describe('SpellCheckManager', function() {
|
describe('SpellCheckManager', function() {
|
||||||
beforeEach(function(done) {
|
beforeEach(function(done) {
|
||||||
this.timelord = sinon.useFakeTimers()
|
this.timelord = sinon.useFakeTimers()
|
||||||
|
|
||||||
window.user = { id: 1 }
|
window.user = { id: 1 }
|
||||||
window.csrfToken = 'token'
|
window.csrfToken = 'token'
|
||||||
this.scope = {
|
this.scope = {
|
||||||
|
@ -29,17 +28,19 @@ define([
|
||||||
addHighlight: sinon.stub()
|
addHighlight: sinon.stub()
|
||||||
}
|
}
|
||||||
this.adapter = {
|
this.adapter = {
|
||||||
getLines: sinon.stub(),
|
getLineCount: sinon.stub(),
|
||||||
|
getFirstVisibleRowNum: sinon.stub(),
|
||||||
|
getLastVisibleRowNum: sinon.stub(),
|
||||||
|
getLinesByRows: sinon.stub(),
|
||||||
highlightedWordManager: this.highlightedWordManager
|
highlightedWordManager: this.highlightedWordManager
|
||||||
}
|
}
|
||||||
return inject(($q, $http, $httpBackend, $cacheFactory) => {
|
return inject(($q, $http, $httpBackend, $cacheFactory) => {
|
||||||
this.$http = $http
|
this.$http = $http
|
||||||
this.$q = $q
|
this.$q = $q
|
||||||
this.$httpBackend = $httpBackend
|
this.$httpBackend = $httpBackend
|
||||||
const cache = $cacheFactory('spellCheckTest', { capacity: 1000 })
|
|
||||||
this.spellCheckManager = new SpellCheckManager(
|
this.spellCheckManager = new SpellCheckManager(
|
||||||
this.scope,
|
this.scope,
|
||||||
cache,
|
$cacheFactory,
|
||||||
$http,
|
$http,
|
||||||
$q,
|
$q,
|
||||||
this.adapter
|
this.adapter
|
||||||
|
@ -52,7 +53,7 @@ define([
|
||||||
return this.timelord.restore()
|
return this.timelord.restore()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('runs a full check soon after init', function() {
|
it('adds an highlight when a misspelling is found', function() {
|
||||||
this.$httpBackend.when('POST', '/spelling/check').respond({
|
this.$httpBackend.when('POST', '/spelling/check').respond({
|
||||||
misspellings: [
|
misspellings: [
|
||||||
{
|
{
|
||||||
|
@ -61,11 +62,225 @@ define([
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
this.adapter.getLines.returns(['oppozition'])
|
this.adapter.getLinesByRows.returns(['oppozition'])
|
||||||
this.spellCheckManager.init()
|
this.spellCheckManager.init()
|
||||||
this.timelord.tick(200)
|
this.timelord.tick(200)
|
||||||
this.$httpBackend.flush()
|
this.$httpBackend.flush()
|
||||||
return expect(this.highlightedWordManager.addHighlight).to.have.been
|
expect(this.highlightedWordManager.addHighlight).to.have.been.called
|
||||||
.called
|
})
|
||||||
|
|
||||||
|
describe('runSpellCheck', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.adapter.getLineCount.returns(10)
|
||||||
|
this.adapter.getFirstVisibleRowNum.returns(3)
|
||||||
|
this.adapter.getLastVisibleRowNum.returns(5)
|
||||||
|
this.adapter.getLinesByRows.returns([
|
||||||
|
'Lorem ipsum dolor sit amet',
|
||||||
|
'consectetur adipisicing elit',
|
||||||
|
'sed do eiusmod'
|
||||||
|
])
|
||||||
|
this.$httpBackend.when('POST', '/spelling/check').respond({
|
||||||
|
misspellings: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
suggestions: ['opposition']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
it('only checks visible lines', function() {
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.timelord.tick(200)
|
||||||
|
this.$httpBackend.flush()
|
||||||
|
expect(this.adapter.getLinesByRows).to.have.been.calledWith([3, 4, 5])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('ignores updated lines', function() {
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.spellCheckManager.changedLines[4] = false
|
||||||
|
this.timelord.tick(200)
|
||||||
|
this.$httpBackend.flush()
|
||||||
|
expect(this.adapter.getLinesByRows).to.have.been.calledWith([3, 5])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('clears highlights for changed lines', function() {
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.timelord.tick(200)
|
||||||
|
this.$httpBackend.flush()
|
||||||
|
expect(
|
||||||
|
this.highlightedWordManager.clearRow.getCall(0).args[0]
|
||||||
|
).to.equal(3)
|
||||||
|
expect(
|
||||||
|
this.highlightedWordManager.clearRow.getCall(1).args[0]
|
||||||
|
).to.equal(4)
|
||||||
|
expect(
|
||||||
|
this.highlightedWordManager.clearRow.getCall(2).args[0]
|
||||||
|
).to.equal(5)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('initially flags all lines as dirty', function() {
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
expect(this.spellCheckManager.changedLines)
|
||||||
|
.to.have.lengthOf(10)
|
||||||
|
.and.to.not.include(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('initially flags checked lines as non-dirty', function() {
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.timelord.tick(200)
|
||||||
|
this.$httpBackend.flush()
|
||||||
|
expect(this.spellCheckManager.changedLines[2]).to.equal(true)
|
||||||
|
expect(this.spellCheckManager.changedLines[3]).to.equal(false)
|
||||||
|
expect(this.spellCheckManager.changedLines[4]).to.equal(false)
|
||||||
|
expect(this.spellCheckManager.changedLines[5]).to.equal(false)
|
||||||
|
expect(this.spellCheckManager.changedLines[6]).to.equal(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('cache', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.adapter.getLineCount.returns(1)
|
||||||
|
this.adapter.getFirstVisibleRowNum.returns(1)
|
||||||
|
this.adapter.getLastVisibleRowNum.returns(1)
|
||||||
|
this.adapter.getLinesByRows.returns(['Lorem ipsum dolor'])
|
||||||
|
this.$httpBackend.when('POST', '/spelling/check').respond({
|
||||||
|
misspellings: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
suggestions: ['foobarbaz']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('adds already checked words to the spellchecker cache', function() {
|
||||||
|
expect(this.spellCheckManager.cache.info().size).to.equal(0)
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.timelord.tick(200)
|
||||||
|
this.$httpBackend.flush()
|
||||||
|
expect(this.spellCheckManager.cache.info().size).to.equal(3)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('adds misspeled word suggestions to the cache', function() {
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.timelord.tick(200)
|
||||||
|
this.$httpBackend.flush()
|
||||||
|
|
||||||
|
expect(
|
||||||
|
this.spellCheckManager.cache.get(
|
||||||
|
`${this.scope.spellCheckLanguage}:Lorem`
|
||||||
|
)
|
||||||
|
).to.eql(['foobarbaz'])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('adds non-misspeled words to the cache as a boolean', function() {
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.timelord.tick(200)
|
||||||
|
this.$httpBackend.flush()
|
||||||
|
expect(
|
||||||
|
this.spellCheckManager.cache.get(
|
||||||
|
`${this.scope.spellCheckLanguage}:ipsum`
|
||||||
|
)
|
||||||
|
).to.equal(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('backend', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.adapter.getLineCount.returns(1)
|
||||||
|
this.adapter.getFirstVisibleRowNum.returns(1)
|
||||||
|
this.adapter.getLastVisibleRowNum.returns(1)
|
||||||
|
this.adapter.getLinesByRows.returns(['Lorem ipsum dolor'])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('hits the backend with all words at startup', function() {
|
||||||
|
this.$httpBackend
|
||||||
|
.expect('POST', '/spelling/check', {
|
||||||
|
language: this.scope.spellCheckLanguage,
|
||||||
|
words: ['Lorem', 'ipsum', 'dolor'],
|
||||||
|
token: window.user.id,
|
||||||
|
_csrf: window.csrfToken
|
||||||
|
})
|
||||||
|
.respond({
|
||||||
|
misspellings: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
suggestions: ['foobarbaz']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.timelord.tick(200)
|
||||||
|
this.$httpBackend.flush()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not hit the backend when all words are already in the cache', function() {
|
||||||
|
this.$httpBackend
|
||||||
|
.expect('POST', '/spelling/check', {
|
||||||
|
language: this.scope.spellCheckLanguage,
|
||||||
|
words: ['Lorem', 'ipsum', 'dolor'],
|
||||||
|
token: window.user.id,
|
||||||
|
_csrf: window.csrfToken
|
||||||
|
})
|
||||||
|
.respond({
|
||||||
|
misspellings: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
suggestions: ['foobarbaz']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.timelord.tick(200)
|
||||||
|
this.$httpBackend.flush()
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.timelord.tick(200)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('hits the backend only with non-cached words', function() {
|
||||||
|
this.$httpBackend
|
||||||
|
.expect('POST', '/spelling/check', {
|
||||||
|
language: this.scope.spellCheckLanguage,
|
||||||
|
words: ['Lorem', 'ipsum', 'dolor'],
|
||||||
|
token: window.user.id,
|
||||||
|
_csrf: window.csrfToken
|
||||||
|
})
|
||||||
|
.respond({
|
||||||
|
misspellings: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
suggestions: ['foobarbaz']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.timelord.tick(200)
|
||||||
|
this.$httpBackend.flush()
|
||||||
|
|
||||||
|
this.adapter.getLinesByRows.returns(['Lorem ipsum dolor sit amet'])
|
||||||
|
this.$httpBackend
|
||||||
|
.expect('POST', '/spelling/check', {
|
||||||
|
language: this.scope.spellCheckLanguage,
|
||||||
|
words: ['sit', 'amet'],
|
||||||
|
token: window.user.id,
|
||||||
|
_csrf: window.csrfToken
|
||||||
|
})
|
||||||
|
.respond({
|
||||||
|
misspellings: [
|
||||||
|
{
|
||||||
|
index: 0,
|
||||||
|
suggestions: ['bazbarfoo']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
this.spellCheckManager.init()
|
||||||
|
this.timelord.tick(200)
|
||||||
|
this.$httpBackend.flush()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
this.$httpBackend.verifyNoOutstandingRequest()
|
||||||
|
this.$httpBackend.verifyNoOutstandingExpectation()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
|
|
Loading…
Reference in a new issue