Merge pull request #8921 from overleaf/em-draft-mode

Change draft mode implementation

GitOrigin-RevId: 3de81a3643cc024c410b7b49e77cd41c7fec8294
This commit is contained in:
Eric Mc Sween
2022-07-20 08:04:06 +00:00
committed by Copybot
parent 68b61bbcaf
commit c13383eb07
2 changed files with 42 additions and 122 deletions
+17 -56
View File
@@ -1,61 +1,22 @@
/* eslint-disable const fsPromises = require('fs/promises')
camelcase, const { callbackify } = require('util')
no-useless-escape,
*/
// 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
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
let DraftModeManager
const fs = require('fs')
const { promisify } = require('util')
const logger = require('@overleaf/logger') const logger = require('@overleaf/logger')
module.exports = DraftModeManager = { async function injectDraftMode(filename) {
injectDraftMode(filename, callback) { const content = await fsPromises.readFile(filename, { encoding: 'utf8' })
if (callback == null) { const modifiedContent = '\\PassOptionsToPackage{draft}{graphicx}' + content
callback = function () {} logger.debug(
} {
return fs.readFile(filename, 'utf8', function (error, content) { content: content.slice(0, 1024), // \documentclass is normally v near the top
if (error != null) { modifiedContent: modifiedContent.slice(0, 1024),
return callback(error) filename,
} },
// avoid adding draft mode more than once 'injected draft class'
if ( )
(content != null await fsPromises.writeFile(filename, modifiedContent, { encoding: 'utf8' })
? content.indexOf('\\documentclass[draft')
: undefined) >= 0
) {
return callback()
}
const modified_content = DraftModeManager._injectDraftOption(content)
logger.debug(
{
content: content.slice(0, 1024), // \documentclass is normally v near the top
modified_content: modified_content.slice(0, 1024),
filename,
},
'injected draft class'
)
return fs.writeFile(filename, modified_content, callback)
})
},
_injectDraftOption(content) {
return (
content
// With existing options (must be first, otherwise both are applied)
.replace(/\\documentclass\[/g, '\\documentclass[draft,')
// Without existing options
.replace(/\\documentclass\{/g, '\\documentclass[draft]{')
)
},
} }
module.exports.promises = { module.exports = {
injectDraftMode: promisify(DraftModeManager.injectDraftMode), injectDraftMode: callbackify(injectDraftMode),
promises: { injectDraftMode },
} }
@@ -1,84 +1,43 @@
/* eslint-disable const Path = require('path')
no-return-assign, const fsPromises = require('fs/promises')
*/ const { expect } = require('chai')
// TODO: This file was created by bulk-decaffeinate. const mockFs = require('mock-fs')
// 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
*/
const SandboxedModule = require('sandboxed-module') const SandboxedModule = require('sandboxed-module')
const sinon = require('sinon')
const modulePath = require('path').join( const MODULE_PATH = Path.join(__dirname, '../../../app/js/DraftModeManager')
__dirname,
'../../../app/js/DraftModeManager'
)
describe('DraftModeManager', function () { describe('DraftModeManager', function () {
beforeEach(function () { beforeEach(function () {
return (this.DraftModeManager = SandboxedModule.require(modulePath, { this.DraftModeManager = SandboxedModule.require(MODULE_PATH, {
requires: { requires: {
fs: (this.fs = {}), 'fs/promises': fsPromises,
}, },
}))
})
describe('_injectDraftOption', function () {
it('should add draft option into documentclass with existing options', function () {
return this.DraftModeManager._injectDraftOption(`\
\\documentclass[a4paper,foo=bar]{article}\
`).should.equal(`\
\\documentclass[draft,a4paper,foo=bar]{article}\
`)
}) })
this.filename = '/mock/filename.tex'
return it('should add draft option into documentclass with no options', function () { this.contents = `\
return this.DraftModeManager._injectDraftOption(`\
\\documentclass{article}\
`).should.equal(`\
\\documentclass[draft]{article}\
`)
})
})
return describe('injectDraftMode', function () {
beforeEach(function () {
this.filename = '/mock/filename.tex'
this.callback = sinon.stub()
const content = `\
\\documentclass{article} \\documentclass{article}
\\begin{document} \\begin{document}
Hello world Hello world
\\end{document}\ \\end{document}\
` `
this.fs.readFile = sinon.stub().callsArgWith(2, null, content) mockFs({
this.fs.writeFile = sinon.stub().callsArg(2) [this.filename]: this.contents,
return this.DraftModeManager.injectDraftMode(this.filename, this.callback)
}) })
})
it('should read the file', function () { afterEach(function () {
return this.fs.readFile mockFs.restore()
.calledWith(this.filename, 'utf8') })
.should.equal(true)
})
it('should write the modified file', function () { describe('injectDraftMode', function () {
return this.fs.writeFile it('prepends a special command to the beginning of the file', async function () {
.calledWith( await this.DraftModeManager.promises.injectDraftMode(this.filename)
this.filename, const contents = await fsPromises.readFile(this.filename, {
`\ encoding: 'utf8',
\\documentclass[draft]{article} })
\\begin{document} expect(contents).to.equal(
Hello world '\\PassOptionsToPackage{draft}{graphicx}' + this.contents
\\end{document}\ )
`
)
.should.equal(true)
})
return it('should call the callback', function () {
return this.callback.called.should.equal(true)
}) })
}) })
}) })