mirror of
https://github.com/bower/bower.git
synced 2026-01-14 00:38:03 -05:00
1248 lines
43 KiB
JavaScript
1248 lines
43 KiB
JavaScript
var path = require('path');
|
|
var mout = require('mout');
|
|
var rimraf = require('../../lib/util/rimraf');
|
|
var fs = require('../../lib/util/fs');
|
|
var Q = require('q');
|
|
var expect = require('expect.js');
|
|
var mkdirp = require('mkdirp');
|
|
var md5 = require('md5-hex');
|
|
var ResolveCache = require('../../lib/core/ResolveCache');
|
|
var defaultConfig = require('../../lib/config');
|
|
var cmd = require('../../lib/util/cmd');
|
|
var copy = require('../../lib/util/copy');
|
|
|
|
describe('ResolveCache', function() {
|
|
var resolveCache;
|
|
var testPackage = path.resolve(__dirname, '../assets/package-a');
|
|
var tempPackage = path.resolve(__dirname, '../tmp/temp-package');
|
|
var tempPackage2 = path.resolve(__dirname, '../tmp/temp2-package');
|
|
var cacheDir = path.join(__dirname, '../tmp/temp-resolve-cache');
|
|
|
|
before(function(next) {
|
|
// Delete cache folder
|
|
rimraf.sync(cacheDir);
|
|
|
|
// Instantiate resolver cache
|
|
resolveCache = new ResolveCache(
|
|
defaultConfig({
|
|
storage: {
|
|
packages: cacheDir
|
|
}
|
|
})
|
|
);
|
|
|
|
// Checkout test package version 0.2.0
|
|
cmd('git', ['checkout', '0.2.0'], { cwd: testPackage }).then(
|
|
next.bind(next, null),
|
|
next
|
|
);
|
|
});
|
|
|
|
beforeEach(function() {
|
|
// Reset in memory cache for each test
|
|
resolveCache.reset();
|
|
});
|
|
|
|
after(function() {
|
|
// Remove cache folder afterwards
|
|
rimraf.sync(cacheDir);
|
|
});
|
|
|
|
describe('.constructor', function() {
|
|
beforeEach(function() {
|
|
// Delete temp folder
|
|
rimraf.sync(tempPackage);
|
|
});
|
|
after(function() {
|
|
// Delete temp folder
|
|
rimraf.sync(tempPackage);
|
|
});
|
|
|
|
function initialize(cacheDir) {
|
|
return new ResolveCache(
|
|
defaultConfig({
|
|
storage: {
|
|
packages: cacheDir
|
|
}
|
|
})
|
|
);
|
|
}
|
|
|
|
it("should create the cache folder if it doesn't exists", function() {
|
|
initialize(tempPackage);
|
|
expect(fs.existsSync(tempPackage)).to.be(true);
|
|
});
|
|
|
|
it('should not error out if the cache folder already exists', function() {
|
|
mkdirp.sync(tempPackage);
|
|
initialize(tempPackage);
|
|
});
|
|
});
|
|
|
|
describe('.store', function() {
|
|
var oldFsRename = fs.rename;
|
|
|
|
beforeEach(function(next) {
|
|
// Restore oldFsRename
|
|
fs.rename = oldFsRename;
|
|
|
|
// Create a fresh copy of the test package into temp
|
|
rimraf.sync(tempPackage);
|
|
copy.copyDir(testPackage, tempPackage, { ignore: ['.git'] }).then(
|
|
next.bind(next, null),
|
|
next
|
|
);
|
|
});
|
|
|
|
it('should move the canonical dir to source-md5/version/ folder if package meta has a version', function(next) {
|
|
resolveCache
|
|
.store(tempPackage, {
|
|
name: 'foo',
|
|
version: '1.0.0',
|
|
_source: 'foo',
|
|
_target: '*'
|
|
})
|
|
.then(function(dir) {
|
|
expect(dir).to.equal(
|
|
path.join(cacheDir, md5('foo'), '1.0.0')
|
|
);
|
|
expect(fs.existsSync(dir)).to.be(true);
|
|
expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true);
|
|
expect(fs.existsSync(tempPackage)).to.be(false);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should move the canonical dir to source-md5/target/ folder if package meta has no version', function(next) {
|
|
resolveCache
|
|
.store(tempPackage, {
|
|
name: 'foo',
|
|
_source: 'foo',
|
|
_target: 'some-branch'
|
|
})
|
|
.then(function(dir) {
|
|
expect(dir).to.equal(
|
|
path.join(cacheDir, md5('foo'), 'some-branch')
|
|
);
|
|
expect(fs.existsSync(dir)).to.be(true);
|
|
expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true);
|
|
expect(fs.existsSync(tempPackage)).to.be(false);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should move the canonical dir to source-md5/_wildcard/ folder if package meta has no version and target is *', function(next) {
|
|
resolveCache
|
|
.store(tempPackage, {
|
|
name: 'foo',
|
|
_source: 'foo',
|
|
_target: '*'
|
|
})
|
|
.then(function(dir) {
|
|
expect(dir).to.equal(
|
|
path.join(cacheDir, md5('foo'), '_wildcard')
|
|
);
|
|
expect(fs.existsSync(dir)).to.be(true);
|
|
expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true);
|
|
expect(fs.existsSync(tempPackage)).to.be(false);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should read the package meta if not present', function(next) {
|
|
var pkgMeta = path.join(tempPackage, '.bower.json');
|
|
|
|
// Copy bower.json to .bower.json and add some props
|
|
copy.copyFile(path.join(tempPackage, 'component.json'), pkgMeta)
|
|
.then(function() {
|
|
return Q.nfcall(fs.readFile, pkgMeta).then(function(
|
|
contents
|
|
) {
|
|
var json = JSON.parse(contents.toString());
|
|
|
|
json._target = '~0.2.0';
|
|
json._source =
|
|
'git://github.com/bower/test-package.git';
|
|
|
|
return Q.nfcall(
|
|
fs.writeFile,
|
|
pkgMeta,
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
});
|
|
})
|
|
// Store as usual
|
|
.then(function() {
|
|
return resolveCache.store(tempPackage);
|
|
})
|
|
.then(function(dir) {
|
|
expect(dir).to.equal(
|
|
path.join(
|
|
cacheDir,
|
|
md5('git://github.com/bower/test-package.git'),
|
|
'0.2.0'
|
|
)
|
|
);
|
|
expect(fs.existsSync(dir)).to.be(true);
|
|
expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true);
|
|
expect(fs.existsSync(tempPackage)).to.be(false);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should error out when reading the package meta if the file does not exist', function(next) {
|
|
resolveCache
|
|
.store(tempPackage)
|
|
.then(
|
|
function() {
|
|
next(new Error('Should have failed'));
|
|
},
|
|
function(err) {
|
|
expect(err).to.be.an(Error);
|
|
expect(err.code).to.equal('ENOENT');
|
|
expect(err.message).to.contain(
|
|
path.join(tempPackage, '.bower.json')
|
|
);
|
|
|
|
next();
|
|
}
|
|
)
|
|
.done();
|
|
});
|
|
|
|
it('should error out when reading an invalid package meta', function(next) {
|
|
var pkgMeta = path.join(tempPackage, '.bower.json');
|
|
|
|
return Q.nfcall(fs.writeFile, pkgMeta, 'w00t')
|
|
.then(function() {
|
|
return resolveCache.store(tempPackage).then(
|
|
function() {
|
|
next(new Error('Should have failed'));
|
|
},
|
|
function(err) {
|
|
expect(err).to.be.an(Error);
|
|
expect(err.code).to.equal('EMALFORMED');
|
|
expect(err.message).to.contain(
|
|
path.join(tempPackage, '.bower.json')
|
|
);
|
|
|
|
next();
|
|
}
|
|
);
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should move the canonical dir, even if it is in a different drive', function(next) {
|
|
var hittedMock = false;
|
|
|
|
fs.rename = function(src, dest, cb) {
|
|
hittedMock = true;
|
|
|
|
setTimeout(function() {
|
|
var err = new Error();
|
|
err.code = 'EXDEV';
|
|
cb(err);
|
|
}, 10);
|
|
};
|
|
|
|
resolveCache
|
|
.store(tempPackage, {
|
|
name: 'foo',
|
|
_source: 'foobar',
|
|
_target: 'some-branch'
|
|
})
|
|
.then(function(dir) {
|
|
// Ensure mock was called
|
|
expect(hittedMock).to.be(true);
|
|
|
|
expect(dir).to.equal(
|
|
path.join(cacheDir, md5('foobar'), 'some-branch')
|
|
);
|
|
expect(fs.existsSync(dir)).to.be(true);
|
|
expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true);
|
|
expect(fs.existsSync(tempPackage)).to.be(false);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should update the in-memory cache', function(next) {
|
|
// Feed the cache
|
|
resolveCache
|
|
.versions('test-in-memory')
|
|
// Copy temp package to temp package 2
|
|
.then(function() {
|
|
return copy.copyDir(tempPackage, tempPackage2, {
|
|
ignore: ['.git']
|
|
});
|
|
})
|
|
// Store the two packages
|
|
.then(function() {
|
|
return resolveCache.store(tempPackage, {
|
|
name: 'foo',
|
|
version: '1.0.0',
|
|
_source: 'test-in-memory',
|
|
_target: '*'
|
|
});
|
|
})
|
|
.then(function() {
|
|
return resolveCache.store(tempPackage2, {
|
|
name: 'foo',
|
|
version: '1.0.1',
|
|
_source: 'test-in-memory',
|
|
_target: '*'
|
|
});
|
|
})
|
|
// Cache should have been updated
|
|
.then(function() {
|
|
return resolveCache
|
|
.versions('test-in-memory')
|
|
.then(function(versions) {
|
|
expect(versions).to.eql(['1.0.1', '1.0.0']);
|
|
|
|
next();
|
|
});
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should url encode target when storing to the fs', function(next) {
|
|
resolveCache
|
|
.store(tempPackage, {
|
|
name: 'foo',
|
|
_source: 'foo',
|
|
_target: 'foo/bar'
|
|
})
|
|
.then(function(dir) {
|
|
expect(dir).to.equal(
|
|
path.join(cacheDir, md5('foo'), 'foo%2Fbar')
|
|
);
|
|
expect(fs.existsSync(dir)).to.be(true);
|
|
expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true);
|
|
expect(fs.existsSync(tempPackage)).to.be(false);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should be possible to store two package at same time', function(next) {
|
|
var store = resolveCache.store.bind(resolveCache, tempPackage, {
|
|
name: 'foo',
|
|
_source: 'foo',
|
|
_target: 'foo/bar'
|
|
});
|
|
var store2 = resolveCache.store.bind(resolveCache, tempPackage2, {
|
|
name: 'foo',
|
|
_source: 'foo',
|
|
_target: 'foo/bar'
|
|
});
|
|
|
|
Q.all([store(), store2()])
|
|
.then(function(dirs) {
|
|
var dir = dirs[0];
|
|
expect(dir).to.equal(
|
|
path.join(cacheDir, md5('foo'), 'foo%2Fbar')
|
|
);
|
|
expect(fs.existsSync(dir)).to.be(true);
|
|
expect(fs.existsSync(path.join(dir, 'baz'))).to.be(true);
|
|
expect(fs.existsSync(tempPackage)).to.be(false);
|
|
expect(fs.existsSync(tempPackage2)).to.be(false);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
});
|
|
|
|
describe('.versions', function() {
|
|
it('should resolve to an array', function(next) {
|
|
resolveCache
|
|
.versions(String(Math.random()))
|
|
.then(function(versions) {
|
|
expect(versions).to.be.an('array');
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should ignore non-semver folders of the source', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0'));
|
|
fs.mkdirSync(path.join(sourceDir, 'foo'));
|
|
|
|
resolveCache
|
|
.versions(source)
|
|
.then(function(versions) {
|
|
expect(versions).to.not.contain('foo');
|
|
expect(versions).to.contain('0.0.1');
|
|
expect(versions).to.contain('0.1.0');
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should order the versions', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0'));
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0-rc.1'));
|
|
|
|
resolveCache
|
|
.versions(source)
|
|
.then(function(versions) {
|
|
expect(versions).to.eql(['0.1.0', '0.1.0-rc.1', '0.0.1']);
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should cache versions to speed-up subsequent calls', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
|
|
resolveCache
|
|
.versions(source)
|
|
.then(function() {
|
|
// Remove folder
|
|
rimraf.sync(sourceDir);
|
|
|
|
return resolveCache.versions(source);
|
|
})
|
|
.then(function(versions) {
|
|
expect(versions).to.eql(['0.0.1']);
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
});
|
|
|
|
describe('.retrieve', function() {
|
|
it('should resolve to empty if there are no packages for the requested source', function(next) {
|
|
resolveCache
|
|
.retrieve(String(Math.random()))
|
|
.spread(function() {
|
|
expect(arguments.length).to.equal(0);
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should resolve to empty if there are no suitable packages for the requested target', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0'));
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.9'));
|
|
fs.mkdirSync(path.join(sourceDir, '0.2.0'));
|
|
|
|
resolveCache
|
|
.retrieve(source, '~0.3.0')
|
|
.spread(function() {
|
|
expect(arguments.length).to.equal(0);
|
|
|
|
return resolveCache.retrieve(source, 'some-branch');
|
|
})
|
|
.spread(function() {
|
|
expect(arguments.length).to.equal(0);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should remove invalid packages from the cache if their package meta is missing or invalid', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0'));
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.9'));
|
|
fs.mkdirSync(path.join(sourceDir, '0.2.0'));
|
|
|
|
// Create an invalid package meta
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.2.0', '.bower.json'),
|
|
'w00t'
|
|
);
|
|
|
|
resolveCache
|
|
.retrieve(source, '~0.1.0')
|
|
.spread(function() {
|
|
var dirs = fs.readdirSync(sourceDir);
|
|
|
|
expect(arguments.length).to.equal(0);
|
|
expect(dirs).to.contain('0.0.1');
|
|
expect(dirs).to.contain('0.2.0');
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should resolve to the highest package that matches a range target, ignoring pre-releases', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
var json = { name: 'foo' };
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
|
|
json.version = '0.0.1';
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.0.1', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
json.version = '0.1.0';
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.1.0', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
json.version = '0.1.0-rc.1';
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0-rc.1'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.1.0-rc.1', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
json.version = '0.1.9';
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.9'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.1.9', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
json.version = '0.2.0';
|
|
fs.mkdirSync(path.join(sourceDir, '0.2.0'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.2.0', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
resolveCache
|
|
.retrieve(source, '~0.1.0')
|
|
.spread(function(canonicalDir, pkgMeta) {
|
|
expect(pkgMeta).to.be.an('object');
|
|
expect(pkgMeta.version).to.equal('0.1.9');
|
|
expect(canonicalDir).to.equal(
|
|
path.join(sourceDir, '0.1.9')
|
|
);
|
|
|
|
return resolveCache.retrieve(source, '*');
|
|
})
|
|
.spread(function(canonicalDir, pkgMeta) {
|
|
expect(pkgMeta).to.be.an('object');
|
|
expect(pkgMeta.version).to.equal('0.2.0');
|
|
expect(canonicalDir).to.equal(
|
|
path.join(sourceDir, '0.2.0')
|
|
);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should resolve to the highest package that matches a range target, not ignoring pre-releases if they are the only versions', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
var json = { name: 'foo' };
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
|
|
json.version = '0.1.0-rc.1';
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0-rc.1'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.1.0-rc.1', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
json.version = '0.1.0-rc.2';
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0-rc.2'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.1.0-rc.2', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
resolveCache
|
|
.retrieve(source, '~0.1.0')
|
|
.spread(function(canonicalDir, pkgMeta) {
|
|
expect(pkgMeta).to.be.an('object');
|
|
expect(pkgMeta.version).to.equal('0.1.0-rc.2');
|
|
expect(canonicalDir).to.equal(
|
|
path.join(sourceDir, '0.1.0-rc.2')
|
|
);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should resolve to exact match (including build metadata) if available', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
var json = { name: 'foo' };
|
|
var encoded;
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
|
|
json.version = '0.1.0';
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.1.0', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
json.version = '0.1.0+build.4';
|
|
encoded = encodeURIComponent('0.1.0+build.4');
|
|
fs.mkdirSync(path.join(sourceDir, encoded));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, encoded, '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
json.version = '0.1.0+build.5';
|
|
encoded = encodeURIComponent('0.1.0+build.5');
|
|
fs.mkdirSync(path.join(sourceDir, encoded));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, encoded, '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
json.version = '0.1.0+build.6';
|
|
encoded = encodeURIComponent('0.1.0+build.6');
|
|
fs.mkdirSync(path.join(sourceDir, encoded));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, encoded, '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
resolveCache
|
|
.retrieve(source, '0.1.0+build.5')
|
|
.spread(function(canonicalDir, pkgMeta) {
|
|
expect(pkgMeta).to.be.an('object');
|
|
expect(pkgMeta.version).to.equal('0.1.0+build.5');
|
|
expect(canonicalDir).to.equal(
|
|
path.join(
|
|
sourceDir,
|
|
encodeURIComponent('0.1.0+build.5')
|
|
)
|
|
);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should resolve to the _wildcard package if target is * and there are no semver versions', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
var json = { name: 'foo' };
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
|
|
fs.mkdirSync(path.join(sourceDir, '_wildcard'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '_wildcard', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
resolveCache
|
|
.retrieve(source, '*')
|
|
.spread(function(canonicalDir, pkgMeta) {
|
|
expect(pkgMeta).to.be.an('object');
|
|
expect(canonicalDir).to.equal(
|
|
path.join(sourceDir, '_wildcard')
|
|
);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it("should resolve to the exact target it's not a semver range", function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
var json = { name: 'foo' };
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
|
|
fs.mkdirSync(path.join(sourceDir, 'some-branch'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, 'some-branch', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
fs.mkdirSync(path.join(sourceDir, 'other-branch'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, 'other-branch', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
resolveCache
|
|
.retrieve(source, 'some-branch')
|
|
.spread(function(canonicalDir, pkgMeta) {
|
|
expect(pkgMeta).to.be.an('object');
|
|
expect(pkgMeta).to.not.have.property('version');
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
});
|
|
|
|
describe('.eliminate', function() {
|
|
beforeEach(function() {
|
|
mkdirp.sync(cacheDir);
|
|
});
|
|
|
|
it('should delete the source-md5/version folder', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0'));
|
|
|
|
resolveCache
|
|
.eliminate({
|
|
name: 'foo',
|
|
version: '0.0.1',
|
|
_source: source,
|
|
_target: '*'
|
|
})
|
|
.then(function() {
|
|
expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be(
|
|
false
|
|
);
|
|
expect(fs.existsSync(path.join(sourceDir, '0.1.0'))).to.be(
|
|
true
|
|
);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should delete the source-md5/target folder', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
fs.mkdirSync(path.join(sourceDir, 'some-branch'));
|
|
|
|
resolveCache
|
|
.eliminate({
|
|
name: 'foo',
|
|
_source: source,
|
|
_target: 'some-branch'
|
|
})
|
|
.then(function() {
|
|
expect(
|
|
fs.existsSync(path.join(sourceDir, 'some-branch'))
|
|
).to.be(false);
|
|
expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be(
|
|
true
|
|
);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should delete the source-md5/_wildcard folder', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
fs.mkdirSync(path.join(sourceDir, '_wildcard'));
|
|
|
|
resolveCache
|
|
.eliminate({
|
|
name: 'foo',
|
|
_source: source,
|
|
_target: '*'
|
|
})
|
|
.then(function() {
|
|
expect(
|
|
fs.existsSync(path.join(sourceDir, '_wildcard'))
|
|
).to.be(false);
|
|
expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be(
|
|
true
|
|
);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should delete the source-md5 folder if empty', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
|
|
resolveCache
|
|
.eliminate({
|
|
name: 'foo',
|
|
version: '0.0.1',
|
|
_source: source,
|
|
_target: '*'
|
|
})
|
|
.then(function() {
|
|
expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be(
|
|
false
|
|
);
|
|
expect(fs.existsSync(path.join(sourceDir))).to.be(false);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should remove entry from in memory cache if the source-md5 folder was deleted', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
|
|
// Feed up the cache
|
|
resolveCache
|
|
.versions(source)
|
|
// Eliminate
|
|
.then(function() {
|
|
return resolveCache.eliminate({
|
|
name: 'foo',
|
|
version: '0.0.1',
|
|
_source: source,
|
|
_target: '*'
|
|
});
|
|
})
|
|
.then(function() {
|
|
// At this point the parent folder should be deleted
|
|
// To test against the in-memory cache, we create a folder
|
|
// manually and request the versions
|
|
mkdirp.sync(path.join(sourceDir, '0.0.2'));
|
|
|
|
resolveCache.versions(source).then(function(versions) {
|
|
expect(versions).to.eql(['0.0.2']);
|
|
|
|
next();
|
|
});
|
|
})
|
|
.done();
|
|
});
|
|
});
|
|
|
|
describe('.clear', function() {
|
|
beforeEach(function() {
|
|
mkdirp.sync(cacheDir);
|
|
});
|
|
|
|
it('should empty the whole cache folder', function(next) {
|
|
resolveCache
|
|
.clear()
|
|
.then(function() {
|
|
var files;
|
|
|
|
expect(fs.existsSync(cacheDir)).to.be(true);
|
|
|
|
files = fs.readdirSync(cacheDir);
|
|
expect(files.length).to.be(0);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should erase the in-memory cache', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
|
|
// Feed the in-memory cache
|
|
resolveCache
|
|
.versions(source)
|
|
// Clear
|
|
.then(function() {
|
|
return resolveCache.clear();
|
|
})
|
|
.then(function() {
|
|
// To test against the in-memory cache, we create a folder
|
|
// manually and request the versions
|
|
mkdirp.sync(path.join(sourceDir, '0.0.2'));
|
|
|
|
resolveCache.versions(source).then(function(versions) {
|
|
expect(versions).to.eql(['0.0.2']);
|
|
|
|
next();
|
|
});
|
|
})
|
|
.done();
|
|
});
|
|
});
|
|
|
|
describe('.reset', function() {
|
|
it('should erase the in-memory cache', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
|
|
// Feed the in-memory cache
|
|
resolveCache
|
|
.versions(source)
|
|
.then(function() {
|
|
// Delete 0.0.1 and create 0.0.2
|
|
fs.rmdirSync(path.join(sourceDir, '0.0.1'));
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.2'));
|
|
|
|
// Reset cache
|
|
resolveCache.reset();
|
|
|
|
// Get versions
|
|
return resolveCache.versions(source);
|
|
})
|
|
.then(function(versions) {
|
|
expect(versions).to.eql(['0.0.2']);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
});
|
|
|
|
describe('.list', function() {
|
|
beforeEach(function() {
|
|
rimraf.sync(cacheDir);
|
|
mkdirp.sync(cacheDir);
|
|
});
|
|
|
|
it('should resolve to an empty array if the cache is empty', function(next) {
|
|
resolveCache
|
|
.list()
|
|
.then(function(entries) {
|
|
expect(entries).to.be.an('array');
|
|
expect(entries.length).to.be(0);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should resolve to an ordered array of entries (name ASC, release ASC)', function(next) {
|
|
var source = 'list-package-1';
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
var source2 = 'list-package-2';
|
|
var sourceId2 = md5(source2);
|
|
var sourceDir2 = path.join(cacheDir, sourceId2);
|
|
|
|
var json = {
|
|
name: 'foo'
|
|
};
|
|
|
|
// Create some versions for different sources
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
json.version = '0.0.1';
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.0.1', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
fs.mkdirSync(path.join(sourceDir, '0.1.0'));
|
|
json.version = '0.1.0';
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.1.0', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
delete json.version;
|
|
|
|
fs.mkdirSync(path.join(sourceDir, 'foo'));
|
|
json._target = 'foo';
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, 'foo', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
fs.mkdirSync(path.join(sourceDir, 'bar'));
|
|
json._target = 'bar';
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, 'bar', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
fs.mkdirSync(path.join(sourceDir, 'aa'));
|
|
json._target = 'aa';
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, 'aa', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
delete json._target;
|
|
|
|
fs.mkdirSync(sourceDir2);
|
|
fs.mkdirSync(path.join(sourceDir2, '0.2.1'));
|
|
json.version = '0.2.1';
|
|
fs.writeFileSync(
|
|
path.join(sourceDir2, '0.2.1', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
fs.mkdirSync(path.join(sourceDir2, '0.2.0'));
|
|
json.name = 'abc';
|
|
json.version = '0.2.0';
|
|
fs.writeFileSync(
|
|
path.join(sourceDir2, '0.2.0', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
resolveCache
|
|
.list()
|
|
.then(function(entries) {
|
|
var expectedJson;
|
|
var bowerDir = path.join(__dirname, '../..');
|
|
|
|
expect(entries).to.be.an('array');
|
|
|
|
expectedJson = fs.readFileSync(
|
|
path.join(
|
|
__dirname,
|
|
'../assets/resolve-cache/list-json-1.json'
|
|
)
|
|
);
|
|
|
|
mout.object.forOwn(entries, function(entry) {
|
|
// Trim absolute bower path from json
|
|
entry.canonicalDir = entry.canonicalDir.substr(
|
|
bowerDir.length
|
|
);
|
|
// Convert windows \ paths to /
|
|
entry.canonicalDir = entry.canonicalDir.replace(
|
|
/\\/g,
|
|
'/'
|
|
);
|
|
});
|
|
|
|
expect(entries).to.eql(JSON.parse(expectedJson));
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should ignore lurking files where dirs are expected', function(next) {
|
|
var source = 'list-package-1';
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
var json = {
|
|
name: 'foo'
|
|
};
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
json.version = '0.0.1';
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.0.1', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
// Create lurking files
|
|
fs.writeFileSync(path.join(cacheDir, 'foo'), 'w00t');
|
|
fs.writeFileSync(path.join(cacheDir, '.DS_Store'), '');
|
|
fs.writeFileSync(path.join(sourceDir, 'foo'), 'w00t');
|
|
fs.writeFileSync(path.join(sourceDir, '.DS_Store'), '');
|
|
|
|
// It should not error out
|
|
resolveCache
|
|
.list()
|
|
.then(function(entries) {
|
|
expect(entries).to.be.an('array');
|
|
expect(entries.length).to.be(1);
|
|
expect(entries[0].pkgMeta).to.eql(json);
|
|
|
|
// Lurking file should have been removed
|
|
expect(fs.existsSync(path.join(cacheDir, 'foo'))).to.be(
|
|
false
|
|
);
|
|
expect(
|
|
fs.existsSync(path.join(cacheDir, '.DS_Store'))
|
|
).to.be(false);
|
|
expect(fs.existsSync(path.join(sourceDir, 'foo'))).to.be(
|
|
false
|
|
);
|
|
expect(
|
|
fs.existsSync(path.join(sourceDir, '.DS_Store'))
|
|
).to.be(false);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
|
|
it('should delete entries if failed to read package meta', function(next) {
|
|
var source = 'list-package-1';
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
var json = {
|
|
name: 'foo'
|
|
};
|
|
|
|
// Create invalid versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.2'));
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.0.2', '.bower.json'),
|
|
'w00t'
|
|
);
|
|
|
|
// Create valid version
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.3'));
|
|
json.version = '0.0.3';
|
|
fs.writeFileSync(
|
|
path.join(sourceDir, '0.0.3', '.bower.json'),
|
|
JSON.stringify(json, null, ' ')
|
|
);
|
|
|
|
// It should not error out
|
|
resolveCache
|
|
.list()
|
|
.then(function(entries) {
|
|
expect(entries).to.be.an('array');
|
|
expect(entries.length).to.be(1);
|
|
expect(entries[0].pkgMeta).to.eql(json);
|
|
|
|
// Packages with invalid metas should have been removed
|
|
expect(fs.existsSync(path.join(sourceDir, '0.0.1'))).to.be(
|
|
false
|
|
);
|
|
expect(fs.existsSync(path.join(sourceDir, '0.0.2'))).to.be(
|
|
false
|
|
);
|
|
|
|
next();
|
|
})
|
|
.done();
|
|
});
|
|
});
|
|
|
|
describe('#clearRuntimeCache', function() {
|
|
it('should clear the in-memory cache for all sources', function(next) {
|
|
var source = String(Math.random());
|
|
var sourceId = md5(source);
|
|
var sourceDir = path.join(cacheDir, sourceId);
|
|
|
|
var source2 = String(Math.random());
|
|
var sourceId2 = md5(source2);
|
|
var sourceDir2 = path.join(cacheDir, sourceId2);
|
|
|
|
// Create some versions
|
|
fs.mkdirSync(sourceDir);
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.1'));
|
|
fs.mkdirSync(sourceDir2);
|
|
fs.mkdirSync(path.join(sourceDir2, '0.0.2'));
|
|
|
|
// Feed the cache
|
|
resolveCache
|
|
.versions(source)
|
|
.then(function() {
|
|
return resolveCache.versions(source2);
|
|
})
|
|
.then(function() {
|
|
// Create some more
|
|
fs.mkdirSync(path.join(sourceDir, '0.0.3'));
|
|
fs.mkdirSync(path.join(sourceDir2, '0.0.4'));
|
|
|
|
// Reset cache
|
|
ResolveCache.clearRuntimeCache();
|
|
})
|
|
.then(function() {
|
|
return resolveCache
|
|
.versions(source)
|
|
.then(function(versions) {
|
|
expect(versions).to.eql(['0.0.3', '0.0.1']);
|
|
|
|
return resolveCache.versions(source2);
|
|
})
|
|
.then(function(versions) {
|
|
expect(versions).to.eql(['0.0.4', '0.0.2']);
|
|
|
|
next();
|
|
});
|
|
})
|
|
.done();
|
|
});
|
|
});
|
|
});
|