mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-29 10:51:35 +00:00
ee85d948e2
GitOrigin-RevId: ef2ef77e26df59d1af3df6dc664e284d3c70102d
202 lines
6.2 KiB
JavaScript
202 lines
6.2 KiB
JavaScript
'use strict'
|
|
|
|
const { expect } = require('chai')
|
|
const BPromise = require('bluebird')
|
|
const _ = require('lodash')
|
|
|
|
const ot = require('..')
|
|
const File = ot.File
|
|
const FileMap = ot.FileMap
|
|
|
|
describe('FileMap', function () {
|
|
function makeTestFile(pathname) {
|
|
return File.fromString(pathname)
|
|
}
|
|
|
|
function makeTestFiles(pathnames) {
|
|
return _.zipObject(pathnames, _.map(pathnames, makeTestFile))
|
|
}
|
|
|
|
function makeFileMap(pathnames) {
|
|
return new FileMap(makeTestFiles(pathnames))
|
|
}
|
|
|
|
it('allows construction with a single file', function () {
|
|
makeFileMap(['a'])
|
|
})
|
|
|
|
it('allows folders to differ by case', function () {
|
|
expect(() => {
|
|
makeFileMap(['a/b', 'A/c'])
|
|
}).not.to.throw
|
|
expect(() => {
|
|
makeFileMap(['a/b/c', 'A/b/d'])
|
|
}).not.to.throw
|
|
expect(() => {
|
|
makeFileMap(['a/b/c', 'a/B/d'])
|
|
}).not.to.throw
|
|
})
|
|
|
|
it('does not allow conflicting paths on construct', function () {
|
|
expect(() => {
|
|
makeFileMap(['a', 'a/b'])
|
|
}).to.throw(FileMap.PathnameConflictError)
|
|
})
|
|
|
|
it('detects conflicting paths with characters that sort before /', function () {
|
|
const fileMap = makeFileMap(['a', 'a!'])
|
|
expect(fileMap.wouldConflict('a/b')).to.be.truthy
|
|
})
|
|
|
|
it('detects conflicting paths', function () {
|
|
const fileMap = makeFileMap(['a/b/c'])
|
|
expect(fileMap.wouldConflict('a/b/c/d')).to.be.truthy
|
|
expect(fileMap.wouldConflict('a')).to.be.truthy
|
|
expect(fileMap.wouldConflict('b')).to.be.falsy
|
|
expect(fileMap.wouldConflict('a/b')).to.be.truthy
|
|
expect(fileMap.wouldConflict('a/c')).to.be.falsy
|
|
expect(fileMap.wouldConflict('a/b/c')).to.be.falsy
|
|
expect(fileMap.wouldConflict('a/b/d')).to.be.falsy
|
|
expect(fileMap.wouldConflict('d/b/c')).to.be.falsy
|
|
})
|
|
|
|
it('allows paths that differ by case', function () {
|
|
const fileMap = makeFileMap(['a/b/c'])
|
|
expect(fileMap.wouldConflict('a/b/C')).to.be.falsy
|
|
expect(fileMap.wouldConflict('A')).to.be.falsy
|
|
expect(fileMap.wouldConflict('A/b')).to.be.falsy
|
|
expect(fileMap.wouldConflict('a/B')).to.be.falsy
|
|
expect(fileMap.wouldConflict('A/B')).to.be.falsy
|
|
})
|
|
|
|
it('does not add a file with a conflicting path', function () {
|
|
const fileMap = makeFileMap(['a/b'])
|
|
const file = makeTestFile('a/b/c')
|
|
|
|
expect(() => {
|
|
fileMap.addFile('a/b/c', file)
|
|
}).to.throw(FileMap.PathnameConflictError)
|
|
})
|
|
|
|
it('does not move a file to a conflicting path', function () {
|
|
const fileMap = makeFileMap(['a/b', 'a/c'])
|
|
|
|
expect(() => {
|
|
fileMap.moveFile('a/b', 'a')
|
|
}).to.throw(FileMap.PathnameConflictError)
|
|
})
|
|
|
|
it('errors when trying to move a non-existent file', function () {
|
|
const fileMap = makeFileMap(['a'])
|
|
expect(() => fileMap.moveFile('b', 'a')).to.throw(FileMap.FileNotFoundError)
|
|
})
|
|
|
|
it('moves a file over an empty folder', function () {
|
|
const fileMap = makeFileMap(['a/b'])
|
|
fileMap.moveFile('a/b', 'a')
|
|
expect(fileMap.countFiles()).to.equal(1)
|
|
expect(fileMap.getFile('a')).to.exist
|
|
expect(fileMap.getFile('a').getContent()).to.equal('a/b')
|
|
})
|
|
|
|
it('does not move a file over a non-empty folder', function () {
|
|
const fileMap = makeFileMap(['a/b', 'a/c'])
|
|
expect(() => {
|
|
fileMap.moveFile('a/b', 'a')
|
|
}).to.throw(FileMap.PathnameConflictError)
|
|
})
|
|
|
|
it('does not overwrite filename that differs by case on add', function () {
|
|
const fileMap = makeFileMap(['a'])
|
|
fileMap.addFile('A', makeTestFile('A'))
|
|
expect(fileMap.countFiles()).to.equal(2)
|
|
expect(fileMap.files.a).to.exist
|
|
expect(fileMap.files.A).to.exist
|
|
expect(fileMap.getFile('a')).to.exist
|
|
expect(fileMap.getFile('A').getContent()).to.equal('A')
|
|
})
|
|
|
|
it('changes case on move', function () {
|
|
const fileMap = makeFileMap(['a'])
|
|
fileMap.moveFile('a', 'A')
|
|
expect(fileMap.countFiles()).to.equal(1)
|
|
expect(fileMap.files.a).not.to.exist
|
|
expect(fileMap.files.A).to.exist
|
|
expect(fileMap.getFile('A').getContent()).to.equal('a')
|
|
})
|
|
|
|
it('does not overwrite filename that differs by case on move', function () {
|
|
const fileMap = makeFileMap(['a', 'b'])
|
|
fileMap.moveFile('a', 'B')
|
|
expect(fileMap.countFiles()).to.equal(2)
|
|
expect(fileMap.files.a).not.to.exist
|
|
expect(fileMap.files.b).to.exist
|
|
expect(fileMap.files.B).to.exist
|
|
expect(fileMap.getFile('B').getContent()).to.equal('a')
|
|
})
|
|
|
|
it('does not find pathname that differs by case', function () {
|
|
const fileMap = makeFileMap(['a'])
|
|
expect(fileMap.getFile('a')).to.exist
|
|
expect(fileMap.getFile('A')).not.to.exist
|
|
expect(fileMap.getFile('b')).not.to.exist
|
|
})
|
|
|
|
it('does not allow non-safe pathnames', function () {
|
|
expect(() => {
|
|
makeFileMap(['c*'])
|
|
}).to.throw(FileMap.BadPathnameError)
|
|
|
|
const fileMap = makeFileMap([])
|
|
|
|
expect(() => {
|
|
fileMap.addFile('c*', makeTestFile('c:'))
|
|
}).to.throw(FileMap.BadPathnameError)
|
|
|
|
fileMap.addFile('a', makeTestFile('a'))
|
|
expect(() => {
|
|
fileMap.moveFile('a', 'c*')
|
|
}).to.throw(FileMap.BadPathnameError)
|
|
|
|
expect(() => {
|
|
fileMap.addFile('hasOwnProperty', makeTestFile('hasOwnProperty'))
|
|
fileMap.addFile('anotherFile', makeTestFile('anotherFile'))
|
|
}).to.throw()
|
|
})
|
|
|
|
it('removes a file', function () {
|
|
const fileMap = makeFileMap(['a', 'b'])
|
|
fileMap.removeFile('a')
|
|
expect(fileMap.countFiles()).to.equal(1)
|
|
expect(fileMap.files.a).not.to.exist
|
|
expect(fileMap.files.b).to.exist
|
|
})
|
|
|
|
it('errors when trying to remove a non-existent file', function () {
|
|
const fileMap = makeFileMap(['a'])
|
|
expect(() => fileMap.removeFile('b')).to.throw(FileMap.FileNotFoundError)
|
|
})
|
|
|
|
it('has mapAsync', function () {
|
|
const concurrency = 1
|
|
return BPromise.map(
|
|
[
|
|
[[], {}],
|
|
[['a'], { a: 'a-a' }], // the test is to map to "content-pathname"
|
|
[['a', 'b'], { a: 'a-a', b: 'b-b' }],
|
|
],
|
|
test => {
|
|
const input = test[0]
|
|
const expectedOutput = test[1]
|
|
const fileMap = makeFileMap(input)
|
|
return fileMap
|
|
.mapAsync((file, pathname) => {
|
|
return file.getContent() + '-' + pathname
|
|
}, concurrency)
|
|
.then(result => {
|
|
expect(result).to.deep.equal(expectedOutput)
|
|
})
|
|
}
|
|
)
|
|
})
|
|
})
|