sync-modules
Version:
automatically keep node_modules in sync with Git hooks
172 lines (137 loc) • 4.04 kB
JavaScript
var assert = require('assert')
var childProcess = require('child_process')
var fs = require('fs')
var path = require('path')
var tmp = require('tmp')
function createTemporaryDirectory () {
var directory
directory = tmp.dirSync()
return {
exec: function (command) {
return childProcess.execSync(command, {
cwd: directory.name,
encoding: 'utf8'
})
},
exists: function (file) {
try {
fs.lstatSync(path.resolve(directory.name, file))
} catch (exception) {
return false
}
return true
},
toString: function () {
return directory.name
}
}
}
describe('happy paths', function () {
var d
this.timeout(30 * 1000)
before(function () {
d = createTemporaryDirectory()
console.log(`Running tests in temporary directory ${d}.`)
d.exec(`
# Set up a sample project and install ourselves into it.
git init
npm init --yes
npm install --save ${__dirname}/..
git add package.json
git commit --message package.json
# Create a new branch called 'npm' that has the package 'npm' installed.
git checkout -b npm
npm install --save npm
git commit --all --message npm
# Create another branch named 'uninstalled' with the 'npm' package uninstalled.
git checkout -b uninstalled
npm uninstall --save npm
git commit --all --message uninstall
`)
})
beforeEach(function () {
d.exec('git checkout -B test master')
})
it('installs additional packages after a checkout', function () {
assert(!d.exists('node_modules/npm'))
d.exec('git checkout npm')
assert(d.exists('node_modules/npm'))
})
it('removes unused packages after a checkout', function () {
d.exec('git checkout npm')
assert(d.exists('node_modules/npm'))
d.exec('git checkout master')
assert(!d.exists('node_modules/npm'))
})
it('installs additional packages after a merge', function () {
assert(!d.exists('node_modules/npm'))
d.exec('git merge npm')
assert(d.exists('node_modules/npm'))
})
it('removes additional packages after a merge', function () {
d.exec('git checkout npm')
assert(d.exists('node_modules/npm'))
d.exec('git merge uninstalled')
assert(!d.exists('node_modules/npm'))
})
it("performs checkout quickly when package.json doesn't change",
function () {
var time
time = process.hrtime()
d.exec('git checkout uninstalled')
assert(process.hrtime(time)[1] < 5e8,
'"git checkout" should take less than half a second.')
})
it("performs merge quickly when package.json doesn't change",
function () {
var time
time = process.hrtime()
d.exec('git merge uninstalled')
assert(process.hrtime(time)[1] < 5e8,
'"git merge" should take less than half a second.')
})
})
describe('uninstallation', function () {
var d
before(function () {
d = createTemporaryDirectory()
console.log(`Running tests in temporary directory ${d}.`)
d.exec('git init')
})
beforeEach(function () {
d.exec(`
npm init --yes
npm install --save ${__dirname}/..
`)
})
it('removes Git hooks during uninstall', function () {
assert(d.exists('.git/hooks/post-checkout'))
assert(d.exists('.git/hooks/post-merge'))
d.exec('npm uninstall --save sync-modules')
assert(!d.exists('.git/hooks/post-checkout'))
assert(!d.exists('.git/hooks/post-merge'))
})
})
describe('sad paths', function () {
var d
beforeEach(function () {
d = createTemporaryDirectory()
console.log(`Running tests in temporary directory ${d}.`)
d.exec('git init')
})
it('refuses to install if there is already a post-checkout hook',
function () {
d.exec('touch .git/hooks/post-checkout')
assert.throws(function () {
d.exec('npm install --save ${__dirname}/..')
})
})
it('refuses to install if there is already a post-merge hook',
function () {
d.exec('touch .git/hooks/post-merge')
assert.throws(function () {
d.exec('npm install --save ${__dirname}/..')
})
})
})