aboutsummaryrefslogtreecommitdiffstats
path: root/vnfmarket/src/main/webapp/vnfmarket/node_modules/karma/lib/init/state_machine.js
blob: 3761a65d6f3657d99c3819017776d5a35e60e532 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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