karma
Version:
Spectacular Test Runner for JavaScript.
142 lines (113 loc) • 3.4 kB
JavaScript
var util = require('util')
var EventEmitter = require('events').EventEmitter
var StateMachine = function (rli, colors) {
var questions
var currentQuestion
var answers
var currentOptions
var currentOptionsPointer
var currentQuestionId
var done
EventEmitter.call(this)
var showPrompt = function () {
rli.write(colors.ANSWER)
rli.prompt()
}
this.onKeypress = function (key) {
if (!currentOptions || !key) {
return
}
if (key.name === 'tab' || key.name === 'right' || key.name === 'down') {
this.suggestNextOption()
} else if (key.name === 'left' || key.name === 'up') {
currentOptionsPointer = currentOptionsPointer + currentOptions.length - 2
this.suggestNextOption()
}
if (!key.ctrl && !key.meta && key.name !== 'enter' && key.name !== 'return') {
key.name = 'escape'
}
}
this.suggestNextOption = function () {
if (!currentOptions) {
return
}
currentOptionsPointer = (currentOptionsPointer + 1) % currentOptions.length
rli._deleteLineLeft()
rli._deleteLineRight()
rli.write(currentOptions[currentOptionsPointer])
}
this.kill = function () {
currentOptions = null
currentQuestionId = null
rli.write('\n' + colors.RESET + '\n')
rli.close()
}
this.onLine = function (line) {
if (currentQuestionId) {
rli.write(colors.RESET)
line = line.trim().replace(colors.ANSWER, '').replace(colors.RESET, '')
if (currentOptions) {
currentOptionsPointer = currentOptions.indexOf(line)
if (currentOptionsPointer === -1) {
return
}
}
if (line === '') {
line = null
}
if (currentQuestion.boolean) {
line = (line === 'yes' || line === 'true' || line === 'on')
}
if (line !== null && currentQuestion.validate) {
currentQuestion.validate(line)
}
if (currentQuestion.multiple) {
answers[currentQuestionId] = answers[currentQuestionId] || []
if (line !== null) {
answers[currentQuestionId].push(line)
showPrompt()
if (currentOptions) {
currentOptions.splice(currentOptionsPointer, 1)
currentOptionsPointer = -1
}
} else {
this.nextQuestion()
}
} else {
answers[currentQuestionId] = line
this.nextQuestion()
}
}
}
this.nextQuestion = function () {
currentQuestion = questions.shift()
while (currentQuestion && currentQuestion.condition && !currentQuestion.condition(answers)) {
currentQuestion = questions.shift()
}
this.emit('next_question', currentQuestion)
if (currentQuestion) {
currentQuestionId = null
rli.write('\n' + colors.question(currentQuestion.question) + '\n')
rli.write(currentQuestion.hint + '\n')
showPrompt()
currentOptions = currentQuestion.options || null
currentOptionsPointer = -1
currentQuestionId = currentQuestion.id
this.suggestNextOption()
} else {
currentQuestionId = null
currentOptions = null
// end
this.kill()
done(answers)
}
}
this.process = function (_questions, _done) {
questions = _questions
answers = {}
done = _done
this.nextQuestion()
}
}
util.inherits(StateMachine, EventEmitter)
module.exports = StateMachine