yui-pathogen-decoder
Advanced tools
Comparing version 0.1.2 to 0.1.3
122
index.js
@@ -0,1 +1,7 @@ | ||
/* | ||
* Copyright 2014 Yahoo! Inc. All rights reserved. | ||
* Licensed under the BSD License. | ||
* http://yuilibrary.com/license/ | ||
*/ | ||
var NAMESPACE = 'p'; | ||
@@ -20,20 +26,29 @@ var GROUP_DELIMITER = ';'; | ||
exports.simpleDecoderFactory = function (name) { | ||
return function (version, modules) { | ||
return { | ||
name: name, | ||
modules: modules.split(MODULE_DELIMITER), | ||
version: version | ||
}; | ||
var NOOP = function () {}; | ||
/** | ||
* Decoder for groups that don't require additional processing | ||
* @method simpleDecoder | ||
* @param {String} name Module group name | ||
* @param {String} version Module group version | ||
* @param {String[]} modules Module names | ||
* @return {Object} Decoded module group | ||
*/ | ||
function simpleDecoder (name, version, modules) { | ||
return { | ||
name: name, | ||
version: version, | ||
modules: modules.split(MODULE_DELIMITER) | ||
}; | ||
}; | ||
} | ||
/** | ||
* Decoder for the gallery module group. Exported for testing purposes. | ||
* Decoder for the gallery module group | ||
* @method galleryDecoder | ||
* @param {String} name Module group name | ||
* @param {String} version Gallery version (without `gallery-` prefix) | ||
* @param {String[]} modules Gallery module names (without `gallery-` prefix) | ||
* @return {Object} Decoded modules and version | ||
* @return {Object} Decoded module group | ||
*/ | ||
exports.galleryDecoder = function (version, modules) { | ||
function galleryDecoder (name, version, modules) { | ||
var len, | ||
@@ -53,12 +68,46 @@ i; | ||
name: 'gallery', | ||
modules: modules, | ||
version: version | ||
version: version, | ||
modules: modules | ||
}; | ||
}; | ||
} | ||
/** | ||
* Decoder for the hash module group | ||
* @method hashDecoder | ||
* @param {String} length Length of individual hash | ||
* @param {String} version Module group version | ||
* @param {String[]} hash Module list hash | ||
* @return {Object} Decoded module group | ||
*/ | ||
function hashDecoder (length, version, hash) { | ||
var modules = [], | ||
index = 0; | ||
if (length < 1) { | ||
return new Error('Hash length must be at least 1'); | ||
} | ||
if (hash.length % length) { | ||
return new Error('Module list hash has unexpected length'); | ||
} | ||
while (index < hash.length) { | ||
modules.push(hash.substr(index, length)); | ||
index += length; | ||
} | ||
return { | ||
name: 'hash', | ||
version: version, | ||
modules: modules | ||
}; | ||
} | ||
// Decoder lookup via group type. The hash decoder is not in here because its | ||
// group type is inferred when the type is an integer. | ||
var DECODER = { | ||
core: exports.simpleDecoderFactory('core'), | ||
root: exports.simpleDecoderFactory('root'), | ||
path: exports.simpleDecoderFactory('path'), | ||
gallery: exports.galleryDecoder | ||
core: simpleDecoder, | ||
root: simpleDecoder, | ||
path: simpleDecoder, | ||
gallery: galleryDecoder | ||
}; | ||
@@ -79,14 +128,14 @@ | ||
var parts = group.split(GROUP_SUB_DELIMITER), | ||
normalizedName, | ||
decoded, | ||
expandedName, | ||
decoder, | ||
name; | ||
// [ group name, group version, modules ] | ||
// [ group name, group version, module names ] | ||
if (parts.length === 3) { | ||
name = parts.shift(); | ||
name = parts[0]; | ||
groupNames.some(function (groupName) { | ||
// Support short group names (e.g., core => c, gallery => g) | ||
// Support short group names ('c' for 'core', etc) | ||
if (groupName.indexOf(name) === 0) { | ||
normalizedName = groupName; | ||
expandedName = groupName; | ||
return true; | ||
@@ -96,4 +145,10 @@ } | ||
if (normalizedName) { | ||
decoded = DECODER[normalizedName].apply(null, parts); | ||
if (expandedName) { | ||
// replace short name with expanded name ('g' => 'gallery') | ||
parts[0] = expandedName; | ||
decoder = DECODER[expandedName]; | ||
} else if (!isNaN(+name)) { | ||
// replace string with number equivalent ('5' => 5) | ||
parts[0] = +name; | ||
decoder = hashDecoder; | ||
} else { | ||
@@ -111,3 +166,4 @@ return new Error('Unrecognized module group ' + name); | ||
else if (parts.length === 2) { | ||
decoded = DECODER.root.apply(null, parts); | ||
parts.unshift('root'); | ||
decoder = DECODER.root; | ||
} | ||
@@ -120,10 +176,10 @@ // XXX: For backwards compatibility. Remove after everyone moves off of | ||
else if (parts.length === 1) { | ||
decoded = { | ||
name: 'path', | ||
version: '', | ||
modules: parts | ||
}; | ||
parts = ['path', '', parts[0]]; | ||
decoder = DECODER.path; | ||
} else { | ||
decoder = NOOP; | ||
} | ||
return decoded || new Error('Module group has unexpected format'); | ||
return decoder.apply(null, parts) || | ||
new Error('Module group has unexpected format'); | ||
}; | ||
@@ -130,0 +186,0 @@ |
{ | ||
"name": "yui-pathogen-decoder", | ||
"version": "0.1.2", | ||
"version": "0.1.3", | ||
"description": "Decodes pathogen-encoded combo urls generated by YUI Loader", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
112
test/test.js
@@ -14,4 +14,104 @@ var assert = require('assert'), | ||
describe('decode', function () { | ||
describe('decode()', function () { | ||
it('should decode hash modules', function () { | ||
strategy.decode({ | ||
path: '/1+nobi/shizu+abcde.debug.js', | ||
query: {} | ||
}, function (err, decoded) { | ||
var group = decoded.groups[0], | ||
modules = group.modules; | ||
assert.strictEqual(err, null, 'unexpected error'); | ||
assert.strictEqual(decoded.filter, 'debug', 'unexpected filter'); | ||
assert.strictEqual(decoded.type, 'js', 'unexpected type'); | ||
assert.strictEqual(decoded.groups.length, 1, 'unexpected number of groups'); | ||
assert.strictEqual(group.name, 'hash', 'unexpected group name'); | ||
assert.strictEqual(modules.length, 5, 'unexpected number of modules'); | ||
assert.strictEqual(group.version, 'nobi/shizu', 'unexpected version'); | ||
assert.strictEqual(modules[0], 'a', 'unexpected module name'); | ||
assert.strictEqual(modules[1], 'b', 'unexpected module name'); | ||
assert.strictEqual(modules[2], 'c', 'unexpected module name'); | ||
assert.strictEqual(modules[3], 'd', 'unexpected module name'); | ||
assert.strictEqual(modules[4], 'e', 'unexpected module name'); | ||
}); | ||
strategy.decode({ | ||
path: '/3+nobi/dora+aaabbbcccdddeee.js', | ||
query: {} | ||
}, function (err, decoded) { | ||
var group = decoded.groups[0], | ||
modules = group.modules; | ||
assert.strictEqual(err, null, 'unexpected error'); | ||
assert.strictEqual(decoded.filter, 'min', 'unexpected filter'); | ||
assert.strictEqual(decoded.type, 'js', 'unexpected type'); | ||
assert.strictEqual(decoded.groups.length, 1, 'unexpected number of groups'); | ||
assert.strictEqual(group.name, 'hash', 'unexpected group name'); | ||
assert.strictEqual(modules.length, 5, 'unexpected number of modules'); | ||
assert.strictEqual(group.version, 'nobi/dora', 'unexpected version'); | ||
assert.strictEqual(modules[0], 'aaa', 'unexpected module name'); | ||
assert.strictEqual(modules[1], 'bbb', 'unexpected module name'); | ||
assert.strictEqual(modules[2], 'ccc', 'unexpected module name'); | ||
assert.strictEqual(modules[3], 'ddd', 'unexpected module name'); | ||
assert.strictEqual(modules[4], 'eee', 'unexpected module name'); | ||
}); | ||
strategy.decode({ | ||
path: '/4+nobi/dora+aaaabbbbccccddddeeee;2+nobi/shizu+xxyyzz.raw.js', | ||
query: {} | ||
}, function (err, decoded) { | ||
var groups = decoded.groups, | ||
modules, | ||
group; | ||
assert.strictEqual(err, null, 'unexpected error'); | ||
assert.strictEqual(decoded.filter, 'raw', 'unexpected filter'); | ||
assert.strictEqual(decoded.type, 'js', 'unexpected type'); | ||
assert.strictEqual(decoded.groups.length, 2, 'unexpected number of groups'); | ||
group = groups[0]; | ||
modules = group.modules; | ||
assert.strictEqual(group.name, 'hash', 'unexpected group name'); | ||
assert.strictEqual(modules.length, 5, 'unexpected number of modules'); | ||
assert.strictEqual(group.version, 'nobi/dora', 'unexpected version'); | ||
assert.strictEqual(modules[0], 'aaaa', 'unexpected module name'); | ||
assert.strictEqual(modules[1], 'bbbb', 'unexpected module name'); | ||
assert.strictEqual(modules[2], 'cccc', 'unexpected module name'); | ||
assert.strictEqual(modules[3], 'dddd', 'unexpected module name'); | ||
assert.strictEqual(modules[4], 'eeee', 'unexpected module name'); | ||
group = groups[1]; | ||
modules = group.modules; | ||
assert.strictEqual(group.name, 'hash', 'unexpected group name'); | ||
assert.strictEqual(modules.length, 3, 'unexpected number of modules'); | ||
assert.strictEqual(group.version, 'nobi/shizu', 'unexpected version'); | ||
assert.strictEqual(modules[0], 'xx', 'unexpected module name'); | ||
assert.strictEqual(modules[1], 'yy', 'unexpected module name'); | ||
assert.strictEqual(modules[2], 'zz', 'unexpected module name'); | ||
}); | ||
strategy.decode({ | ||
path: '/0+nobi/dora+aaabbbcccdddeee.js', | ||
query: {} | ||
}, function (err, decoded) { | ||
assert(err instanceof Error, 'expected an error'); | ||
assert.strictEqual(decoded, undefined, 'unexpected decoded object'); | ||
}); | ||
strategy.decode({ | ||
path: '/-2+nobi/dora+aaabbbcccdddeee.js', | ||
query: {} | ||
}, function (err, decoded) { | ||
assert(err instanceof Error, 'expected an error'); | ||
assert.strictEqual(decoded, undefined, 'unexpected decoded object'); | ||
}); | ||
}); | ||
it('should decode core modules', function () { | ||
@@ -250,13 +350,7 @@ strategy.decode({ | ||
it('should fail when too many or too few group components', function () { | ||
it('should fail when too many group components', function () { | ||
strategy.decode({ | ||
path: '/core', | ||
path: '/core+gallery+3.12.0+yui.js', | ||
query: {} | ||
}, function (err) { | ||
assert(err instanceof Error, 'should fail when too few'); | ||
}); | ||
strategy.decode({ | ||
path: '/core+gallery+core+3.12.0+yui', | ||
query: {} | ||
}, function (err) { | ||
assert(err instanceof Error, 'should fail when too many'); | ||
@@ -263,0 +357,0 @@ }); |
26630
7
518