Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

inquirer

Package Overview
Dependencies
Maintainers
1
Versions
232
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

inquirer - npm Package Compare versions

Comparing version
0.1.9
to
0.2.0
+39
examples/checkbox.js
/**
* Checkbox list examples
*/
"use strict";
var inquirer = require("../lib/inquirer");
inquirer.prompt([
{
type: "checkbox",
message: "Select toppings",
name: "toppings",
choices: [
{
name: "Peperonni"
},
{
name: "Cheese"
},
{
name: "Pineapple"
},
{
name: "Mushroom"
},
{
name: "Bacon"
}
],
validate: function( answer ) {
if ( answer.length < 1 ) {
return "You must choose at least one topping.";
}
return true;
}
}
], function( answers ) {
console.log( JSON.stringify(answers, null, " ") );
});
/**
* Expand list examples
*/
"use strict";
var inquirer = require("../lib/inquirer");
inquirer.prompt([
{
type: "expand",
message: "Conflict on `file.js`: ",
name: "overwrite",
choices: [
{
key: "y",
name: "Overwrite",
value: "overwrite"
},
{
key: "a",
name: "Overwrite this one and all next",
value: "overwrite_all"
},
{
key: "d",
name: "Show diff",
value: "diff"
},
{
key: "x",
name: "Abort",
value: "abort"
}
]
}
], function( answers ) {
console.log( JSON.stringify(answers, null, " ") );
});
/**
* Input prompt example
*/
"use strict";
var inquirer = require("../lib/inquirer");
var questions = [
{
type: "input",
name: "first_name",
message: "What's your first name"
},
{
type: "input",
name: "last_name",
message: "What's your last name"
},
{
type: "input",
name: "phone",
message: "What's your phone number",
validate: function( value ) {
var pass = value.match(/^([01]{1})?[\-\.\s]?\(?(\d{3})\)?[\-\.\s]?(\d{3})[\-\.\s]?(\d{4})\s?((?:#|ext\.?\s?|x\.?\s?){1}(?:\d+)?)?$/i);
if (pass) {
return true;
} else {
return "Please enter a valid phone number";
}
}
}
];
inquirer.prompt( questions, function( answers ) {
console.log( JSON.stringify(answers, null, " ") );
});
/**
* List prompt example
*/
"use strict";
var inquirer = require("../lib/inquirer");
inquirer.prompt({
type: "list",
name: "size",
message: "What size do you need",
choices: [ "Jumbo", "Large", "Standard", "Medium", "Small", "Micro" ],
filter: function( val ) { return val.toLowerCase(); }
}, function( answers ) {
console.log( JSON.stringify(answers, null, " ") );
});
/**
* Password prompt example
*/
"use strict";
var inquirer = require("../lib/inquirer");
inquirer.prompt([
{
type: "password",
message: "Enter your git password",
name: "password"
}
], function( answers ) {
console.log( JSON.stringify(answers, null, " ") );
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

/**
* `list` type prompt
*/
var _ = require("lodash");
var util = require("util");
var clc = require("cli-color");
var Base = require("./base");
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt() {
Base.apply( this, arguments );
if (!this.opt.choices) {
this.throwParamError("choices");
}
this.firstRender = true;
this.pointer = 0;
// Make sure no default is set (so it won't be printed)
this.opt.default = null;
return this;
}
util.inherits( Prompt, Base );
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype._run = function( cb ) {
this.done = cb;
// Move the selected marker on keypress
this.rl.on( "keypress", this.onKeypress.bind(this) );
// Once user confirm (enter key)
this.rl.on( "line", this.onSubmit.bind(this) );
// Init the prompt
this.render();
this.hideCursor();
// Prevent user from writing
this.rl.output.mute();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function() {
// Render question
var message = this.getQuestion();
var choicesStr = this.getChoices();
if ( this.firstRender ) {
message += clc.blackBright("(Press <space> to select)");
}
// Render choices or answer depending on the state
if ( this.status === "answered" ) {
message += clc.cyan( this.selection.join(", ") ) + "\n";
} else {
message += choicesStr;
}
this.firstRender = false;
var msgLines = message.split(/\n/);
this.height = msgLines.length;
// Write message to screen and setPrompt to control backspace
this.rl.setPrompt( _.last(msgLines) );
this.write( message );
return this;
};
/**
* Generate the prompt choices string
* @return {String} Choices string
*/
Prompt.prototype.getChoices = function() {
var output = "";
this.opt.choices.forEach(function( choice, i ) {
output += "\n ";
var isSelected = (i === this.pointer);
output += isSelected ? clc.cyan(this.getPointer()) : " ";
output += this.getCheckbox( choice.checked, choice.name );
}.bind(this));
return output;
};
/**
* When user press `enter` key
*/
Prompt.prototype.onSubmit = function() {
var choices = _.where(this.opt.choices, { checked: true });
this.selection = _.pluck(choices, "name");
var answer = _.pluck(choices, "value");
this.rl.output.unmute();
this.showCursor();
this.validate( answer, function( isValid ) {
if ( isValid === true ) {
this.status = "answered";
// Rerender prompt (and clean subline error)
this.down().clean(1).render();
this.rl.removeAllListeners("keypress");
this.rl.removeAllListeners("line");
this.done( answer );
} else {
this.down().error( isValid ).clean().render();
this.hideCursor();
this.rl.output.mute();
}
}.bind(this));
};
/**
* When user press a key
*/
Prompt.prototype.onKeypress = function( s, key ) {
// Only process up and down key
if (!key || (key.name !== "up" && key.name !== "down" && key.name !== "space")) return;
var len = this.opt.choices.length;
this.rl.output.unmute();
if ( key.name === "space" ) {
var checked = this.opt.choices[ this.pointer ].checked;
this.opt.choices[ this.pointer ].checked = !checked;
} else if ( key.name === "up" ) {
(this.pointer > 0) ? this.pointer-- : (this.pointer = len - 1);
} else if ( key.name === "down" ) {
(this.pointer < len - 1) ? this.pointer++ : (this.pointer = 0);
}
// Rerender
this.clean().render();
this.rl.output.mute();
};
/**
* `rawlist` type prompt
*/
var _ = require("lodash");
var util = require("util");
var clc = require("cli-color");
var Base = require("./base");
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt() {
Base.apply( this, arguments );
if ( !this.opt.choices ) {
this.throwParamError("choices");
}
this.validate();
// Add the default `help` (/expand) option
this.opt.choices.push({
key : "h",
name : "Help, list all options",
value : "help"
});
// Setup the default string (capitalize the default key)
var defIndex = 0;
if ( _.isNumber(this.opt.default) && this.opt.choices[this.opt.default] ) {
defIndex = this.opt.default;
}
var defStr = _.pluck( this.opt.choices, "key" );
this.rawDefault = defStr[ defIndex ];
defStr[ defIndex ] = String( defStr[defIndex] ).toUpperCase();
this.opt.default = defStr.join("");
return this;
}
util.inherits( Prompt, Base );
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype._run = function( cb ) {
this.done = cb;
// Save user answer and update prompt to show selected option.
this.rl.on( "line", this.onSubmit.bind(this) );
this.rl.on( "keypress", this.onKeypress.bind(this) );
// Init the prompt
this.render();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function() {
// Render question
var message = this.getQuestion();
if ( this.status === "answered" ) {
message += clc.cyan( this.selected.name ) + "\n";
} else if ( this.status === "expanded" ) {
message += this.getChoices();
message += "\n Answer: ";
}
var msgLines = message.split(/\n/);
this.height = msgLines.length;
this.rl.setPrompt( _.last(msgLines) );
this.write( message );
return this;
};
/**
* Generate the prompt choices string
* @return {String} Choices string
*/
Prompt.prototype.getChoices = function() {
var output = "";
this.opt.choices.forEach(function( choice, i ) {
var choiceStr = "\n " + choice.key + ") " + choice.name;
if ( this.selectedKey === choice.key ) {
choiceStr = clc.cyan( choiceStr );
}
output += choiceStr;
}.bind(this));
return output;
};
/**
* When user press `enter` key
*/
Prompt.prototype.onSubmit = function( input ) {
if ( input == null || input === "" ) {
input = this.rawDefault;
}
var selected = _.where( this.opt.choices, { key : input.toLowerCase() })[0];
if ( selected != null && selected.key === "h" ) {
this.selectedKey = "";
this.status = "expanded";
this.down().clean(2).render();
return;
}
if ( selected != null ) {
this.status = "answered";
this.selected = selected;
// Re-render prompt
this.down().clean(2).render();
this.rl.removeAllListeners("line");
this.rl.removeAllListeners("keypress");
this.done( this.selected.value );
return;
}
// Input is invalid
this
.error("Please enter a valid command")
.clean()
.render();
};
/**
* When user press a key
*/
Prompt.prototype.onKeypress = function( s, key ) {
this.selectedKey = this.rl.line.toLowerCase();
var selected = _.where( this.opt.choices, { key : this.selectedKey })[0];
if ( this.status === "expanded" ) {
this.clean().render();
} else {
this
.down()
.hint( selected ? selected.name : "" )
.clean()
.render();
}
this.write( this.rl.line );
};
/**
* Validate the choices
*/
Prompt.prototype.validate = function() {
var formatError;
var errors = [];
var keymap = {};
this.opt.choices.map(function( choice ) {
if ( !choice.key || choice.key.length !== 1 ) {
formatError = true;
}
if ( keymap[choice.key] ) {
errors.push(choice.key);
}
keymap[ choice.key ] = true;
choice.key = String( choice.key ).toLowerCase();
});
if ( formatError ) {
throw new Error("Format error: `key` param must be a single letter and is required.");
}
if ( keymap.h ) {
throw new Error("Reserved key error: `key` param cannot be `h` - this value is reserved.");
}
if ( errors.length ) {
throw new Error( "Duplicate key error: `key` param must be unique. Duplicates: " +
_.uniq(errors).join(", ") );
}
};
/**
* `password` type prompt
*/
var _ = require("lodash");
var util = require("util");
var clc = require("cli-color");
var Base = require("./base");
/**
* Module exports
*/
module.exports = Prompt;
/**
* Constructor
*/
function Prompt() {
return Base.apply( this, arguments );
}
util.inherits( Prompt, Base );
/**
* Start the Inquiry session
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype._run = function( cb ) {
this.done = cb;
// Once user confirm (enter key)
this.rl.on( "line", this.onSubmit.bind(this) );
this.rl.on( "keypress", this.onKeypress.bind(this) );
// Init
this.render();
this.rl.output.mute();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function() {
var message = this.getQuestion();
var msgLines = message.split(/\n/);
this.height = msgLines.length;
// Write message to screen and setPrompt to control backspace
this.rl.setPrompt( _.last(msgLines) );
this.write( message );
return this;
};
/**
* When user press `enter` key
*/
Prompt.prototype.onSubmit = function( input ) {
var value = input || this.opt.default || "";
this.rl.output.unmute();
this.validate( value, function( isValid ) {
if ( isValid === true ) {
this.status = "answered";
// Re-render prompt
this.down().clean(2).render();
//Mask answer
var mask = new Array( value.length + 1 ).join("*");
// Render answer
this.write( clc.cyan(mask) + "\n" );
this.rl.removeAllListeners("line");
this.done( value );
} else {
this.down().error( isValid ).clean().render();
this.rl.output.mute();
}
}.bind(this));
};
/**
* When user type
*/
Prompt.prototype.onKeypress = function() {
this.rl.output.unmute();
this.clean().render();
var mask = new Array( this.rl.line.length + 1 ).join("*");
this.write(mask);
this.rl.output.mute();
};
module.exports = {
input: {
message: "message",
name: "name"
},
confirm: {
message: "message",
name: "name"
},
password: {
message: "message",
name: "name"
},
list: {
message: "message",
name: "name",
choices: [ "foo", "bar", "bum" ]
},
rawlist: {
message: "message",
name: "name",
choices: [ "foo", "bar", "bum" ]
},
expand: {
message: "message",
name: "name",
choices: [
{ key: "a", name: "acab" },
{ key: "b", name: "bar" },
{ key: "c", name: "chile" }
]
},
checkbox: {
message: "message",
name: "name",
choices: [
"choice 1",
"choice 2",
"choice 3"
]
}
};
var expect = require("chai").expect;
var sinon = require("sinon");
var ReadlineStub = require("../../helpers/readline");
var Base = require("../../../lib/prompts/base");
describe("`base` prompt (e.g. prompt helpers)", function() {
beforeEach(function() {
this.rl = new ReadlineStub();
this.base = new Base({
message: "foo bar",
name: "name"
}, this.rl );
});
it("`suffix` method should only add ':' if last char is a letter", function() {
expect(this.base.suffix("m:")).to.equal("m: ");
expect(this.base.suffix("m?")).to.equal("m? ");
expect(this.base.suffix("m")).to.equal("m: ");
expect(this.base.suffix("m ")).to.equal("m ");
expect(this.base.suffix()).to.equal(": ");
});
it("should not point by reference to the entry `question` object", function() {
var question = {
message: "foo bar",
name: "name"
};
var base = new Base( question, this.rl );
expect(question).to.not.equal(base.opt);
expect(question.name).to.equal(base.opt.name);
expect(question.message).to.equal(base.opt.message);
});
});
var expect = require("chai").expect;
var sinon = require("sinon");
var _ = require("lodash");
var ReadlineStub = require("../../helpers/readline");
var fixtures = require("../../helpers/fixtures");
var Checkbox = require("../../../lib/prompts/checkbox");
describe("`checkbox` prompt", function() {
beforeEach(function() {
var self = this;
this.output = "";
this.fixture = _.clone( fixtures.checkbox );
this._write = Checkbox.prototype.write;
Checkbox.prototype.write = function( str ) {
self.output += str;
return this;
};
this.rl = new ReadlineStub();
this.checkbox = new Checkbox( this.fixture, this.rl );
});
afterEach(function() {
Checkbox.prototype.write = this._write;
});
it("should return a single selected choice in an array", function( done ) {
this.checkbox.run(function( answer ) {
expect(answer).to.be.an("array");
expect(answer.length).to.equal(1);
expect(answer[0]).to.equal("choice 1");
done();
});
this.rl.emit("keypress", " ", { name: "space" });
this.rl.emit("line");
});
it("should return multiples selected choices in an array", function( done ) {
this.checkbox.run(function( answer ) {
expect(answer).to.be.an("array");
expect(answer.length).to.equal(2);
expect(answer[0]).to.equal("choice 1");
expect(answer[1]).to.equal("choice 2");
done();
});
this.rl.emit("keypress", " ", { name: "space" });
this.rl.emit("keypress", null, { name: "down" });
this.rl.emit("keypress", " ", { name: "space" });
this.rl.emit("line");
});
it("should check defaults choices", function( done ) {
this.fixture.choices = [
{ name: "1", checked: true },
{ name: "2", checked: false },
{ name: "3", checked: false }
];
this.checkbox = new Checkbox( this.fixture, this.rl );
this.checkbox.run(function( answer ) {
expect(answer.length).to.equal(1);
expect(answer[0]).to.equal("1");
done();
});
this.rl.emit("line");
});
it("should toggle choice when hitting space", function( done ) {
this.checkbox.run(function( answer ) {
expect(answer.length).to.equal(1);
expect(answer[0]).to.equal("choice 1");
done();
});
this.rl.emit("keypress", " ", { name: "space" });
this.rl.emit("keypress", null, { name: "down" });
this.rl.emit("keypress", " ", { name: "space" });
this.rl.emit("keypress", " ", { name: "space" });
this.rl.emit("line");
});
});
var expect = require("chai").expect;
var sinon = require("sinon");
var _ = require("lodash");
var ReadlineStub = require("../../helpers/readline");
var fixtures = require("../../helpers/fixtures");
var Expand = require("../../../lib/prompts/expand");
describe("`expand` prompt", function() {
beforeEach(function() {
var self = this;
this.output = "";
this._write = Expand.prototype.write;
Expand.prototype.write = function( str ) {
self.output += str;
return this;
};
this.fixture = _.clone( fixtures.expand );
this.rl = new ReadlineStub();
this.expand = new Expand( this.fixture, this.rl );
});
afterEach(function() {
Expand.prototype.write = this._write;
});
it("should throw if `key` is missing", function() {
var mkPrompt = function() {
this.fixture.choices = [ "a", "a" ];
return new Expand( this.fixture, this.rl );
}.bind(this);
expect(mkPrompt).to.throw(/Format error/);
});
it("should throw if `key` is duplicate", function() {
var mkPrompt = function() {
this.fixture.choices = [
{ key: "a", name: "foo" },
{ key: "a", name: "foo" }
];
return new Expand( this.fixture, this.rl );
}.bind(this);
expect(mkPrompt).to.throw(/Duplicate\ key\ error/);
});
it("should throw if `key` is `h`", function() {
var mkPrompt = function() {
this.fixture.choices = [
{ key: "h", name: "foo" }
];
return new Expand( this.fixture, this.rl );
}.bind(this);
expect(mkPrompt).to.throw(/Reserved\ key\ error/);
});
it("should take the first choice by default", function( done ) {
this.expand.run(function( answer ) {
expect(answer).to.equal("acab");
done();
});
this.rl.emit("line");
});
it("should use the `default` argument value", function( done ) {
this.fixture.default = 1;
this.expand = new Expand( this.fixture, this.rl );
this.expand.run(function( answer ) {
expect(answer).to.equal("bar");
done();
});
this.rl.emit("line");
});
it("should return the user input", function( done ) {
this.expand.run(function( answer ) {
expect(answer).to.equal("bar");
done();
});
this.rl.emit("line", "b");
});
it("should have help option", function( done ) {
var run = 0;
this.expand.run(function( answer ) {
expect(this.output).to.match(/a\)\ acab/);
expect(this.output).to.match(/b\)\ bar/);
expect(answer).to.equal("chile");
done();
}.bind(this));
this.rl.emit("line", "h");
this.rl.emit("line", "c");
});
it("should not allow invalid command", function( done ) {
var self = this;
var callCount = 0;
this.expand.run(function( answer ) {
callCount++;
});
this.rl.emit( "line", "blah" );
setTimeout(function() {
self.rl.emit( "line", "a" );
setTimeout(function() {
expect(callCount).to.equal(1);
done();
}, 10 );
}, 10 );
});
it("should display and capitalize the default choice `key`", function() {
this.fixture.default = 1;
this.expand = new Expand( this.fixture, this.rl );
this.expand.run(function() {});
expect(this.output).to.contain("(aBch)");
});
it("should 'autocomplete' the user input", function() {
this.expand = new Expand( this.fixture, this.rl );
this.expand.run(function() {});
this.rl.line = "a";
this.rl.emit("keypress");
setTimeout(function() {
expect(this.output).to.contain("acab");
}.bind(this), 10);
});
});
var expect = require("chai").expect;
var sinon = require("sinon");
var _ = require("lodash");
var ReadlineStub = require("../../helpers/readline");
var fixtures = require("../../helpers/fixtures");
var Password = require("../../../lib/prompts/password");
describe("`password` prompt", function() {
beforeEach(function() {
this._write = Password.prototype.write;
Password.prototype.write = function() { return this; };
this.fixture = _.clone( fixtures.password );
this.rl = new ReadlineStub();
});
afterEach(function() {
Password.prototype.write = this._write;
});
it("should use raw value from the user", function( done ) {
var password = new Password( this.fixture, this.rl );
password.run(function( answer ) {
expect(answer).to.equal("Inquirer");
done();
});
this.rl.emit( "line", "Inquirer" );
});
});
+0
-0

@@ -0,0 +0,0 @@ {

@@ -0,0 +0,0 @@ language: node_js

+6
-4

@@ -49,3 +49,3 @@ /**

{
type: "list",
type: "expand",
name: "toppings",

@@ -55,2 +55,3 @@ message: "What about the toping",

{
key: "p",
name: "Peperonni and chesse",

@@ -60,2 +61,3 @@ value: "PeperonniChesse"

{
key: "a",
name: "All dressed",

@@ -65,7 +67,7 @@ value: "alldressed"

{
key: "w",
name: "Hawaïan",
value: "hawain"
value: "hawaian"
}
],
default: 1
]
},

@@ -72,0 +74,0 @@ {

@@ -10,3 +10,3 @@ /*jshint strict:false */

},
files: [ "lib/**/*.js" ]
files: [ "lib/**/*.js", "test/**/*.js" ]
},

@@ -13,0 +13,0 @@

@@ -6,3 +6,2 @@ /**

"use strict";
var _ = require("lodash");

@@ -27,6 +26,9 @@ var async = require("async");

cli.prompts = {
list : require("./prompts/list"),
input : require("./prompts/input"),
confirm : require("./prompts/confirm"),
rawlist : require("./prompts/rawlist")
list : require("./prompts/list"),
input : require("./prompts/input"),
confirm : require("./prompts/confirm"),
rawlist : require("./prompts/rawlist"),
expand : require("./prompts/expand"),
checkbox : require("./prompts/checkbox"),
password : require("./prompts/password")
};

@@ -92,2 +94,6 @@

if ( _.isFunction(question.choices) ) {
question.choices = question.choices( this.answers );
}
var prompt = new this.prompts[question.type]( question, this.rl );

@@ -117,2 +123,6 @@

cli.onKeypress = function( s, key ) {
// Ignore `enter` key (readline `line` event is the only one we care for)
if ( key && (key.name === "enter" || key.name === "return") ) return;
this.rl.emit( "keypress", s, key );

@@ -128,4 +138,6 @@ }.bind(cli);

cli.onForceClose = function() {
this.rl.output.unmute();
process.stdout.write("\033[?25h");
this.rl.close();
console.log("\n"); // Line return
}.bind(cli);

@@ -28,8 +28,8 @@ /**

_.assign( this, {
height : 0,
answered : false
height : 0,
status : "pending"
});
// Set defaults prompt options
this.opt = _.defaults( question, {
this.opt = _.defaults( _.clone(question), {
validate: function() { return true; },

@@ -120,3 +120,3 @@ filter: function( val ) { return val; },

while ( x-- ) {
this.rl.output.write("\n");
this.write("\n");
}

@@ -142,3 +142,3 @@

/**
* Write error message under the current line
* Write error message
* @param {String} Error Error message

@@ -149,2 +149,5 @@ * @return {Prompt} Self

Prompt.prototype.error = function( error ) {
readline.moveCursor( this.rl.output, -clc.width, 0 );
readline.clearLine( this.rl.output, 0 );
var errMsg = clc.red(">> ") +

@@ -154,5 +157,22 @@ (error || "Please enter a valid value");

this.up();
return this.up();
};
return this;
/**
* Write hint message
* @param {String} Hint Hint message
* @return {Prompt} Self
*/
Prompt.prototype.hint = function( hint ) {
readline.moveCursor( this.rl.output, -clc.width, 0 );
readline.clearLine( this.rl.output, 0 );
if ( hint.length ) {
var hintMsg = clc.cyan(">> ") + hint;
this.write( hintMsg );
}
return this.up();
};

@@ -206,3 +226,3 @@

str || (str = "");
return str + ": ";
return (str.length < 1 || /([a-z])$/i.test(str) ? str + ":" : str).trim() + " ";
};

@@ -218,6 +238,6 @@

var message = this.prefix() + this.opt.message + this.suffix();
var message = _.compose(this.prefix, this.suffix)(this.opt.message);
// Append the default if available, and if question isn't answered
if ( this.opt.default && !this.answered ) {
if ( this.opt.default && this.status !== "answered" ) {
message += "("+ this.opt.default + ") ";

@@ -239,1 +259,53 @@ }

};
/**
* Hide cursor
* @return {Prompt} self
*/
Prompt.prototype.hideCursor = function() {
return this.write("\033[?25l");
};
/**
* Show cursor
* @return {Prompt} self
*/
Prompt.prototype.showCursor = function() {
return this.write("\033[?25h");
};
/**
* Get the pointer char
* @return {String} the pointer char
*/
Prompt.prototype.getPointer = function() {
if ( process.platform === "win32" ) return ">";
if ( process.platform === "linux" ) return "‣";
return "❯";
};
/**
* Get the checkbox
* @param {Boolean} checked - add a X or not to the checkbox
* @param {String} after - Text to append after the check char
* @return {String} - Composited checkbox string
*/
Prompt.prototype.getCheckbox = function( checked, after ) {
var win32 = (process.platform === "win32");
var check = "";
after || (after = "");
if ( checked ) {
check = clc.green( win32 ? "[X]" : "⬢" );
} else {
check = win32 ? "[ ]" : "⬡";
}
return check + " " + after;
};

@@ -76,5 +76,6 @@ /**

this.write( message );
this.rl.setPrompt( message );
this.height = message.split(/\n/).length;
var msgLines = message.split(/\n/);
this.height = msgLines.length;
this.rl.setPrompt( _.last(msgLines) );

@@ -90,3 +91,3 @@ return this;

Prompt.prototype.onSubmit = function( input ) {
this.answered = true;
this.status = "answered";

@@ -93,0 +94,0 @@ // Filter value to write final answer to screen

@@ -55,5 +55,6 @@ /**

this.write( message );
this.rl.setPrompt( message );
this.height = message.split(/\n/).length;
var msgLines = message.split(/\n/);
this.height = msgLines.length;
this.rl.setPrompt( _.last(msgLines) );

@@ -74,6 +75,6 @@ return this;

if ( isValid === true ) {
this.answered = true;
this.status = "answered";
// Re-render prompt
this.down().clean(2).render();
this.clean(1).render();

@@ -86,5 +87,5 @@ // Render answer

} else {
this.error(isValid).clean().render();
this.error( isValid ).clean().render();
}
}.bind(this));
};

@@ -62,3 +62,3 @@ /**

this.render();
this.rl.output.write( this.hideCursor() );
this.hideCursor();

@@ -88,4 +88,4 @@ // Prevent user from writing

// Render choices or answer depending on the state
if ( this.answered ) {
message += clc.cyan(this.opt.choices[this.selected].name) + "\n";
if ( this.status === "answered" ) {
message += clc.cyan( this.opt.choices[this.selected].name ) + "\n";
} else {

@@ -117,9 +117,9 @@ message += choicesStr;

this.opt.choices.forEach(function( choice, i ) {
output += "\n ";
if ( i === this.selected ) {
output += clc.cyan("[X] " + choice.name);
} else {
output += "[ ] " + choice.name;
output += "\n ";
var isSelected = (i === this.selected);
var line = (isSelected ? this.getPointer() + " " : " ") + choice.name;
if ( isSelected ) {
line = clc.cyan( line );
}
output += " ";
output += line + " ";
}.bind(this));

@@ -136,4 +136,4 @@

Prompt.prototype.onSubmit = function() {
var choice = this.opt.choices[this.selected];
this.answered = true;
var choice = this.opt.choices[ this.selected ];
this.status = "answered";

@@ -144,3 +144,3 @@ // Rerender prompt

this.rl.output.write( this.showCursor() );
this.showCursor();

@@ -174,21 +174,1 @@ this.rl.removeAllListeners("keypress");

};
/**
* Hide cursor
* @return {String} hide cursor ANSI string
*/
Prompt.prototype.hideCursor = function() {
return "\033[?25l";
};
/**
* Show cursor
* @return {String} show cursor ANSI string
*/
Prompt.prototype.showCursor = function() {
return "\033[?25h";
};

@@ -76,3 +76,3 @@ /**

if ( this.answered ) {
if ( this.status === "answered" ) {
message += clc.cyan(this.opt.choices[this.selected].name) + "\n";

@@ -127,3 +127,3 @@ } else {

if ( this.opt.choices[input] != null ) {
this.answered = true;
this.status = "answered";
this.selected = input;

@@ -135,2 +135,3 @@

this.rl.removeAllListeners("line");
this.rl.removeAllListeners("keypress");
this.done( this.opt.choices[this.selected].value );

@@ -154,9 +155,11 @@ return;

Prompt.prototype.onKeypress = function( s, key ) {
var input = Number(this.rl.line);
var index = input - 1;
var index = this.rl.line.length ? Number(this.rl.line) - 1 : 0;
if ( this.opt.choices[index] ) {
this.selected = index;
this.down().clean(1).render();
this.rl.output.write( input.toString() );
} else {
this.selected = undefined;
}
this.down().clean(1).render().write( this.rl.line );
};

@@ -0,0 +0,0 @@ /**

@@ -28,6 +28,6 @@ /**

return {
return _.extend(val, {
name: val.name || val.value,
value: val.value || val.name
};
});
});

@@ -34,0 +34,0 @@ };

{
"name": "inquirer",
"version": "0.1.9",
"version": "0.2.0",
"description": "A collection of common interactive command line user interfaces.",

@@ -5,0 +5,0 @@ "main": "lib/inquirer.js",

+61
-24

@@ -70,4 +70,4 @@ Inquirer.js [![Build Status](https://travis-ci.org/SBoudrias/Inquirer.js.png?branch=master)](http://travis-ci.org/SBoudrias/Inquirer.js)

+ **default**: (String) Default value to use if nothing is entered
+ **choices**: (Array) Choices array.
Values can be simple `string`s, or `object`s containing a `name` (to display) and a `value` properties (to save in the answers hash).
+ **choices**: (Array|Function) Choices array or a function returning a choices array. If defined as a function, the first parameter will be the current inquirer session answers.
Array values can be simple `strings`, or `objects` containing a `name` (to display) and a `value` properties (to save in the answers hash).
+ **validate**: (Function) Receive the user input and should return `true` if the value is valid, and an error message (`String`) otherwise. If `false` is returned, a default error message is provided.

@@ -110,5 +110,7 @@ + **filter**: (Function) Receive the user input and return the filtered value to be used inside the program. The value returned will be added to the _Answers_ hash.

Prompts
Prompts type
---------------------
_allowed options written inside square brackets (`[]`) are optionnals. Others are required._
### List - `{ type: "list" }`

@@ -119,8 +121,3 @@

``` prompt
[?] What about the toping: (Use arrow key)
[X] Peperonni and chesse
[ ] All dressed
[ ] Hawaïan
```
![List prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/list-prompt.png)

@@ -132,17 +129,30 @@ ### Raw List - `{ type: "rawlist" }`

``` prompt
[?] You also get a free 2L liquor:
1) Pepsi
2) 7up
3) Coke
Answer:
```
![Raw list prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/rawlist-prompt.png)
### Expand - `{ type: "expand" }`
Take `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that
default must the choice `index` in the array)
Note that the `choice` object will take an extra parameter called `key` for the `expand` prompt. This parameter must be a single (lowercased) character. The `h` option is added by the prompt and shouldn't be defined by the user.
See `examples/expand.js` for a running example.
![Expand prompt closed](https://dl.dropboxusercontent.com/u/59696254/inquirer/expand-prompt-1.png)
![Expand prompt expanded](https://dl.dropboxusercontent.com/u/59696254/inquirer/expand-prompt-2.png)
### Checkbox - `{ type: "checkbox" }`
Take `type`, `name`, `message`, `choices`[, `filter`, `validate`] properties.
Choices marked as `{ checked: true }` will be checked by default.
![Checkbox prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/checkbox-prompt.png)
### Confirm - `{ type: "confirm" }`
Take `type`, `name`, `message`[, `default`] properties.
Take `type`, `name`, `message`[, `default`] properties. `default` is expected to be a boolean if used.
``` prompt
[?] Is it for a delivery: (Y/n)
```
![Confirm prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/confirm-prompt.png)

@@ -153,7 +163,29 @@ ### Input - `{ type: "input" }`

``` prompt
[?] Any comments on your purchase experience: (Nope, all good!)
```
![Input prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/input-prompt.png)
### Password - `{ type: "password" }`
Take `type`, `name`, `message`[, `default`, `filter`, `validate`] properties.
![Password prompt](https://dl.dropboxusercontent.com/u/59696254/inquirer/password-prompt.png)
Support (OS - terminals)
=====================
You should expect mostly good support for the CLI below. This does not mean we won't
look at issues found on other command line - feel free to report any!
- **Mac OS**:
- Terminal.app
- iTerm
- **Windows**:
- cmd.exe
- Powershell
- Cygwin
- **Ubuntu**:
- Terminal
News on the march (Release notes)

@@ -179,7 +211,12 @@ =====================

We're looking to offer good support for multiples prompt and environments. If you want to
help, we'd like to keep a list of testers for each terminal/OS so we can contact you and
get feedback before release; let us know if you want to be added to the list! (just tweet
to @vaxilart)
License
=====================
Copyright (c) 2012 Simon Boudrias
Copyright (c) 2012 Simon Boudrias (twitter: @vaxilart)
Licensed under the MIT license.

@@ -0,0 +0,0 @@ var EventEmitter = require("events").EventEmitter;

@@ -8,2 +8,3 @@ /**

var _ = require("lodash");
var fixtures = require("../helpers/fixtures");
var ReadlineStub = require("../helpers/readline");

@@ -48,2 +49,30 @@ var inquirer = require("../../lib/inquirer");

]
},
{
name: "expand",
apis: [
"requiredValues",
"filter",
"message"
]
},
{
name: "checkbox",
apis: [
"requiredValues",
"message",
"choices",
"filter",
"validate"
]
},
{
name: "password",
apis: [
"requiredValues",
"message",
"filter",
"validate",
"default"
]
}

@@ -63,11 +92,7 @@ ];

it("should filter the user input", function( done ) {
var prompt = new this.Prompt({
message: "foo bar",
name: "foo",
choices: [ "foo", "bar" ],
filter: function() {
return "pass";
}
}, this.rl);
this.fixture.filter = function() {
return "pass";
};
var prompt = new this.Prompt( this.fixture, this.rl );
prompt.run(function( answer ) {

@@ -82,14 +107,10 @@ expect(answer).to.equal("pass");

it("should allow filter function to be asynchronous", function( done ) {
var prompt = new this.Prompt({
message: "foo bar",
name: "foo",
choices: [ "foo", "bar" ],
filter: function() {
var done = this.async();
setTimeout(function() {
done("pass");
}, 0);
}
}, this.rl);
this.fixture.filter = function() {
var done = this.async();
setTimeout(function() {
done("pass");
}, 0);
};
var prompt = new this.Prompt( this.fixture, this.rl );
prompt.run(function( answer ) {

@@ -116,18 +137,15 @@ expect(answer).to.equal("pass");

var called = 0;
var prompt = new this.Prompt({
message: "foo bar",
name: "foo",
validate: function( value ) {
called++;
expect(value).to.equal("Inquirer");
// Make sure returning false won't continue
if (called === 2) {
done();
} else {
self.rl.emit("line", "Inquirer");
}
return false;
this.fixture.validate = function( value ) {
called++;
// Make sure returning false won't continue
if (called === 2) {
done();
} else {
self.rl.emit("line");
}
}, this.rl);
return false;
};
var prompt = new this.Prompt( this.fixture, this.rl );
prompt.run(function( answer ) {

@@ -138,3 +156,3 @@ // This should NOT be called

this.rl.emit("line", "Inquirer");
this.rl.emit("line");
});

@@ -146,18 +164,15 @@

var errorMessage = "uh oh, error!";
var prompt = new this.Prompt({
message: "foo bar",
name: "foo",
validate: function( value ) {
called++;
expect(value).to.equal("Inquirer");
// Make sure returning false won't continue
if (called === 2) {
done();
} else {
self.rl.emit("line", "Inquirer");
}
return errorMessage;
this.fixture.validate = function( value ) {
called++;
// Make sure returning false won't continue
if (called === 2) {
done();
} else {
self.rl.emit("line");
}
}, this.rl);
return errorMessage;
};
var prompt = new this.Prompt( this.fixture, this.rl );
prompt.run(function( answer ) {

@@ -168,3 +183,3 @@ // This should NOT be called

this.rl.emit("line", "Inquirer");
this.rl.emit("line");
});

@@ -174,12 +189,9 @@

var called = 0;
var prompt = new this.Prompt({
message: "foo bar",
name: "foo",
validate: function( value ) {
expect(value).to.equal("Inquirer");
called++;
return true;
}
}, this.rl);
this.fixture.validate = function( value ) {
called++;
return true;
};
var prompt = new this.Prompt( this.fixture, this.rl );
prompt.run(function( answer ) {

@@ -190,27 +202,25 @@ expect(called).to.equal(1);

this.rl.emit("line", "Inquirer");
this.rl.emit("line");
});
it("should allow validate function to be asynchronous", function( continu ) {
it("should allow validate function to be asynchronous", function( next ) {
var self = this;
var called = 0;
var prompt = new this.Prompt({
message: "foo bar",
name: "foo",
validate: function( value ) {
var done = this.async();
setTimeout(function() {
called++;
expect(value).to.equal("Inquirer");
// Make sure returning false won't continue
if (called === 2) {
continu();
} else {
self.rl.emit("line", "Inquirer");
}
done(false);
}, 0);
}
}, this.rl);
this.fixture.validate = function( value ) {
var done = this.async();
setTimeout(function() {
called++;
// Make sure returning false won't continue
if (called === 2) {
next();
} else {
self.rl.emit("line");
}
done(false);
}, 0);
};
var prompt = new this.Prompt( this.fixture, this.rl );
prompt.run(function( answer ) {

@@ -221,3 +231,3 @@ // This should NOT be called

this.rl.emit("line", "Inquirer");
this.rl.emit( "line" );
});

@@ -236,14 +246,10 @@

it("should allow a default value", function( done ) {
var self = this;
var prompt = new this.Prompt({
message: "foo",
name: "foo",
"default": "pass"
}, this.rl);
this.fixture.default = "pass";
var prompt = new this.Prompt( this.fixture, this.rl );
prompt.run(function( answer ) {
expect(self.output).to.contain("(pass)");
expect(this.output).to.contain("(pass)");
expect(answer).to.equal("pass");
done();
});
}.bind(this));

@@ -264,12 +270,8 @@ this.rl.emit("line", "");

it("should print message on screen", function() {
var message = "Foo bar bar foo bar";
var prompt = new this.Prompt({
message: message,
name: "foo",
choices: [ "foo", "bar" ]
}, this.rl);
this.fixture.message = "Foo bar bar foo bar";
var prompt = new this.Prompt( this.fixture, this.rl );
prompt.run();
expect(this.output).to.contain(message);
expect( this.output ).to.contain( this.fixture.message );
});

@@ -288,8 +290,4 @@

it("should print choices to screen", function() {
var choices = [ "Echo", "foo" ];
var prompt = new this.Prompt({
message: "m",
name: "foo",
choices: choices
}, this.rl);
var prompt = new this.Prompt( this.fixture, this.rl );
var choices = prompt.opt.choices;

@@ -299,3 +297,3 @@ prompt.run();

_.each( choices, function( choice ) {
expect(this.output).to.contain(choice);
expect( this.output ).to.contain( choice.name );
}, this );

@@ -312,3 +310,4 @@ });

var mkPrompt = function() {
new this.Prompt({ name : "foo" });
delete this.fixture.message;
new this.Prompt( this.fixture, this.rl );
}.bind(this);

@@ -320,3 +319,4 @@ expect(mkPrompt).to.throw(/message/);

var mkPrompt = function() {
new this.Prompt({ message : "foo" });
delete this.fixture.name;
new this.Prompt( this.fixture, this.rl );
}.bind(this);

@@ -338,3 +338,4 @@ expect(mkPrompt).to.throw(/name/);

var self = this;
this.Prompt = inquirer.prompts[detail.name];
this.fixture = _.clone(fixtures[ detail.name ]);
this.Prompt = inquirer.prompts[ detail.name ];
this.rl = new ReadlineStub();

@@ -341,0 +342,0 @@

@@ -85,6 +85,35 @@ /**

it("should parse `choices` if passed as a function", function( done ) {
var stubChoices = [ "foo", "bar" ];
inquirer.prompts.stub = function( params ) {
this.opt = {
when: function() { return true; }
};
expect(params.choices).to.equal(stubChoices);
done();
};
inquirer.prompts.stub.prototype.run = function() {};
var prompts = [{
type: "input",
name: "name1",
message: "message",
default: "bar"
}, {
type: "stub",
name: "name",
message: "message",
choices: function( answers ) {
expect(answers.name1).to.equal("bar");
return stubChoices;
}
}];
inquirer.prompt(prompts, function() {});
inquirer.rl.emit("line");
});
// Hierarchical prompts (`when`)
describe("hierarchical mode", function() {
describe("in hierarchical mode", function() {
it("should pass current answers to `when`", function( done ) {

@@ -91,0 +120,0 @@ var prompts = [{

var expect = require("chai").expect;
var sinon = require("sinon");
var _ = require("lodash");
var ReadlineStub = require("../../helpers/readline");
var fixtures = require("../../helpers/fixtures");
var Confirm = require("../../../lib/prompts/confirm");
// Prevent prompt from writing to screen
// Confirm.prototype.write = function() { return this; };

@@ -15,2 +15,3 @@ describe("`confirm` prompt", function() {

this.output = "";
this.fixture = _.clone( fixtures.confirm );

@@ -24,6 +25,3 @@ this._write = Confirm.prototype.write;

this.rl = new ReadlineStub();
this.confirm = new Confirm({
message: "foo bar",
name: "name"
}, this.rl);
this.confirm = new Confirm( this.fixture, this.rl );
});

@@ -35,6 +33,6 @@

it("should default to true", function(done) {
it("should default to true", function( done ) {
var self = this;
this.confirm.run(function(answer) {
this.confirm.run(function( answer ) {
expect(self.output).to.contain("Y/n");

@@ -45,15 +43,12 @@ expect(answer).to.be.true;

this.rl.emit("line", "");
this.rl.emit( "line", "" );
});
it("should allow a default `false` value", function(done) {
it("should allow a default `false` value", function( done ) {
var self = this;
var falseConfirm = new Confirm({
message: "foo bar",
name: "name",
default: false
}, this.rl);
this.fixture.default = false;
var falseConfirm = new Confirm( this.fixture, this.rl );
falseConfirm.run(function(answer) {
falseConfirm.run(function( answer ) {
expect(self.output).to.contain("y/N");

@@ -64,15 +59,12 @@ expect(answer).to.be.false;

this.rl.emit("line", "");
this.rl.emit( "line", "" );
});
it("should allow a default `true` value", function(done) {
it("should allow a default `true` value", function( done ) {
var self = this;
var falseConfirm = new Confirm({
message: "foo bar",
name: "name",
default: true
}, this.rl);
this.fixture.default = true;
var falseConfirm = new Confirm( this.fixture, this.rl );
falseConfirm.run(function(answer) {
falseConfirm.run(function( answer ) {
expect(self.output).to.contain("Y/n");

@@ -83,8 +75,8 @@ expect(answer).to.be.true;

this.rl.emit("line", "");
this.rl.emit( "line", "" );
});
it("should parse 'Y' value to boolean true", function(done) {
it("should parse 'Y' value to boolean true", function( done ) {
this.confirm.run(function(answer) {
this.confirm.run(function( answer ) {
expect(answer).to.be.true;

@@ -97,5 +89,5 @@ done();

it("should parse 'Yes' value to boolean true", function(done) {
it("should parse 'Yes' value to boolean true", function( done ) {
this.confirm.run(function(answer) {
this.confirm.run(function( answer ) {
expect(answer).to.be.true;

@@ -108,5 +100,5 @@ done();

it("should parse 'No' value to boolean false", function(done) {
it("should parse 'No' value to boolean false", function( done ) {
this.confirm.run(function(answer) {
this.confirm.run(function( answer ) {
expect(answer).to.be.false;

@@ -119,5 +111,5 @@ done();

it("should parse every other string value to boolean false", function(done) {
it("should parse every other string value to boolean false", function( done ) {
this.confirm.run(function(answer) {
this.confirm.run(function( answer ) {
expect(answer).to.be.false;

@@ -124,0 +116,0 @@ done();

var expect = require("chai").expect;
var sinon = require("sinon");
var _ = require("lodash");
var ReadlineStub = require("../../helpers/readline");
var fixtures = require("../../helpers/fixtures");

@@ -14,2 +16,3 @@ var Input = require("../../../lib/prompts/input");

this.fixture = _.clone( fixtures.input );
this.rl = new ReadlineStub();

@@ -22,10 +25,7 @@ });

it("should use raw value from the user", function(done) {
it("should use raw value from the user", function( done ) {
var input = new Input({
message: "foo bar",
name: "name"
}, this.rl);
var input = new Input( this.fixture, this.rl );
input.run(function(answer) {
input.run(function( answer ) {
expect(answer).to.equal("Inquirer");

@@ -35,5 +35,5 @@ done();

this.rl.emit("line", "Inquirer");
this.rl.emit( "line", "Inquirer" );
});
});
var expect = require("chai").expect;
var sinon = require("sinon");
var _ = require("lodash");
var ReadlineStub = require("../../helpers/readline");
var fixtures = require("../../helpers/fixtures");

@@ -14,8 +16,5 @@ var List = require("../../../lib/prompts/list");

this.fixture = _.clone( fixtures.list );
this.rl = new ReadlineStub();
this.list = new List({
message: "message",
name: "name",
choices: [ "foo", "bar", "bum" ]
}, this.rl);
this.list = new List( this.fixture, this.rl );
});

@@ -27,6 +26,5 @@

it("should default to first choice", function(done) {
this.list.run(function(answer) {
it("should default to first choice", function( done ) {
this.list.run(function( answer ) {
expect(answer).to.equal("foo");
done();

@@ -38,5 +36,5 @@ });

it("should move selected cursor on keypress", function(done) {
it("should move selected cursor on keypress", function( done ) {
this.list.run(function(answer) {
this.list.run(function( answer ) {
expect(answer).to.equal("bar");

@@ -50,5 +48,5 @@ done();

it("should move selected cursor up and down on keypress", function(done) {
it("should move selected cursor up and down on keypress", function( done ) {
this.list.run(function(answer) {
this.list.run(function( answer ) {
expect(answer).to.equal("foo");

@@ -63,3 +61,3 @@ done();

it("should loop the choices when going out of boundaries", function(done) {
it("should loop the choices when going out of boundaries", function( done ) {

@@ -74,3 +72,3 @@ var i = 0;

this.list.run(function(answer) {
this.list.run(function( answer ) {
expect(answer).to.equal("bar");

@@ -85,3 +83,3 @@ complete();

this.list.selected = 0; //reset
this.list.run(function(answer) {
this.list.run(function( answer ) {
expect(answer).to.equal("foo");

@@ -105,10 +103,6 @@ complete();

it("should allow a default index", function( done ) {
var rl = new ReadlineStub();
var list = new List({
message: "message",
name: "name",
choices: [ "foo", "bar", "bum" ],
default: 1
}, rl);
this.fixture.default = 1;
var list = new List( this.fixture, this.rl );
list.run(function( answer ) {

@@ -119,14 +113,10 @@ expect(answer).to.equal("bar");

rl.emit("line");
this.rl.emit("line");
});
it("should work from a default index", function( done ) {
var rl = new ReadlineStub();
var list = new List({
message: "message",
name: "name",
choices: [ "foo", "bar", "bum" ],
default: 1
}, rl);
this.fixture.default = 1;
var list = new List( this.fixture, this.rl );
list.run(function( answer ) {

@@ -137,14 +127,9 @@ expect(answer).to.equal("bum");

rl.emit("keypress", "", { name : "down" });
rl.emit("line");
this.rl.emit("keypress", "", { name : "down" });
this.rl.emit("line");
});
it("shouldn't allow an invalid index as default", function( done ) {
var rl = new ReadlineStub();
var list = new List({
message: "message",
name: "name",
choices: [ "foo", "bar", "bum" ],
default: 4
}, rl);
this.fixture.default = 4;
var list = new List( this.fixture, this.rl );

@@ -156,3 +141,3 @@ list.run(function( answer ) {

rl.emit("line");
this.rl.emit("line");

@@ -159,0 +144,0 @@ });

var expect = require("chai").expect;
var sinon = require("sinon");
var _ = require("lodash");
var ReadlineStub = require("../../helpers/readline");
var fixtures = require("../../helpers/fixtures");

@@ -15,7 +17,4 @@ var Rawlist = require("../../../lib/prompts/rawlist");

this.rl = new ReadlineStub();
this.rawlist = new Rawlist({
message: "message",
name: "name",
choices: [ "foo", "bar" ]
}, this.rl);
this.fixture = _.clone( fixtures.rawlist );
this.rawlist = new Rawlist( this.fixture, this.rl );
});

@@ -73,9 +72,4 @@

it("should allow a default index", function( done ) {
var rl = new ReadlineStub();
var list = new Rawlist({
message: "message",
name: "name",
choices: [ "foo", "bar", "bum" ],
default: 1
}, rl);
this.fixture.default = 1;
var list = new Rawlist(this.fixture, this.rl);

@@ -87,13 +81,8 @@ list.run(function( answer ) {

rl.emit("line");
this.rl.emit("line");
});
it("shouldn't allow an invalid index as default", function( done ) {
var rl = new ReadlineStub();
var list = new Rawlist({
message: "message",
name: "name",
choices: [ "foo", "bar", "bum" ],
default: 4
}, rl);
this.fixture.default = 4;
var list = new Rawlist(this.fixture, this.rl);

@@ -105,3 +94,3 @@ list.run(function( answer ) {

rl.emit("line");
this.rl.emit("line");

@@ -108,0 +97,0 @@ });

@@ -18,2 +18,16 @@ var expect = require("chai").expect;

});
it("should keep extra keys", function() {
var initial = [{ name: "foo", extra: "1" }, { name: "bar", key: "z" }];
var normalized = utils.normalizeChoices(initial);
expect(normalized).to.eql([{
name: "foo",
value: "foo",
extra: "1"
}, {
name: "bar",
value: "bar",
key: "z"
}]);
});
});

@@ -20,0 +34,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet