Skip to content

Commit

Permalink
Add relative module/plugin/resource id support to cram builder plugin.
Browse files Browse the repository at this point in the history
…Fix #142
  • Loading branch information
briancavalier committed Nov 21, 2013
1 parent d5bc6cf commit 13f39ab
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 70 deletions.
149 changes: 79 additions & 70 deletions builder/cram.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
(function(define) {
define(function(require) {

var when, unfold, defaultModuleRegex, defaultSpecRegex, replaceIdsRegex,
var when, unfold, mid, defaultModuleRegex, defaultSpecRegex, replaceIdsRegex,
removeCommentsRx, splitSpecsRegex;

when = require('when');
unfold = require('when/unfold');
mid = require('../lib/loader/moduleId');

// default dependency regex
defaultModuleRegex = /\.(module|create)$/;
Expand Down Expand Up @@ -70,102 +71,110 @@ define(function(require) {
dependencies = [];
ids = [specId];

addDep(wireId);
_addDep(wireId);

return unfold(fetchNextSpec, endOfList, scanSpec, ids)
.then(function() {
return generateDefine(specId, dependencies);
}
);


function fetchNextSpec() {
var id, dfd;

id = ids.shift();
dfd = when.defer();

require(
[id],
function(spec) { dfd.resolve([spec, ids]); },
dfd.reject
);
var id = ids.shift();
return when.promise(function(resolve, reject) {
require(
[id],
function(spec) { resolve([{ spec: spec, id: id }, ids]); },
reject
);
});
}

return dfd.promise;
function _addDep(moduleId) {
if(!(moduleId in seenModules)) {
dependencies.push(moduleId);
seenModules[moduleId] = moduleId;
}
}

function scanSpec(spec) {
function scanSpec(specDescriptor) {
var spec = specDescriptor.spec;

scanPlugins(spec);
scanObj(spec);
}

function scanObj(obj, path) {
// Scan all keys. This might be the spec itself, or any sub-object-literal
// in the spec.
for (var name in obj) {
scanItem(obj[name], createPath(path, name));
function resolveId(moduleId) {
return mid.resolve(specDescriptor.id, moduleId)
}
}

function scanItem(it, path) {
// Determine the kind of thing we're looking at
// 1. If it's a string, and the key is module or create, then assume it
// is a moduleId, and add it as a dependency.
// 2. If it's an object or an array, scan it recursively
// 3. If it's a wire spec, add it to the list of spec ids
if (isSpec(path) && typeof it === 'string') {
addSpec(it);

} else if (isDep(path) && typeof it === 'string') {
// Get module def
addDep(it);

} else if (isStrictlyObject(it)) {
// Descend into subscope
scanObj(it, path);

} else if (Array.isArray(it)) {
// Descend into array
var arrayPath = path + '[]';
it.forEach(function(arrayItem) {
scanItem(arrayItem, arrayPath);
});
function scanObj(obj, path) {
// Scan all keys. This might be the spec itself,
// or any sub-object-literal in the spec.
for (var name in obj) {
scanItem(obj[name], createPath(path, name));
}
}

function scanItem(it, path) {
// Determine the kind of thing we're looking at
// 1. If it's a string, and the key is module or create, then assume it
// is a moduleId, and add it as a dependency.
// 2. If it's an object or an array, scan it recursively
// 3. If it's a wire spec, add it to the list of spec ids
if (isSpec(path) && typeof it === 'string') {
addSpec(it);

} else if (isDep(path) && typeof it === 'string') {
// Get module def
addDep(it);

} else if (isStrictlyObject(it)) {
// Descend into subscope
scanObj(it, path);

} else if (Array.isArray(it)) {
// Descend into array
var arrayPath = path + '[]';
it.forEach(function(arrayItem) {
scanItem(arrayItem, arrayPath);
});
}
}
}

function scanPlugins(spec) {
var plugins = spec.$plugins || spec.plugins;
function scanPlugins(spec) {
var plugins = spec.$plugins || spec.plugins;

if(Array.isArray(plugins)) {
plugins.forEach(addPlugin);
} else if(typeof plugins === 'object') {
Object.keys(plugins).forEach(function(key) {
addPlugin(plugins[key]);
});
if(Array.isArray(plugins)) {
plugins.forEach(addPlugin);
} else if(typeof plugins === 'object') {
Object.keys(plugins).forEach(function(key) {
addPlugin(plugins[key]);
});
}
}
}

function addPlugin(plugin) {
if(typeof plugin === 'string') {
addDep(plugin);
} else if(typeof plugin === 'object' && plugin.module) {
addDep(plugin.module);
function addPlugin(plugin) {
if(typeof plugin === 'string') {
addDep(plugin);
} else if(typeof plugin === 'object' && plugin.module) {
addDep(plugin.module);
}
}
}

function addDep(moduleId) {
if(!(moduleId in seenModules)) {
dependencies.push(moduleId);
seenModules[moduleId] = moduleId;
function addDep(moduleId) {
_addDep(resolveId(moduleId));
}
}

function addSpec(specId) {
if(!(specId in seenModules)) {
ids.push(specId);
function addSpec(specId) {
specId = resolveId(specId);
if(!(specId in seenModules)) {
ids.push(specId);
}
_addDep(specId);
}
addDep(specId);

}

}

function generateDefine(specId, dependencies) {
Expand Down
58 changes: 58 additions & 0 deletions test/node/builder/cram-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,64 @@ buster.testCase('wire/builder/cram', {
});
},

'should resolve relative module ids': function(done) {
var spec, json, specId;

specId = 'test';

spec = {
a: { module: './a' }
};

json = JSON.stringify(spec);

function req(ids, cb) {
cb(spec);
}

builder.compile('wire', specId, req, {
read: function(_, cb) {
cb(specObjectToModule(spec));
},
write: function(content) {
refute.equals(content.indexOf('["wire", "test/a"]'), -1);
done();
},
error: function (reason) {
refute(true, reason);
}
});
},

'should resolve relative plugin and resource ids': function(done) {
var spec, json, specId;

specId = 'test';

spec = {
a: { module: './plugin!./a' }
};

json = JSON.stringify(spec);

function req(ids, cb) {
cb(spec);
}

builder.compile('wire', specId, req, {
read: function(_, cb) {
cb(specObjectToModule(spec));
},
write: function(content) {
refute.equals(content.indexOf('["wire", "test/plugin!test/a"]'), -1);
done();
},
error: function (reason) {
refute(true, reason);
}
});
},

'with a comma-separated list of specs': {
'should generate a define for each': function(done) {
var specs = {
Expand Down

0 comments on commit 13f39ab

Please sign in to comment.