ember-cli-ajh
Version:
Command line tool for developing ambitious ember.js apps
463 lines (353 loc) • 13.7 kB
JavaScript
;
var path = require('path');
var expect = require('chai').expect;
var assign = require('lodash/object/assign');
var Project = require('../../../lib/models/project');
var AddonDiscovery = require('../../../lib/models/addon-discovery');
var fixturePath = path.resolve(__dirname, '../../fixtures/addon');
var MockUI = require('../../helpers/mock-ui');
var chalk = require('chalk');
describe('models/addon-discovery.js', function() {
var project, projectPath, ui;
this.timeout(40000);
beforeEach(function() {
ui = new MockUI();
projectPath = path.resolve(fixturePath, 'simple');
var packageContents = require(path.join(projectPath, 'package.json'));
project = new Project(projectPath, packageContents, ui);
});
describe('dependencies', function() {
var mockPkg, deps, devDeps;
beforeEach(function() {
deps = {
'foo-bar': 'latest',
'blah-blah': '1.0.0'
};
devDeps = {
'dev-foo-bar': 'latest'
};
mockPkg = {
dependencies: deps,
devDependencies: devDeps
};
});
it('returns an object containing depenencies from the provided package.json', function() {
var expected = assign({}, deps, devDeps);
var discovery = new AddonDiscovery(ui);
expect(discovery.dependencies(mockPkg)).to.be.eql(expected);
});
it('excludes development dependencies if instructed', function() {
var expected = assign({}, deps);
var discovery = new AddonDiscovery(ui);
expect(discovery.dependencies(mockPkg, true)).to.be.eql(expected);
});
});
describe('discoverFromInternalProjectAddons', function() {
it('calls discoverAtPath for each path in project.supportedInternalAddonPaths', function() {
var actualPaths = [];
var project = {
supportedInternalAddonPaths: function() {
return [ 'lib/foo/', 'baz/qux/' ];
}
};
var discovery = new AddonDiscovery(ui);
discovery.discoverAtPath = function(path) {
actualPaths.push(path);
};
discovery.discoverFromInternalProjectAddons(project);
expect(actualPaths).to.be.eql(project.supportedInternalAddonPaths());
});
});
describe('discoverInRepoAddons', function() {
describe('returns empty array when ember-addon.paths is empty', function() {
var discovery, pkg;
beforeEach(function() {
discovery = new AddonDiscovery(ui);
});
it('returns empty array if `ember-addon` is not present in provided package', function() {
pkg = { };
var actual = discovery.discoverInRepoAddons(fixturePath, pkg);
expect(actual).to.be.eql([]);
});
it('returns empty array if `ember-addon.paths` is missing in provided package', function() {
pkg = {
'ember-addon': { }
};
var actual = discovery.discoverInRepoAddons(fixturePath, pkg);
expect(actual).to.be.eql([]);
});
it('returns empty array if `ember-addon.paths` is empty in provided package', function() {
pkg = {
'ember-addon': {
paths: []
}
};
var actual = discovery.discoverInRepoAddons(fixturePath, pkg);
expect(actual).to.be.eql([]);
});
});
it('calls discoverAtPath for each path in ember-addon.paths', function() {
var actualPaths = [];
var pkg = {
'ember-addon': {
paths: [ 'lib/foo', 'baz/qux' ]
}
};
var discovery = new AddonDiscovery(ui);
discovery.discoverAtPath = function(providedPath) {
actualPaths.push(providedPath);
return providedPath;
};
discovery.discoverInRepoAddons(fixturePath, pkg);
var expected = [
path.join(fixturePath, 'lib', 'foo'),
path.join(fixturePath, 'baz', 'qux')
];
expect(actualPaths).to.be.eql(expected);
});
it('falsey results from discoverAtPath are filtered out', function() {
var actualPaths = [];
var pkg = {
'ember-addon': {
paths: [ 'lib/foo', 'baz/qux' ]
}
};
var discovery = new AddonDiscovery(ui);
discovery.discoverAtPath = function(providedPath) {
actualPaths.push(providedPath);
return null;
};
var result = discovery.discoverInRepoAddons(fixturePath, pkg);
var expectedPaths = [
path.join(fixturePath, 'lib', 'foo'),
path.join(fixturePath, 'baz', 'qux')
];
expect(actualPaths).to.be.eql(expectedPaths);
expect(result).to.be.eql([]);
});
});
describe('discoverFromDependencies', function() {
var mockPkg, deps, devDeps;
beforeEach(function() {
deps = {
'foo-bar': 'latest',
'blah-blah': '1.0.0'
};
devDeps = {
'dev-foo-bar': 'latest'
};
mockPkg = {
dependencies: deps,
devDependencies: devDeps
};
});
it('can find a package without a main entry point [DEPRECATED]', function() {
var root = path.join(fixturePath, 'shared-package', 'base');
var addonNodeModulesPath = path.join(root, 'node_modules');
var actualPaths = [];
var discovery = new AddonDiscovery(ui);
deps['invalid-package'] = 'latest';
discovery.discoverAtPath = function(providedPath) {
actualPaths.push(providedPath);
return providedPath;
};
discovery.discoverFromDependencies(root, addonNodeModulesPath, mockPkg, true);
var expectedPaths = [
path.join(root, 'node_modules', 'foo-bar'),
path.join(root, 'node_modules', 'blah-blah'),
path.join(root, 'node_modules', 'invalid-package')
];
expect(actualPaths).to.be.eql(expectedPaths);
var output = ui.output.trim();
var expectedWarning = chalk.yellow('The package `invalid-package` is not a properly formatted package, we have used a fallback lookup to resolve it at `' + path.join(root, 'node_modules', 'invalid-package') + '`. This is generally caused by an addon not having a `main` entry point (or `index.js`).');
expect(output).to.equal(expectedWarning);
});
it('does not error when dependencies are not found', function() {
var root = path.join(fixturePath, 'shared-package', 'base');
var addonNodeModulesPath = path.join(root, 'node_modules');
var actualPaths = [];
var discovery = new AddonDiscovery(ui);
deps['blah-zorz'] = 'latest';
discovery.discoverAtPath = function(providedPath) {
actualPaths.push(providedPath);
return providedPath;
};
discovery.discoverFromDependencies(root, addonNodeModulesPath, mockPkg, true);
var expectedPaths = [
path.join(root, 'node_modules', 'foo-bar'),
path.join(root, 'node_modules', 'blah-blah'),
path.join(root, 'node_modules', 'blah-zorz')
];
expect(actualPaths).to.be.eql(expectedPaths);
});
it('calls discoverAtPath for each entry in dependencies', function() {
var root = path.join(fixturePath, 'shared-package', 'base');
var addonNodeModulesPath = path.join(root, 'node_modules');
var actualPaths = [];
var discovery = new AddonDiscovery(ui);
discovery.discoverAtPath = function(providedPath) {
actualPaths.push(providedPath);
return providedPath;
};
discovery.discoverFromDependencies(root, addonNodeModulesPath, mockPkg);
var expectedPaths = [
path.join(root, '..', 'node_modules', 'dev-foo-bar'),
path.join(root, 'node_modules', 'foo-bar'),
path.join(root, 'node_modules', 'blah-blah')
];
expect(actualPaths).to.be.eql(expectedPaths);
});
it('excludes devDeps if `excludeDevDeps` is true', function() {
var root = path.join(fixturePath, 'shared-package', 'base');
var addonNodeModulesPath = path.join(root, 'node_modules');
var actualPaths = [];
var discovery = new AddonDiscovery(ui);
discovery.discoverAtPath = function(providedPath) {
actualPaths.push(providedPath);
return providedPath;
};
discovery.discoverFromDependencies(root, addonNodeModulesPath, mockPkg, true);
var expectedPaths = [
path.join(root, 'node_modules', 'foo-bar'),
path.join(root, 'node_modules', 'blah-blah')
];
expect(actualPaths).to.be.eql(expectedPaths);
});
});
describe('discoverFromProjectItself', function() {
it('adds the project.root if it is an addon', function() {
var project = {
isEmberCLIAddon: function() {
return false;
}
};
var discovery = new AddonDiscovery(ui);
var actual = discovery.discoverFromProjectItself(project);
expect(actual).to.be.eql([]);
});
it('returns the root path if the project is an addon', function() {
var actualPaths = [];
var project = {
root: 'foo/bar/baz',
isEmberCLIAddon: function() {
return true;
}
};
var discovery = new AddonDiscovery(ui);
discovery.discoverAtPath = function(providedPath) {
actualPaths.push(providedPath);
return providedPath;
};
var actual = discovery.discoverFromProjectItself(project);
var expectedPaths = [ 'foo/bar/baz' ];
expect(actualPaths).to.be.eql(expectedPaths);
expect(actual).to.be.eql(expectedPaths);
});
});
describe('discoverChildAddons', function() {
var addon, discovery, discoverFromDependenciesCalled, discoverInRepoAddonsCalled;
beforeEach(function() {
addon = {
name: 'awesome-sauce',
root: fixturePath,
pkg: {
dependencies: {
'foo-bar': 'latest'
},
devDependencies: {
'dev-dep-bar': 'latest'
}
}
};
discovery = new AddonDiscovery(ui);
discovery.discoverFromDependencies = function() {
discoverFromDependenciesCalled = true;
return [];
};
discovery.discoverInRepoAddons = function() {
discoverInRepoAddonsCalled = true;
return [];
};
});
it('delegates to discoverInRepoAddons and discoverFromDependencies', function() {
discovery.discoverChildAddons(addon);
expect(discoverInRepoAddonsCalled).to.equal(true);
expect(discoverFromDependenciesCalled).to.equal(true);
});
it('concats discoverInRepoAddons and discoverFromDependencies results', function() {
discovery.discoverFromDependencies = function() {
return [ 'discoverFromDependencies' ];
};
discovery.discoverInRepoAddons = function() {
return [ 'discoverInRepoAddons' ];
};
var result = discovery.discoverChildAddons(addon);
expect(result).to.be.eql([ 'discoverFromDependencies', 'discoverInRepoAddons' ]);
});
});
describe('discoverProjectAddons', function() {
var addon, discovery, discoverFromProjectItselfCalled, discoverFromInternalProjectAddonsCalled, discoverFromDependenciesCalled, discoverInRepoAddonsCalled;
beforeEach(function() {
addon = {
name: 'awesome-sauce',
root: fixturePath,
pkg: {
dependencies: {
'foo-bar': 'latest'
},
devDependencies: {
'dev-dep-bar': 'latest'
}
},
hasDependencies: function() {
return true;
}
};
discovery = new AddonDiscovery(ui);
discovery.discoverFromProjectItself = function() {
discoverFromProjectItselfCalled = true;
return [ 'discoverFromProjectItself' ];
};
discovery.discoverFromInternalProjectAddons = function() {
discoverFromInternalProjectAddonsCalled = true;
return [ 'discoverFromInternalProjectAddons' ];
};
discovery.discoverFromDependencies = function() {
discoverFromDependenciesCalled = true;
return [ 'discoverFromDependencies' ];
};
discovery.discoverInRepoAddons = function() {
discoverInRepoAddonsCalled = true;
return [ 'discoverInRepoAddons' ];
};
});
it('delegates to internal methods', function() {
discovery.discoverProjectAddons(addon);
expect(discoverFromProjectItselfCalled).to.equal(true);
expect(discoverFromInternalProjectAddonsCalled).to.equal(true);
expect(discoverInRepoAddonsCalled).to.equal(true);
expect(discoverFromDependenciesCalled).to.equal(true);
});
it('concats discoverInRepoAddons and discoverFromDependencies results', function() {
var result = discovery.discoverProjectAddons(addon);
expect(result).to.be.eql([ 'discoverFromProjectItself', 'discoverFromInternalProjectAddons', 'discoverFromDependencies', 'discoverInRepoAddons' ]);
});
});
describe('discoverAtPath', function() {
it('returns an info object when addon is found', function() {
var addonPath = path.join(fixturePath, 'simple/node_modules/ember-random-addon');
var addonPkg = require(path.join(addonPath, 'package.json'));
var discovery = new AddonDiscovery(ui);
var result = discovery.discoverAtPath(addonPath);
expect(result.name).to.be.equal('ember-random-addon');
expect(result.path).to.be.equal(addonPath);
expect(result.pkg).to.be.eql(addonPkg);
});
it('returns `null` if path is not for an addon', function() {
var addonPath = path.join(fixturePath, 'simple');
var discovery = new AddonDiscovery(ui);
var result = discovery.discoverAtPath(addonPath);
expect(result).to.be.equal(null);
});
});
});