New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

inquirer

Package Overview
Dependencies
Maintainers
1
Versions
231
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.2.3
to
0.2.4
Inquirerjs.sublime-project

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

+0
-0

@@ -0,0 +0,0 @@ # http://editorconfig.org

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

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

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

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

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

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

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

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

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

@@ -0,0 +0,0 @@ /*jshint strict:false */

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

if ( _.isFunction(question.default) ) {
question.default = question.default( this.answers );
}
if ( _.isFunction(question.choices) ) {

@@ -96,0 +100,0 @@ question.choices = question.choices( this.answers );

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

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

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

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

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

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

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

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

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

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

+1
-1
{
"name": "inquirer",
"version": "0.2.3",
"version": "0.2.4",
"description": "A collection of common interactive command line user interfaces.",

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

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

+ **message**: (String) The question to print.
+ **default**: (String) Default value to use if nothing is entered
+ **default**: (String|Function) Default value to use if nothing is entered, or a function that returns the default value. If defined as a function, the first parameter will be the current inquirer session answers.
+ **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.

@@ -72,0 +72,0 @@ Array values can be simple `strings`, or `objects` containing a `name` (to display) and a `value` properties (to save in the answers hash).

@@ -0,0 +0,0 @@ module.exports = {

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

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

@@ -93,2 +93,32 @@ /**

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

@@ -95,0 +125,0 @@ var stubChoices = [ "foo", "bar" ];

@@ -0,0 +0,0 @@ var expect = require("chai").expect;

@@ -0,0 +0,0 @@ var expect = require("chai").expect;

@@ -0,0 +0,0 @@ var expect = require("chai").expect;

@@ -0,0 +0,0 @@ var expect = require("chai").expect;

@@ -0,0 +0,0 @@ var expect = require("chai").expect;

@@ -0,0 +0,0 @@ var expect = require("chai").expect;

@@ -0,0 +0,0 @@ var expect = require("chai").expect;

@@ -0,0 +0,0 @@ var expect = require("chai").expect;

@@ -0,0 +0,0 @@ var expect = require("chai").expect;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
{
"node" : true,
"bitwise" : true,
"boss" : true,
"browser" : true,
"camelcase" : true,
"debug" : true,
"eqeqeq" : true,
"eqnull" : true,
"esnext" : true,
"expr" : true,
"immed" : true,
"iterator" : true,
"lastsemic" : true,
"laxbreak" : true,
"laxcomma" : true,
"loopfunc" : true,
"maxlen" : 120,
"multistr" : true,
"newcap" : true,
"noarg" : true,
"onecase" : true,
"onevar" : false,
"plusplus" : false,
"proto" : true,
"quotmark" : "double",
"regexdash" : true,
"regexp" : true,
"scripturl" : true,
"shadow" : true,
"smarttabs" : true,
"strict" : false,
"sub" : true,
"supernew" : true,
"undef" : true,
"validthis" : true,
"withstmt" : true,
"globals": {
"describe": true,
"it": true,
"beforeEach": true,
"afterEach": true
}
}

Sorry, the diff of this file is not supported yet

language: node_js
node_js:
- "0.8"
- "0.10"
/**
* Nested Inquirer call
*/
"use strict";
var inquirer = require("../lib/inquirer");
inquirer.prompt({
type: "input",
name: "candy",
message: "What's your favorite candy?"
}, function( answers ) {
inquirer.prompt({
type: "input",
name: "liquor",
message: "And your favorite liquor?"
});
});
/**
* Pizza delivery prompt example
* run example by writing `node pizza.js` in your console
*/
"use strict";
var inquirer = require("../lib/inquirer");
console.log("Hi, welcome to Node Pizza");
var questions = [
{
type: "confirm",
name: "toBeDelivered",
message: "Is it for a delivery",
default: false
},
{
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";
}
}
},
{
type: "list",
name: "size",
message: "What size do you need",
choices: [ "Large", "Medium", "Small" ],
filter: function( val ) { return val.toLowerCase(); }
},
{
type: "input",
name: "quantity",
message: "How many do you need",
validate: function( value ) {
var valid = !isNaN(parseFloat(value));
return valid || "Please enter a number";
},
filter: Number
},
{
type: "list",
name: "toppings",
message: "What about the toping",
choices: [
{
name: "Peperonni and chesse",
value: "PeperonniChesse"
},
{
name: "All dressed",
value: "alldressed"
},
{
name: "Hawaïan",
value: "hawain"
}
],
default: 1
},
{
type: "rawlist",
name: "liquor",
message: "You also get a free 2L liquor",
choices: [ "Pepsi", "7up", "Coke" ]
},
{
type: "input",
name: "comments",
message: "Any comments on your purchase experience",
default: "Nope, all good!"
},
{
type: "list",
name: "prize",
message: "For leaving a comments, you get a freebie",
choices: [ "cake", "fries" ],
when: function( answers ) {
return answers.comments !== "Nope, all good!";
}
}
];
inquirer.prompt( questions, function( answers ) {
console.log("\nOrder receipt:");
console.log( JSON.stringify(answers, null, " ") );
});
/*jshint strict:false */
module.exports = function( grunt ) {
grunt.initConfig({
jshint: {
options: {
jshintrc : ".jshintrc"
},
files: [ "lib/**/*.js" ]
},
simplemocha: {
options: {
ui: "bdd",
reporter: "spec"
},
all: "test/specs/**/*.js"
}
});
grunt.loadNpmTasks("grunt-contrib-jshint");
grunt.loadNpmTasks("grunt-simple-mocha");
grunt.loadNpmTasks('grunt-release');
grunt.registerTask("default", [ "jshint", "simplemocha" ]);
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

/**
* Inquirer.js
* A collection of common interactive command line user interfaces.
*/
"use strict";
var _ = require("lodash");
var async = require("async");
var clc = require("cli-color");
var readlineFacade = require("./utils/readline");
var utils = require("./utils/utils");
/**
* Module exports
*/
var cli = module.exports;
/**
* Client interfaces
*/
cli.prompts = {
list : require("./prompts/list"),
input : require("./prompts/input"),
confirm : require("./prompts/confirm"),
rawlist : require("./prompts/rawlist")
};
/**
* Public CLI helper interface
* @param {array} questions Questions settings array
* @param {Function} cb Callback being passed the user answers
* @return {null}
*/
cli.prompt = function( questions, allDone ) {
var self = this;
// Instantiate the Readline interface
// @Note: Don't reassign if already present (allow test to override the Stream)
this.rl || (this.rl = readlineFacade.createInterface());
this.rl.resume();
// Keep global reference to the answers
this.answers = {};
// Make sure questions is an array.
if ( !_.isArray(questions) ) {
questions = [questions];
}
// Propagate keypress events directly on the readline
process.stdin.on( "keypress", this.onKeypress );
// Make sure new prompt start on a newline when closing
self.rl.on( "SIGINT", this.onForceClose );
// Control flow functions
var onCompletion = function() {
// Remove events listeners
this.rl.removeListener("SIGINT", this.onForceClose);
process.stdin.removeListener( "keypress", this.onKeypress );
// Close the readline
this.rl.close();
this.rl = null;
if ( _.isFunction(allDone) ) {
allDone(this.answers);
}
}.bind(this);
var onEach = function( question, done ) {
// Callback to save answer and continu to next question
var after = function( answer ) {
this.answers[question.name] = answer;
done( null );
}.bind(this);
// Default type to input
if ( !this.prompts[question.type] ) {
question.type = "input";
}
var prompt = new this.prompts[question.type]( question, this.rl );
// Check if prompt should be runned (if `when` return true)
utils.runAsync( prompt.opt.when, function( continu ) {
if( continu ) {
prompt.run( after );
} else {
done( null );
}
}, this.answers );
}.bind(this);
// Start running the questions
async.mapSeries( questions, onEach, onCompletion );
};
/**
* Propagate keypress to the readline
* @return {null}
*/
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 );
}.bind(cli);
/**
* Handle the ^C exit
* @return {null}
*/
cli.onForceClose = function() {
this.rl.output.unmute();
// close the readline
this.rl.close();
this.rl = null;
console.log("\n"); // Line return
}.bind(cli);
/**
* Base prompt implementation
* Should be extended by prompt types.
*/
var _ = require("lodash");
var utils = require("../utils/utils");
var clc = require("cli-color");
var ansiTrim = require("cli-color/lib/trim");
var readline = require("readline");
/**
* Module exports
*/
module.exports = Prompt;
/**
* Prompt constructor
*/
function Prompt( question, rl ) {
// Setup instance defaults property
_.assign( this, {
height : 0,
answered : false
});
// Set defaults prompt options
this.opt = _.defaults( question, {
validate: function() { return true; },
filter: function( val ) { return val; },
when: function() { return true; }
});
// Check to make sure prompt requirements are there
if (!this.opt.message) {
this.throwParamError("message");
}
if (!this.opt.name) {
this.throwParamError("name");
}
// Normalize choices
if ( _.isArray(this.opt.choices) ) {
this.opt.choices = utils.normalizeChoices( this.opt.choices );
}
this.rl = rl;
return this;
}
/**
* Start the Inquiry session and manage output value filtering
* @param {Function} cb Callback when prompt is done
* @return {this}
*/
Prompt.prototype.run = function( cb ) {
var self = this;
this._run(function( value ) {
self.filter( value, cb );
});
return this;
};
// default noop (this one should be overwritten in prompts)
Prompt.prototype._run = function( cb ) { cb(); };
/**
* Throw an error telling a required parameter is missing
* @param {String} name Name of the missing param
* @return {Throw Error}
*/
Prompt.prototype.throwParamError = function( name ) {
throw new Error("You must provide a `" + name + "` parameter");
};
/**
* Remove the prompt from screen
* @param {Number} Extra lines to remove (probably to compensate the "enter" key line
* return)
* @return {Prompt} self
*/
Prompt.prototype.clean = function( extra ) {
_.isNumber(extra) || (extra = 0);
var len = this.height + extra;
while ( len-- ) {
readline.moveCursor(this.rl.output, -clc.width, 0);
readline.clearLine(this.rl.output, 0);
if ( len ) readline.moveCursor(this.rl.output, 0, -1);
}
return this;
};
/**
* Move cursor down by `x`
* @param {Number} x How far to go down (default to 1)
* @return {Prompt} self
*/
Prompt.prototype.down = function( x ) {
_.isNumber(x) || (x = 1);
// @bug: Write new lines instead of moving cursor as unix system don't allocate a new
// line when the cursor is moved over there.
while ( x-- ) {
this.rl.output.write("\n");
}
return this;
};
/**
* Move cursor up by `x`
* @param {Number} x How far to go up (default to 1)
* @return {Prompt} self
*/
Prompt.prototype.up = function( x ) {
_.isNumber(x) || (x = 1);
readline.moveCursor( this.rl.output, 0, -x );
return this;
};
/**
* Write error message under the current line
* @param {String} Error Error message
* @return {Prompt} Self
*/
Prompt.prototype.error = function( error ) {
var errMsg = clc.red(">> ") +
(error || "Please enter a valid value");
this.write( errMsg );
this.up();
return this;
};
/**
* Validate a given input
* @param {String} value Input string
* @param {Function} callback Pass `true` (if input is valid) or an error message as
* parameter.
* @return {null}
*/
Prompt.prototype.validate = function( input, cb ) {
utils.runAsync( this.opt.validate, cb, input );
};
/**
* Filter a given input before sending back
* @param {String} value Input string
* @param {Function} callback Pass the filtered input as parameter.
* @return {null}
*/
Prompt.prototype.filter = function( input, cb ) {
utils.runAsync( this.opt.filter, cb, input );
};
/**
* Return the prompt line prefix
* @param {String} [optionnal] String to concatenate to the prefix
* @return {String} prompt prefix
*/
Prompt.prototype.prefix = function( str ) {
str || (str = "");
return "[" + clc.green("?") + "] " + str;
};
/**
* Return the prompt line suffix
* @param {String} [optionnal] String to concatenate to the suffix
* @return {String} prompt suffix
*/
Prompt.prototype.suffix = function( str ) {
str || (str = "");
return (str.length < 1 || /([a-z])$/i.test(str) ? str + ":" : str).trim() + " ";
};
/**
* Generate the prompt question string
* @return {String} prompt question string
*/
Prompt.prototype.getQuestion = function() {
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 ) {
message += "("+ this.opt.default + ") ";
}
return message;
};
/**
* Write a string to the stdout
* @return {Self}
*/
Prompt.prototype.write = function( str ) {
this.rl.output.write( str );
return this;
};
/**
* `confirm` 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 );
var rawDefault = true;
_.extend( this.opt, {
filter: function( input ) {
var value = rawDefault;
if ( input != null && input !== "" ) {
value = /^y(es)?/i.test(input);
}
return value;
}.bind(this)
});
if ( _.isBoolean(this.opt.default) ) {
rawDefault = this.opt.default;
}
this.opt.default = rawDefault ? "Y/n" : "y/N";
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;
// Once user confirm (enter key)
this.rl.once( "line", this.onSubmit.bind(this) );
// Init
this.render();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function() {
var message = this.getQuestion();
this.write( message );
this.rl.setPrompt( message );
this.height = message.split(/\n/).length;
return this;
};
/**
* When user press "enter" key
*/
Prompt.prototype.onSubmit = function( input ) {
this.answered = true;
// Filter value to write final answer to screen
this.filter( input, function( output ) {
this.clean(1).render();
this.write( clc.cyan(output ? "Yes" : "No") + "\n" );
this.done( input ); // send "input" because the master class will refilter
}.bind(this));
};
/**
* `input` 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) );
// Init
this.render();
return this;
};
/**
* Render the prompt to screen
* @return {Prompt} self
*/
Prompt.prototype.render = function() {
var message = this.getQuestion();
this.write( message );
this.rl.setPrompt( message );
this.height = message.split(/\n/).length;
return this;
};
/**
* When user press `enter` key
*/
Prompt.prototype.onSubmit = function( input ) {
var value = input || this.opt.default || "";
this.validate( value, function( isValid ) {
if ( isValid === true ) {
this.answered = true;
// Re-render prompt
this.down().clean(2).render();
// Render answer
this.write( clc.cyan(value) + "\n" );
this.rl.removeAllListeners("line");
this.done( value );
} else {
this.error(isValid).clean().render();
}
}.bind(this));
};
/**
* `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.selected = 0;
var def = this.opt.default;
if ( _.isNumber(def) && def >= 0 && def < this.opt.choices.length ) {
this.selected = def;
}
// 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.once( "line", this.onSubmit.bind(this) );
// Init the prompt
this.render();
this.rl.output.write( 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("(Use arrow keys)");
}
// Render choices or answer depending on the state
if ( this.answered ) {
message += clc.cyan(this.opt.choices[this.selected].name) + "\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 ";
if ( i === this.selected ) {
output += clc.cyan("[X] " + choice.name);
} else {
output += "[ ] " + choice.name;
}
output += " ";
}.bind(this));
return output;
};
/**
* When user press `enter` key
*/
Prompt.prototype.onSubmit = function() {
var choice = this.opt.choices[this.selected];
this.answered = true;
// Rerender prompt
this.rl.output.unmute();
this.clean().render();
this.rl.output.write( this.showCursor() );
this.rl.removeAllListeners("keypress");
this.done( choice.value );
};
/**
* 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") ) return;
this.rl.output.unmute();
var len = this.opt.choices.length;
if ( key.name === "up" ) {
(this.selected > 0) ? this.selected-- : (this.selected = len - 1);
} else if ( key.name === "down" ) {
(this.selected < len - 1) ? this.selected++ : (this.selected = 0);
}
// Rerender
this.clean().render();
this.rl.output.mute();
};
/**
* 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";
};
/**
* `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.selected = 0;
this.rawDefault = 0;
var def = this.opt.default;
if ( _.isNumber(def) && def >= 0 && def < this.opt.choices.length ) {
this.selected = this.rawDefault = def;
}
// 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;
// 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();
var choicesStr = this.getChoices();
if ( this.answered ) {
message += clc.cyan(this.opt.choices[this.selected].name) + "\n";
} else {
message += choicesStr;
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 display = "\n " + (i + 1) + ") " + choice.name;
if ( i === this.selected ) {
display = clc.cyan( display );
}
output += display;
}.bind(this));
return output;
};
/**
* When user press `enter` key
*/
Prompt.prototype.onSubmit = function( input ) {
if ( input == null || input === "" ) {
input = this.rawDefault;
} else {
input -= 1;
}
// Input is valid
if ( this.opt.choices[input] != null ) {
this.answered = true;
this.selected = input;
// Re-render prompt
this.down().clean(2).render();
this.rl.removeAllListeners("line");
this.rl.removeAllListeners("keypress");
this.done( this.opt.choices[this.selected].value );
return;
}
// Input is invalid
this
.error("Please enter a valid index")
.write( clc.bol(0, true) )
.clean()
.render();
};
/**
* When user press a key
*/
Prompt.prototype.onKeypress = function( s, key ) {
var index = this.rl.line.length ? Number(this.rl.line) - 1 : 0;
if ( this.opt.choices[index] ) {
this.selected = index;
} else {
this.selected = undefined;
}
this.down().clean(1).render().write( this.rl.line );
};
/**
* Readline API façade to fix some issues
* @Note: May look a bit like Monkey patching... if you know a better way let me know.
*/
"use strict";
var _ = require("lodash");
var readline = require("readline");
var MuteStream = require("mute-stream");
var ansiTrim = require("cli-color/lib/trim");
/**
* Module export
*/
var Interface = module.exports = {};
/**
* Create a readline interface
* @param {Object} opt Readline option hash
* @return {readline} the new readline interface
*/
Interface.createInterface = function( opt ) {
opt || (opt = {});
var filteredOpt = opt;
// Default `input` to stdin
filteredOpt.input = opt.input || process.stdin;
// Add mute capabilities to the output
var ms = new MuteStream();
ms.pipe( opt.output || process.stdout );
filteredOpt.output = ms;
// Create the readline
var rl = readline.createInterface( filteredOpt );
// Fix bug with refreshLine
rl._refreshLine = _.wrap(rl._refreshLine, function( func ) {
func.call(rl);
var line = this._prompt + this.line;
var visualLength = ansiTrim(line).length;
readline.moveCursor(this.output, -line.length, 0);
readline.moveCursor(this.output, visualLength, 0);
});
// Prevent arrows from breaking the question line
var origWrite = rl._ttyWrite;
rl._ttyWrite = function( s, key ) {
key || (key = {});
if ( key.name === "up" ) return;
if ( key.name === "down" ) return;
origWrite.apply( this, arguments );
};
return rl;
};
/**
* Utility functions
*/
"use strict";
var _ = require("lodash");
/**
* Module exports
*/
var utils = module.exports;
/**
* Normalize choices array
* @param {Array} choices The avaiable prompt choices
* @return {Array} Normalized choices containing `name`/`value` hash
*/
utils.normalizeChoices = function normalizeChoices( choices ) {
return _.map( choices, function( val ) {
if ( _.isString(val) ) {
return { name : val, value: val };
}
return {
name: val.name || val.value,
value: val.value || val.name
};
});
};
/**
* Run a function asynchronously or synchronously
* @param {Function} func Function to run
* @param {Function} cb Callback function passed the `func` returned value
* @...rest {Mixed} rest Arguments to pass to `func`
* @return {Null}
*/
utils.runAsync = function( func, cb ) {
var rest = [];
var len = 1;
while ( len++ < arguments.length ) {
rest.push( arguments[len] );
}
var async = false;
var isValid = func.apply({
async: function() {
async = true;
return _.once(cb);
}
}, rest );
if ( !async ) {
cb(isValid);
}
};

Sorry, the diff of this file is not supported yet

{
"name": "inquirer",
"version": "0.1.12",
"description": "A collection of common interactive command line user interfaces.",
"main": "lib/inquirer.js",
"scripts": {
"test": "grunt --verbose"
},
"repository": {
"type": "git",
"url": "git://github.com/SBoudrias/Inquirer.js.git"
},
"keywords": [
"command",
"prompt",
"stdin",
"cli"
],
"author": {
"name": "Simon Boudrias",
"email": "admin@simonboudrias.com"
},
"license": "MIT",
"dependencies": {
"lodash": "~1.2.1",
"async": "~0.2.8",
"cli-color": "~0.2.2",
"mute-stream": "0.0.3"
},
"devDependencies": {
"grunt": "~0.4.1",
"grunt-cli": "~0.1.8",
"grunt-simple-mocha": "~0.4.0",
"mocha": "~1.9.0",
"chai": "~1.6.0",
"grunt-contrib-jshint": "~0.5.1",
"sinon": "~1.7.2",
"proxyquire": "~0.4.1",
"grunt-release": "~0.3.3"
},
"readme": "Inquirer.js [![Build Status](https://travis-ci.org/SBoudrias/Inquirer.js.png?branch=master)](http://travis-ci.org/SBoudrias/Inquirer.js)\n=====================\n\nA collection of common interactive command line user interfaces.\n\n\nGoal and philosophy\n---------------------\n\nWe strive at providing easily embeddable and beatiful command line interface for Node.js ;\nsome hope in becoming the CLI Xanadu.\n\n_Inquirer_ should ease the process of asking end user questions, parsing, validating answers, and providing error feedback.\n\n_Inquirer_ provide the user interface, and the inquiry session flow. If you're searching for a full blown command line program utility, then check out [Commander.js](https://github.com/visionmedia/commander.js) (inspired by) or [Cli-color](https://github.com/medikoo/cli-color) (used internally).\n\n\nDocumentation\n=====================\n\n\nInstallation\n---------------------\n\n``` prompt\nnpm install inquirer\n```\n\n```javascript\nvar inquirer = require(\"inquirer\");\ninquirer.prompt([/* Pass your questions in here */], function( answers ) {\n\t// Use user feedback for... whatever!!\n});\n```\n\n\nExamples (Run it and see it)\n---------------------\n\nCheckout the `examples/` folder for code and interface examples.\n\n``` prompt\nnode examples/pizza.js\n# etc\n```\n\n\nMethods\n---------------------\n\n### `inquirer.prompt( questions, callback )`\n\nLaunch the prompt interface (inquiry session)\n\n+ **questions** (Array) containing [Question Object](#question)\n+ **callback** (Function) first parameter is the [Answers Object](#answers)\n\n\nObjects\n---------------------\n\n### Question\nA question object is a `hash` containing question related values:\n\n+ **type**: (String) Type of the prompt. Defaults: `input` - Possible values: `input`, `confirm`,\n`list`, `rawlist`\n+ **name**: (String) The name to use when storing the answer in the anwers hash.\n+ **message**: (String) The question to print.\n+ **default**: (String) Default value to use if nothing is entered\n+ **choices**: (Array) Choices array. \nValues can be simple `string`s, or `object`s containing a `name` (to display) and a `value` properties (to save in the answers hash).\n+ **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.\n+ **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.\n+ **when**: (Function) Receive the current user answers hash and should return `true` or `false` depending on wheter or not this question should be asked.\n\n`validate`, `filter` and `when` functions can be asynchronously using `this.async()`. You just have to pass the value you'd normally return to the callback option.\n\n``` javascript\n{\n validate: function(input) {\n\n // Declare function as asynchronous, and save the done callback\n var done = this.async();\n\n // Do async stuff\n setTimeout(function() {\n if (typeof input !== \"number\") {\n // Pass the return value in the done callback\n done(\"You need to provide a number\");\n return;\n }\n // Pass the return value in the done callback\n done(true);\n }, 3000);\n }\n}\n```\n\n### Answers\nA key/value hash containing the client answers in each prompt.\n\n+ **Key** The `name` property of the _question_ object\n+ **Value** (Depends on the prompt)\n + `confirm`: (Boolean)\n + `input` : User input (filtered if `filter` is defined) (String)\n + `rawlist`, `list` : Selected choice value (or name if no value specified) (String)\n\n\nPrompts\n---------------------\n\n### List - `{ type: \"list\" }`\n\nTake `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that\ndefault must the choice `index` in the array)\n\n``` prompt\n[?] What about the toping: (Use arrow key)\n [X] Peperonni and chesse\n [ ] All dressed\n [ ] Hawaïan\n```\n\n### Raw List - `{ type: \"rawlist\" }`\n\nTake `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that\ndefault must the choice `index` in the array)\n\n``` prompt\n[?] You also get a free 2L liquor: \n 1) Pepsi\n 2) 7up\n 3) Coke\n Answer: \n```\n\n### Confirm - `{ type: \"confirm\" }`\n\nTake `type`, `name`, `message`[, `default`] properties.\n\n``` prompt\n[?] Is it for a delivery: (Y/n)\n```\n\n### Input - `{ type: \"input\" }`\n\nTake `type`, `name`, `message`[, `default`, `filter`, `validate`] properties.\n\n``` prompt\n[?] Any comments on your purchase experience: (Nope, all good!)\n```\n\n\nNews on the march (Release notes)\n=====================\n\n+ **0.1.7** : Add a hierarchical prompt API with `when`, allow lists from having a default\n+ **0.1.6** : Fix bug on unix and minor enhancement\n+ **0.1.5** : Enhance visual style; prompts are now more succint. Lots of bug fixes.\n+ **0.1.3** : Add async support for validation and filtering functions.\n+ **0.1.0** : First official release. There's 4 prompt types: `input`, `confirm`, `list` and\n`rawlist`. There's functionnality to allow the validation of input, and the filtering of values.\n\n\nContributing\n=====================\n\n**Style Guide**: Please base yourself on [Idiomatic.js](https://github.com/rwldrn/idiomatic.js) style guide with two space indent \n**Unit test**: Unit test are wrote in Mocha. Please add a unit test for every new feature\nor bug fix. `npm test` to run the test suite. \n**Documentation**: Add documentation for every API change. Feel free to send corrections\nor better docs! \n\n\nLicense\n=====================\n\nCopyright (c) 2012 Simon Boudrias \nLicensed under the MIT license.\n",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/SBoudrias/Inquirer.js/issues"
},
"_id": "inquirer@0.1.12",
"_from": "inquirer@~0.1"
}
Inquirer.js [![Build Status](https://travis-ci.org/SBoudrias/Inquirer.js.png?branch=master)](http://travis-ci.org/SBoudrias/Inquirer.js)
=====================
A collection of common interactive command line user interfaces.
Goal and philosophy
---------------------
We strive at providing easily embeddable and beatiful command line interface for Node.js ;
some hope in becoming the CLI Xanadu.
_Inquirer_ should ease the process of asking end user questions, parsing, validating answers, and providing error feedback.
_Inquirer_ provide the user interface, and the inquiry session flow. If you're searching for a full blown command line program utility, then check out [Commander.js](https://github.com/visionmedia/commander.js) (inspired by) or [Cli-color](https://github.com/medikoo/cli-color) (used internally).
Documentation
=====================
Installation
---------------------
``` prompt
npm install inquirer
```
```javascript
var inquirer = require("inquirer");
inquirer.prompt([/* Pass your questions in here */], function( answers ) {
// Use user feedback for... whatever!!
});
```
Examples (Run it and see it)
---------------------
Checkout the `examples/` folder for code and interface examples.
``` prompt
node examples/pizza.js
# etc
```
Methods
---------------------
### `inquirer.prompt( questions, callback )`
Launch the prompt interface (inquiry session)
+ **questions** (Array) containing [Question Object](#question)
+ **callback** (Function) first parameter is the [Answers Object](#answers)
Objects
---------------------
### Question
A question object is a `hash` containing question related values:
+ **type**: (String) Type of the prompt. Defaults: `input` - Possible values: `input`, `confirm`,
`list`, `rawlist`
+ **name**: (String) The name to use when storing the answer in the anwers hash.
+ **message**: (String) The question to print.
+ **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).
+ **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.
+ **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.
+ **when**: (Function) Receive the current user answers hash and should return `true` or `false` depending on wheter or not this question should be asked.
`validate`, `filter` and `when` functions can be asynchronously using `this.async()`. You just have to pass the value you'd normally return to the callback option.
``` javascript
{
validate: function(input) {
// Declare function as asynchronous, and save the done callback
var done = this.async();
// Do async stuff
setTimeout(function() {
if (typeof input !== "number") {
// Pass the return value in the done callback
done("You need to provide a number");
return;
}
// Pass the return value in the done callback
done(true);
}, 3000);
}
}
```
### Answers
A key/value hash containing the client answers in each prompt.
+ **Key** The `name` property of the _question_ object
+ **Value** (Depends on the prompt)
+ `confirm`: (Boolean)
+ `input` : User input (filtered if `filter` is defined) (String)
+ `rawlist`, `list` : Selected choice value (or name if no value specified) (String)
Prompts
---------------------
### List - `{ type: "list" }`
Take `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that
default must the choice `index` in the array)
``` prompt
[?] What about the toping: (Use arrow key)
[X] Peperonni and chesse
[ ] All dressed
[ ] Hawaïan
```
### Raw List - `{ type: "rawlist" }`
Take `type`, `name`, `message`, `choices`[, `default`, `filter`] properties. (Note that
default must the choice `index` in the array)
``` prompt
[?] You also get a free 2L liquor:
1) Pepsi
2) 7up
3) Coke
Answer:
```
### Confirm - `{ type: "confirm" }`
Take `type`, `name`, `message`[, `default`] properties.
``` prompt
[?] Is it for a delivery: (Y/n)
```
### Input - `{ type: "input" }`
Take `type`, `name`, `message`[, `default`, `filter`, `validate`] properties.
``` prompt
[?] Any comments on your purchase experience: (Nope, all good!)
```
News on the march (Release notes)
=====================
+ **0.1.7** : Add a hierarchical prompt API with `when`, allow lists from having a default
+ **0.1.6** : Fix bug on unix and minor enhancement
+ **0.1.5** : Enhance visual style; prompts are now more succint. Lots of bug fixes.
+ **0.1.3** : Add async support for validation and filtering functions.
+ **0.1.0** : First official release. There's 4 prompt types: `input`, `confirm`, `list` and
`rawlist`. There's functionnality to allow the validation of input, and the filtering of values.
Contributing
=====================
**Style Guide**: Please base yourself on [Idiomatic.js](https://github.com/rwldrn/idiomatic.js) style guide with two space indent
**Unit test**: Unit test are wrote in Mocha. Please add a unit test for every new feature
or bug fix. `npm test` to run the test suite.
**Documentation**: Add documentation for every API change. Feel free to send corrections
or better docs!
License
=====================
Copyright (c) 2012 Simon Boudrias
Licensed under the MIT license.
var EventEmitter = require("events").EventEmitter;
var sinon = require("sinon");
var util = require("util");
var _ = require("lodash");
var stub = {
write : sinon.stub().returns(stub),
moveCursor : sinon.stub().returns(stub),
setPrompt : sinon.stub().returns(stub),
close : sinon.stub().returns(stub),
pause : sinon.stub().returns(stub),
resume : sinon.stub().returns(stub),
output : {
mute : sinon.stub().returns(stub),
unmute : sinon.stub().returns(stub),
write : sinon.stub().returns(stub)
}
};
var ReadlineStub = function() {
EventEmitter.apply( this, arguments );
};
util.inherits( ReadlineStub, EventEmitter );
_.assign( ReadlineStub.prototype, stub );
module.exports = ReadlineStub;
/**
* Test Prompt public APIs
*/
var expect = require("chai").expect;
var sinon = require("sinon");
var _ = require("lodash");
var ReadlineStub = require("../helpers/readline");
var inquirer = require("../../lib/inquirer");
// Define prompts and their public API
var prompts = [
{
name: "input",
apis: [
"filter",
"validate",
"default",
"message",
"requiredValues"
]
},
{
name: "confirm",
apis: [
"message",
"requiredValues"
]
},
{
name: "rawlist",
apis: [
"filter",
"message",
"choices",
"requiredValues"
]
},
{
name: "list",
apis: [
"filter",
"message",
"choices",
"requiredValues"
]
}
];
// Define tests
var tests = {
"filter": function() {
describe("filter API", function() {
beforeEach(function() {
this.output = "";
});
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);
prompt.run(function( answer ) {
expect(answer).to.equal("pass");
done();
});
this.rl.emit("line", "");
});
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);
prompt.run(function( answer ) {
expect(answer).to.equal("pass");
done();
});
this.rl.emit("line", "");
});
});
},
"validate": function() {
describe("validate API", function() {
beforeEach(function() {
this.output = "";
});
it("should reject input if boolean false is returned", function( done ) {
var self = this;
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.rl);
prompt.run(function( answer ) {
// This should NOT be called
expect(false).to.be.true;
});
this.rl.emit("line", "Inquirer");
});
it("should reject input if a string is returned", function( done ) {
var self = this;
var called = 0;
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.rl);
prompt.run(function( answer ) {
// This should NOT be called
expect(false).to.be.true;
});
this.rl.emit("line", "Inquirer");
});
it("should accept input if boolean true is returned", function( done ) {
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);
prompt.run(function( answer ) {
expect(called).to.equal(1);
done();
});
this.rl.emit("line", "Inquirer");
});
it("should allow validate function to be asynchronous", function( continu ) {
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);
prompt.run(function( answer ) {
// This should NOT be called
expect(false).to.be.true;
});
this.rl.emit("line", "Inquirer");
});
});
},
"default": function() {
describe("default API", function() {
beforeEach(function() {
this.output = "";
});
it("should allow a default value", function( done ) {
var self = this;
var prompt = new this.Prompt({
message: "foo",
name: "foo",
"default": "pass"
}, this.rl);
prompt.run(function( answer ) {
expect(self.output).to.contain("(pass)");
expect(answer).to.equal("pass");
done();
});
this.rl.emit("line", "");
});
});
},
"message": function() {
describe("message API", function() {
beforeEach(function() {
this.output = "";
});
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);
prompt.run();
expect(this.output).to.contain(message);
});
});
},
"choices": function() {
describe("choices API", function() {
beforeEach(function() {
this.output = "";
});
it("should print choices to screen", function() {
var choices = [ "Echo", "foo" ];
var prompt = new this.Prompt({
message: "m",
name: "foo",
choices: choices
}, this.rl);
prompt.run();
_.each( choices, function( choice ) {
expect(this.output).to.contain(choice);
}, this );
});
});
},
"requiredValues": function() {
describe("Missing value", function() {
it("`message` should throw", function() {
var mkPrompt = function() {
new this.Prompt({ name : "foo" });
}.bind(this);
expect(mkPrompt).to.throw(/message/);
});
it("`name` should throw", function() {
var mkPrompt = function() {
new this.Prompt({ message : "foo" });
}.bind(this);
expect(mkPrompt).to.throw(/name/);
});
});
}
};
// Run tests
describe("Prompt public APIs", function() {
_.each( prompts, function( detail ) {
describe("on " + detail.name + " prompt", function() {
beforeEach(function() {
var self = this;
this.Prompt = inquirer.prompts[detail.name];
this.rl = new ReadlineStub();
this.output = "";
this._write = this.Prompt.prototype.write;
this.Prompt.prototype.write = function( str ) {
self.output += str;
return this;
};
});
afterEach(function() {
this.Prompt.prototype.write = this._write;
});
_.each( detail.apis, function( apiName ) {
tests[apiName]( detail.name );
}, this);
});
});
});
/**
* Inquirer public API test
*/
var expect = require("chai").expect;
var sinon = require("sinon");
var _ = require("lodash");
var ReadlineStub = require("../helpers/readline");
var inquirer = require("../../lib/inquirer");
describe("inquirer.prompt", function() {
beforeEach(function() {
inquirer.rl = new ReadlineStub();
});
it("should resume and close readline", function( done ) {
var rl = inquirer.rl;
inquirer.prompt({
type: "confirm",
name: "q1",
message: "message"
}, function( answers ) {
expect(rl.resume.called).to.be.true;
expect(rl.close.called).to.be.true;
expect(inquirer.rl).to.be.null;
rl = inquirer.rl = new ReadlineStub();
inquirer.prompt({
type: "confirm",
name: "q1",
message: "message"
}, function( answers ) {
expect(rl.resume.called).to.be.true;
expect(rl.close.called).to.be.true;
expect(inquirer.rl).to.be.null;
done();
});
inquirer.rl.emit("line");
});
rl.emit("line");
});
it("should take a prompts array and return answers", function( done ) {
var prompts = [{
type: "confirm",
name: "q1",
message: "message"
}, {
type: "confirm",
name: "q2",
message: "message",
default: false
}];
inquirer.prompt( prompts, function( answers ) {
expect(answers.q1).to.be.true;
expect(answers.q2).to.be.false;
done();
});
inquirer.rl.emit("line");
inquirer.rl.emit("line");
});
it("should take a single prompt and return answer", function( done ) {
var prompt = {
type: "input",
name: "q1",
message: "message",
default: "bar"
};
inquirer.prompt( prompt, function( answers ) {
expect(answers.q1).to.equal("bar");
done();
});
inquirer.rl.emit("line");
});
// Hierarchical prompts (`when`)
describe("in hierarchical mode", function() {
it("should pass current answers to `when`", function( done ) {
var prompts = [{
type: "confirm",
name: "q1",
message: "message"
}, {
name: "q2",
message: "message",
when: function( answers ) {
expect(answers).to.be.an("object");
expect(answers.q1).to.be.true;
done();
}
}];
inquirer.prompt( prompts, function( answers ) {});
inquirer.rl.emit("line");
});
it("should run prompt if `when` returns true", function( done ) {
var goesInWhen = false;
var prompts = [{
type: "confirm",
name: "q1",
message: "message"
}, {
type: "input",
name: "q2",
message: "message",
default: "bar-var",
when: function() {
goesInWhen = true;
return true;
}
}];
inquirer.prompt( prompts, function( answers ) {
expect(goesInWhen).to.be.true;
expect(answers.q2).to.equal("bar-var");
done();
});
inquirer.rl.emit("line");
inquirer.rl.emit("line");
});
it("should not run prompt if `when` returns false", function( done ) {
var goesInWhen = false;
var prompts = [{
type: "confirm",
name: "q1",
message: "message"
}, {
type: "confirm",
name: "q2",
message: "message",
when: function() {
goesInWhen = true;
return false;
}
}, {
type: "input",
name: "q3",
message: "message",
default: "foo"
}];
inquirer.prompt( prompts, function( answers ) {
expect(goesInWhen).to.be.true;
expect(answers.q2).to.not.exist;
expect(answers.q3).to.equal("foo");
expect(answers.q1).to.be.true;
done();
});
inquirer.rl.emit("line");
inquirer.rl.emit("line");
});
it("should run asynchronous `when`", function( done ) {
var goesInWhen = false;
var prompts = [{
type: "confirm",
name: "q1",
message: "message"
}, {
type: "input",
name: "q2",
message: "message",
default: "foo-bar",
when: function() {
goesInWhen = true;
var goOn = this.async();
setTimeout(function() { goOn(true); }, 0 );
setTimeout(function() {
inquirer.rl.emit("line");
}, 10 );
}
}];
inquirer.prompt( prompts, function( answers ) {
expect(goesInWhen).to.be.true;
expect(answers.q2).to.equal("foo-bar");
done();
});
inquirer.rl.emit("line");
});
});
});
var expect = require("chai").expect;
var sinon = require("sinon");
var ReadlineStub = require("../../helpers/readline");
var Base = require("../../../lib/prompts/base");
// Prevent prompt from writing to screen
// Confirm.prototype.write = function() { return this; };
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(": ");
});
});
var expect = require("chai").expect;
var sinon = require("sinon");
var ReadlineStub = require("../../helpers/readline");
var Confirm = require("../../../lib/prompts/confirm");
// Prevent prompt from writing to screen
// Confirm.prototype.write = function() { return this; };
describe("`confirm` prompt", function() {
beforeEach(function() {
var self = this;
this.output = "";
this._write = Confirm.prototype.write;
Confirm.prototype.write = function( str ) {
self.output += str;
return this;
};
this.rl = new ReadlineStub();
this.confirm = new Confirm({
message: "foo bar",
name: "name"
}, this.rl);
});
afterEach(function() {
Confirm.prototype.write = this._write;
});
it("should default to true", function(done) {
var self = this;
this.confirm.run(function(answer) {
expect(self.output).to.contain("Y/n");
expect(answer).to.be.true;
done();
});
this.rl.emit("line", "");
});
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);
falseConfirm.run(function(answer) {
expect(self.output).to.contain("y/N");
expect(answer).to.be.false;
done();
});
this.rl.emit("line", "");
});
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);
falseConfirm.run(function(answer) {
expect(self.output).to.contain("Y/n");
expect(answer).to.be.true;
done();
});
this.rl.emit("line", "");
});
it("should parse 'Y' value to boolean true", function(done) {
this.confirm.run(function(answer) {
expect(answer).to.be.true;
done();
});
this.rl.emit("line", "Y");
});
it("should parse 'Yes' value to boolean true", function(done) {
this.confirm.run(function(answer) {
expect(answer).to.be.true;
done();
});
this.rl.emit("line", "Yes");
});
it("should parse 'No' value to boolean false", function(done) {
this.confirm.run(function(answer) {
expect(answer).to.be.false;
done();
});
this.rl.emit("line", "No");
});
it("should parse every other string value to boolean false", function(done) {
this.confirm.run(function(answer) {
expect(answer).to.be.false;
done();
});
this.rl.emit("line", "bla bla foo");
});
});
var expect = require("chai").expect;
var sinon = require("sinon");
var ReadlineStub = require("../../helpers/readline");
var Input = require("../../../lib/prompts/input");
describe("`input` prompt", function() {
beforeEach(function() {
this._write = Input.prototype.write;
Input.prototype.write = function() { return this; };
this.rl = new ReadlineStub();
});
afterEach(function() {
Input.prototype.write = this._write;
});
it("should use raw value from the user", function(done) {
var input = new Input({
message: "foo bar",
name: "name"
}, this.rl);
input.run(function(answer) {
expect(answer).to.equal("Inquirer");
done();
});
this.rl.emit("line", "Inquirer");
});
});
var expect = require("chai").expect;
var sinon = require("sinon");
var ReadlineStub = require("../../helpers/readline");
var List = require("../../../lib/prompts/list");
describe("`list` prompt", function() {
beforeEach(function() {
this._write = List.prototype.write;
List.prototype.write = function() { return this; };
this.rl = new ReadlineStub();
this.list = new List({
message: "message",
name: "name",
choices: [ "foo", "bar", "bum" ]
}, this.rl);
});
afterEach(function() {
List.prototype.write = this._write;
});
it("should default to first choice", function(done) {
this.list.run(function(answer) {
expect(answer).to.equal("foo");
done();
});
this.rl.emit("line");
});
it("should move selected cursor on keypress", function(done) {
this.list.run(function(answer) {
expect(answer).to.equal("bar");
done();
});
this.rl.emit("keypress", "", { name : "down" });
this.rl.emit("line");
});
it("should move selected cursor up and down on keypress", function(done) {
this.list.run(function(answer) {
expect(answer).to.equal("foo");
done();
});
this.rl.emit("keypress", "", { name : "down" });
this.rl.emit("keypress", "", { name : "up" });
this.rl.emit("line");
});
it("should loop the choices when going out of boundaries", function(done) {
var i = 0;
function complete() {
i++;
if (i === 2) {
done();
}
}
this.list.run(function(answer) {
expect(answer).to.equal("bar");
complete();
});
this.rl.emit("keypress", "", { name : "up" });
this.rl.emit("keypress", "", { name : "up" });
this.rl.emit("line");
this.list.selected = 0; //reset
this.list.run(function(answer) {
expect(answer).to.equal("foo");
complete();
});
this.rl.emit("keypress", "", { name : "down" });
this.rl.emit("keypress", "", { name : "down" });
this.rl.emit("keypress", "", { name : "down" });
this.rl.emit("line");
});
it("should require a choices array", function() {
var mkPrompt = function() {
new List({ name : "foo", message: "bar" });
};
expect(mkPrompt).to.throw(/choices/);
});
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);
list.run(function( answer ) {
expect(answer).to.equal("bar");
done();
});
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);
list.run(function( answer ) {
expect(answer).to.equal("bum");
done();
});
rl.emit("keypress", "", { name : "down" });
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);
list.run(function( answer ) {
expect(answer).to.equal("foo");
done();
});
rl.emit("line");
});
});
var expect = require("chai").expect;
var sinon = require("sinon");
var ReadlineStub = require("../../helpers/readline");
var Rawlist = require("../../../lib/prompts/rawlist");
describe("`rawlist` prompt", function() {
beforeEach(function() {
this._write = Rawlist.prototype.write;
Rawlist.prototype.write = function() { return this; };
this.rl = new ReadlineStub();
this.rawlist = new Rawlist({
message: "message",
name: "name",
choices: [ "foo", "bar" ]
}, this.rl);
});
afterEach(function() {
Rawlist.prototype.write = this._write;
});
it("should default to first choice", function(done) {
this.rawlist.run(function(answer) {
expect(answer).to.equal("foo");
done();
});
this.rl.emit("line");
});
it("should select given index", function(done) {
this.rawlist.run(function(answer) {
expect(answer).to.equal("bar");
done();
});
this.rl.emit("line", "2");
});
it("should not allow invalid index", function(done) {
var self = this;
var callCount = 0;
this.rawlist.run(function(answer) {
callCount++;
});
this.rl.emit("line", "blah");
setTimeout(function() {
self.rl.emit("line", "1");
setTimeout(function() {
expect(callCount).to.equal(1);
done();
}, 10);
}, 10);
});
it("should require a choices array", function() {
var mkPrompt = function() {
new Rawlist({ name : "foo", message: "bar" });
};
expect(mkPrompt).to.throw(/choices/);
});
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);
list.run(function( answer ) {
expect(answer).to.equal("bar");
done();
});
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);
list.run(function( answer ) {
expect(answer).to.equal("foo");
done();
});
rl.emit("line");
});
});
var expect = require("chai").expect;
var sinon = require("sinon");
var utils = require("../../lib/utils/utils");
describe("normalizeChoices", function() {
it("should normalize array containing strings", function() {
var initial = [ "foo", "bar" ];
var normalized = utils.normalizeChoices(initial);
expect(normalized).to.eql([{
name: "foo",
value: "foo"
}, {
name: "bar",
value: "bar"
}]);
});
});
describe("runAsync", function() {
it("should run synchronous functions", function( done ) {
var aFunc = function() {
return "pass1";
};
utils.runAsync(aFunc, function( val ) {
expect(val).to.equal("pass1");
done();
});
});
it("should run synchronous functions", function( done ) {
var aFunc = function() {
var returns = this.async();
returns("pass2");
};
utils.runAsync(aFunc, function( val ) {
expect(val).to.equal("pass2");
done();
});
});
it("should pass single argument", function( done ) {
var aFunc = function( val ) {
expect(val).to.equal("a");
done();
};
utils.runAsync(aFunc, function() {}, "a");
});
it("should apply multiple arguments", function( done ) {
var aFunc = function( val, val2 ) {
expect(val).to.equal("a");
expect(val2).to.equal("b");
done();
};
utils.runAsync(aFunc, function() {}, "a", "b");
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet