Add specs to cover ::relativizeToWorkingDirectory

Yay, this uncovered a problem with the implementation.
This commit is contained in:
Daniel Hengeveld
2016-01-12 15:32:59 -05:00
parent 04b4be16aa
commit a9f9cd5b8f
2 changed files with 76 additions and 9 deletions

View File

@@ -738,4 +738,52 @@ describe('GitRepositoryAsync', () => {
expect(newLines).toBe(1)
})
})
describe('GitRepositoryAsync::relativizeToWorkingDirectory(_path)', () => {
let workingDirectory
beforeEach(() => {
workingDirectory = copyRepository()
repo = GitRepositoryAsync.open(workingDirectory)
})
it('relativizes the given path to the working directory of the repository', async () => {
let absolutePath = path.join(workingDirectory, 'a.txt')
expect(await repo.relativizeToWorkingDirectory(absolutePath)).toBe('a.txt')
absolutePath = path.join(workingDirectory, 'a/b/c.txt')
expect(await repo.relativizeToWorkingDirectory(absolutePath)).toBe('a/b/c.txt')
expect(await repo.relativizeToWorkingDirectory('a.txt')).toBe('a.txt')
expect(await repo.relativizeToWorkingDirectory('/not/in/workdir')).toBe('/not/in/workdir')
expect(await repo.relativizeToWorkingDirectory(null)).toBe(null)
expect(await repo.relativizeToWorkingDirectory()).toBe(undefined)
expect(await repo.relativizeToWorkingDirectory('')).toBe('')
expect(await repo.relativizeToWorkingDirectory(workingDirectory)).toBe('')
})
describe('when the opened path is a symlink', () => {
it('relativizes against both the linked path and real path', async () => {
// Symlinks require admin privs on windows so we just skip this there,
// done in git-utils as well
if (process.platform === 'win32') {
return
}
console.log('workingDirectory in spec', workingDirectory);
const linkDirectory = path.join(temp.mkdirSync('atom-working-dir-symlink'), 'link')
fs.symlinkSync(workingDirectory, linkDirectory)
const linkedRepo = GitRepositoryAsync.open(linkDirectory)
expect(await linkedRepo.relativizeToWorkingDirectory(path.join(workingDirectory, 'test1'))).toBe('test1')
expect(await linkedRepo.relativizeToWorkingDirectory(path.join(linkDirectory, 'test2'))).toBe('test2')
expect(await linkedRepo.relativizeToWorkingDirectory(path.join(linkDirectory, 'test2/test3'))).toBe('test2/test3')
expect(await linkedRepo.relativizeToWorkingDirectory('test2/test3')).toBe('test2/test3')
})
it ('handles case insensitive filesystems', async () => {
repo.isCaseInsensitive = true
expect(await repo.relativizeToWorkingDirectory(path.join(workingDirectory.toUpperCase(), 'a.txt'))).toBe('a.txt')
expect(await repo.relativizeToWorkingDirectory(path.join(workingDirectory.toUpperCase(), 'a/b/c.txt'))).toBe('a/b/c.txt')
})
})
})
})

View File

@@ -163,10 +163,6 @@ export default class GitRepositoryAsync {
return this.getRepo()
.then((repo) => {
let workingDirectory = repo.workdir()
const opened = this.openedPath.replace(/\/\.git$/, '')
if (path.relative(opened, workingDirectory) !== '') {
workingDirectory = opened
}
return this.relativize(_path, workingDirectory)
}
)
@@ -182,14 +178,18 @@ export default class GitRepositoryAsync {
// The original implementation also handled null workingDirectory as it
// pulled it from a sync function that could return null. We require it
// to be passed here.
let openedWorkingDirectory
if (!_path || !workingDirectory) {
return _path
}
// Depending on where the paths come from, they may have a '/private/'
// prefix. Standardize by stripping that out.
_path = _path.replace(/^\/private\//, '/')
workingDirectory = workingDirectory.replace(/^\/private\//, '/')
// If the opened directory and the workdir differ, this is a symlinked repo
// root, so we have to do all the checks below twice--once against the realpath
// and one against the opened path
const opened = this.openedPath.replace(/\/\.git$/, '')
if (path.relative(opened, workingDirectory) !== '') {
openedWorkingDirectory = opened
}
if (process.platform === 'win32') {
_path = _path.replace(/\\/g, '/')
@@ -201,18 +201,37 @@ export default class GitRepositoryAsync {
workingDirectory = workingDirectory.replace(/\/$/, '')
const originalPath = _path
if (this.isCaseInsensitive) {
_path = _path.toLowerCase()
workingDirectory = workingDirectory.toLowerCase()
}
// Depending on where the paths come from, they may have a '/private/'
// prefix. Standardize by stripping that out.
_path = _path.replace(/^\/private\//, '/')
workingDirectory = workingDirectory.replace(/^\/private\//, '/')
const originalPath = _path
if (_path.indexOf(workingDirectory) === 0) {
return originalPath.substring(workingDirectory.length + 1)
} else if (_path === workingDirectory) {
return ''
}
if (openedWorkingDirectory) {
if (this.isCaseInsensitive) {
openedWorkingDirectory = openedWorkingDirectory.toLowerCase()
}
openedWorkingDirectory = openedWorkingDirectory.replace(/\/$/, '')
openedWorkingDirectory = openedWorkingDirectory.replace(/^\/private\//, '/')
if (_path.indexOf(openedWorkingDirectory) === 0) {
return originalPath.substring(openedWorkingDirectory.length + 1)
} else if (_path === openedWorkingDirectory) {
return ''
}
}
return _path
}