| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- import sinon from 'sinon'
- import { fireEvent, waitFor } from '@testing-library/react'
- import { expect } from 'chai'
- import { EditorView } from '@codemirror/view'
- import { EditorState } from '@codemirror/state'
- import {
- restoreScrollPosition,
- scrollPosition,
- } from '../../../../../frontend/js/features/source-editor/extensions/scroll-position'
- const doc = `
- \\documentclass{article}
- \\title{Your Paper}
- \\author{You}
- \\begin{document}
- \\maketitle
- \\begin{abstract}
- Your abstract.
- \\end{abstract}
- \\section{Introduction}
- Your introduction goes here!
- \\end{document}`
- const mockDoc = () => {
- return {
- doc_id: 'test-doc',
- }
- }
- describe('CodeMirror scroll position extension', function () {
- beforeEach(function () {
- sinon.stub(HTMLElement.prototype, 'scrollHeight').returns(800)
- sinon.stub(HTMLElement.prototype, 'scrollWidth').returns(500)
- sinon.stub(HTMLElement.prototype, 'clientHeight').returns(200)
- sinon.stub(HTMLElement.prototype, 'clientWidth').returns(500)
- sinon
- .stub(HTMLElement.prototype, 'getBoundingClientRect')
- .returns({ top: 100, left: 0, right: 500, bottom: 200 } as DOMRect)
- // Range.getClientRects doesn't exist yet in jsdom
- window.Range.prototype.getClientRects = sinon.stub().returns([])
- })
- afterEach(function () {
- sinon.restore()
- // @ts-ignore
- delete window.Range.prototype.getClientRects
- })
- it('stores scroll position when the view is destroyed', async function () {
- const currentDoc = mockDoc()
- sinon.stub(window.Storage.prototype, 'getItem').callsFake(key => {
- switch (key) {
- case 'doc.position.test-doc':
- return JSON.stringify({
- cursorPosition: { row: 2, column: 2 },
- firstVisibleLine: 5,
- })
- default:
- return null
- }
- })
- const view = new EditorView({
- state: EditorState.create({
- doc,
- extensions: [scrollPosition({ currentDoc }, { visual: false })],
- }),
- })
- const setItem = sinon.spy(window.Storage.prototype, 'setItem')
- fireEvent.scroll(view.scrollDOM, { target: { scrollTop: 10 } })
- view.destroy()
- const expected = JSON.stringify({
- cursorPosition: { row: 2, column: 2 },
- firstVisibleLine: 12,
- })
- await waitFor(() => {
- expect(setItem).to.have.been.calledWith('doc.position.test-doc', expected)
- })
- })
- it('restores scroll position', async function () {
- const currentDoc = mockDoc()
- const getItem = sinon
- .stub(window.Storage.prototype, 'getItem')
- .callsFake(key => {
- switch (key) {
- case 'editor.position.test-doc':
- return JSON.stringify({ firstVisibleLine: 12 })
- default:
- return null
- }
- })
- const view = new EditorView({
- state: EditorState.create({
- doc,
- extensions: [scrollPosition({ currentDoc }, { visual: false })],
- }),
- })
- view.dispatch(restoreScrollPosition())
- await waitFor(() => {
- expect(getItem).to.have.been.calledWith('doc.position.test-doc')
- })
- // TODO: scrollTop should be a higher value but requires more mocking
- // await waitFor(() => {
- // expect(view.scrollDOM.scrollTop).to.eq(0)
- // })
- })
- })
|