Comparing version 0.1.0 to 0.2.0
@@ -6,6 +6,6 @@ | ||
result = program | ||
.register('do', function(args) { | ||
.register('abcd', function(args) { | ||
console.log('just do', args) | ||
}) | ||
.register('do code', function(args) { | ||
.register('abcde code', function(args) { | ||
console.log('doing something', args) | ||
@@ -12,0 +12,0 @@ }) |
69
index.js
@@ -28,2 +28,3 @@ /* | ||
var minimist = require('minimist') | ||
, leven = require('leven') | ||
@@ -34,13 +35,20 @@ function commist() { | ||
function lookup(parts) { | ||
if (typeof parts === 'string') | ||
parts = parts.split(' ') | ||
function lookup(array) { | ||
if (typeof array === 'string') | ||
array = array.split(' ') | ||
return commands.filter(function(cmd) { | ||
return cmd.match(parts) | ||
return commands.map(function(cmd) { | ||
return cmd.match(array) | ||
}).filter(function(match) { | ||
return match.partsNotMatched === 0 | ||
}).sort(function(a, b) { | ||
if (a.length > b.length) | ||
return -1 | ||
else | ||
if (a.inputNotMatched > b.inputNotMatched) | ||
return 1 | ||
if (a.inputNotMatched === b.inputNotMatched && a.totalDistance > b.totalDistance) | ||
return 1 | ||
return -1 | ||
}).map(function(match) { | ||
return match.cmd | ||
}) | ||
@@ -51,3 +59,3 @@ } | ||
var argv = minimist(args) | ||
, matching = lookup(argv._) | ||
, matching = lookup(argv._.join(' ')) | ||
@@ -65,11 +73,10 @@ if (matching.length > 0) { | ||
function register(command, func) { | ||
var parts = command.split(' ') | ||
, matching = lookup(parts) | ||
var matching = lookup(command) | ||
matching.forEach(function(match) { | ||
if (match.length === parts.length) | ||
if (match.string === command) | ||
throw new Error('command already registered: ' + command) | ||
}) | ||
commands.push(new Command(parts, func)) | ||
commands.push(new Command(command, func)) | ||
@@ -86,6 +93,12 @@ return this | ||
function Command(parts, func) { | ||
this.parts = parts | ||
this.length = parts.length | ||
this.func = func | ||
function Command(string, func) { | ||
this.string = string | ||
this.parts = string.split(' ') | ||
this.length = this.parts.length | ||
this.func = func | ||
this.parts.forEach(function(part) { | ||
if (part.length < 3) | ||
throw new Error('command words must be at least 3 chars: ' + command) | ||
}) | ||
} | ||
@@ -105,8 +118,22 @@ | ||
Command.prototype.match = function match(args) { | ||
return this.parts.reduce(function(acc, part, i) { | ||
return acc && part === args[i] | ||
}, true) | ||
Command.prototype.match = function match(string) { | ||
return new CommandMatch(this, string) | ||
} | ||
function CommandMatch(cmd, array) { | ||
this.cmd = cmd | ||
this.distances = cmd.parts.map(function(elem, i) { | ||
if (array[i] !== undefined) | ||
return leven(elem, array[i]) | ||
else | ||
return undefined | ||
}).filter(function(distance, i) { | ||
return distance !== undefined && distance < cmd.parts[i].length - 2 | ||
}) | ||
this.partsNotMatched = cmd.length - this.distances.length | ||
this.inputNotMatched = array.length - this.distances.length | ||
this.totalDistance = this.distances.reduce(function(acc, i) { return acc + i }, 0) | ||
} | ||
module.exports = commist |
{ | ||
"name": "commist", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Build your commands on minimist!", | ||
@@ -21,2 +21,3 @@ "main": "index.js", | ||
"dependencies": { | ||
"leven": "^1.0.0", | ||
"minimist": "^1.1.0" | ||
@@ -23,0 +24,0 @@ }, |
@@ -12,6 +12,6 @@ commist | ||
result = program | ||
.register('do', function(args) { | ||
.register('abcd', function(args) { | ||
console.log('just do', args) | ||
}) | ||
.register('do code', function(args) { | ||
.register('abcde code', function(args) { | ||
console.log('doing something', args) | ||
@@ -29,2 +29,17 @@ }) | ||
When calling _commist_ programs, you can abbreviate down to three char | ||
words. In the above example, these are valid commands: | ||
``` | ||
node example.js abc | ||
node example.js abc cod | ||
node example.js anot comm | ||
``` | ||
Moreover, little spelling mistakes are corrected too: | ||
``` | ||
node example.js abcs cod | ||
``` | ||
Acknowledgements | ||
@@ -31,0 +46,0 @@ ---------------- |
66
test.js
@@ -141,1 +141,67 @@ | ||
}) | ||
test('looking up commands with abbreviations', function(t) { | ||
var program = commist() | ||
, result | ||
function noop1() {} | ||
function noop2() {} | ||
function noop3() {} | ||
program.register('hello', noop1) | ||
program.register('hello world matteo', noop3) | ||
program.register('hello world', noop2) | ||
t.equal(program.lookup('hel')[0].func, noop1) | ||
t.equal(program.lookup('hel wor mat')[0].func, noop3) | ||
t.equal(program.lookup('hel wor')[0].func, noop2) | ||
t.end() | ||
}) | ||
test('executing commands from abbreviations', function(t) { | ||
t.plan(1) | ||
var program = commist() | ||
, result | ||
program.register('hello', function(args) { | ||
t.deepEqual(args, { _: ['a'], x: 23 }) | ||
}) | ||
program.register('hello world', function(args) { | ||
t.ok(false, 'must pick the right command') | ||
}) | ||
program.parse(['hel', 'a', '-x', '23']) | ||
}) | ||
test('a command must be at least 3 chars', function(t) { | ||
var program = commist() | ||
, result | ||
function noop1() {} | ||
try { | ||
program.register('h', noop1) | ||
t.ok(false, 'not thrown') | ||
} catch(err) { | ||
} | ||
t.end() | ||
}) | ||
test('a command part must be at least 3 chars', function(t) { | ||
var program = commist() | ||
, result | ||
function noop1() {} | ||
try { | ||
program.register('h b', noop1) | ||
t.ok(false, 'not thrown') | ||
} catch(err) { | ||
} | ||
t.end() | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
11448
268
52
2
+ Addedleven@^1.0.0
+ Addedleven@1.0.2(transitive)