PageRenderTime 32ms CodeModel.GetById 18ms app.highlight 10ms RepoModel.GetById 2ms app.codeStats 0ms

/test/repl.coffee

http://github.com/jashkenas/coffee-script
CoffeeScript | 140 lines | 100 code | 31 blank | 9 comment | 2 complexity | 89d9865ed6b30b5a41237767a92a997f MD5 | raw file
  1return if global.testingBrowser
  2
  3os = require 'os'
  4fs = require 'fs'
  5path = require 'path'
  6
  7# REPL
  8# ----
  9Stream = require 'stream'
 10
 11class MockInputStream extends Stream
 12  constructor: ->
 13    super()
 14    @readable = true
 15
 16  resume: ->
 17
 18  emitLine: (val) ->
 19    @emit 'data', Buffer.from("#{val}\n")
 20
 21class MockOutputStream extends Stream
 22  constructor: ->
 23    super()
 24    @writable = true
 25    @written = []
 26
 27  write: (data) ->
 28    # console.log 'output write', arguments
 29    @written.push data
 30
 31  lastWrite: (fromEnd = -1) ->
 32    @written[@written.length - 1 + fromEnd].replace /\r?\n$/, ''
 33
 34# Create a dummy history file
 35historyFile = path.join os.tmpdir(), '.coffee_history_test'
 36fs.writeFileSync historyFile, '1 + 2\n'
 37
 38testRepl = (desc, fn) ->
 39  input = new MockInputStream
 40  output = new MockOutputStream
 41  repl = Repl.start {input, output, historyFile}
 42  test desc, -> fn input, output, repl
 43
 44ctrlV = { ctrl: true, name: 'v'}
 45
 46
 47testRepl 'reads history file', (input, output, repl) ->
 48  input.emitLine repl.history[0]
 49  eq '3', output.lastWrite()
 50
 51testRepl "starts with coffee prompt", (input, output) ->
 52  eq 'coffee> ', output.lastWrite(0)
 53
 54testRepl "writes eval to output", (input, output) ->
 55  input.emitLine '1+1'
 56  eq '2', output.lastWrite()
 57
 58testRepl "comments are ignored", (input, output) ->
 59  input.emitLine '1 + 1 #foo'
 60  eq '2', output.lastWrite()
 61
 62testRepl "output in inspect mode", (input, output) ->
 63  input.emitLine '"1 + 1\\n"'
 64  eq "'1 + 1\\n'", output.lastWrite()
 65
 66testRepl "variables are saved", (input, output) ->
 67  input.emitLine "foo = 'foo'"
 68  input.emitLine 'foobar = "#{foo}bar"'
 69  eq "'foobar'", output.lastWrite()
 70
 71testRepl "empty command evaluates to undefined", (input, output) ->
 72  # A regression fixed in Node 5.11.0 broke the handling of pressing enter in
 73  # the Node REPL; see https://github.com/nodejs/node/pull/6090 and
 74  # https://github.com/jashkenas/coffeescript/issues/4502.
 75  # Just skip this test for versions of Node < 6.
 76  return if parseInt(process.versions.node.split('.')[0], 10) < 6
 77  input.emitLine ''
 78  eq 'undefined', output.lastWrite()
 79
 80testRepl "#4763: comment evaluates to undefined", (input, output) ->
 81  input.emitLine '# comment'
 82  eq 'undefined', output.lastWrite()
 83
 84testRepl "#4763: multiple comments evaluate to undefined", (input, output) ->
 85  input.emitLine '### a ### ### b ### # c'
 86  eq 'undefined', output.lastWrite()
 87
 88testRepl "ctrl-v toggles multiline prompt", (input, output) ->
 89  input.emit 'keypress', null, ctrlV
 90  eq '------> ', output.lastWrite(0)
 91  input.emit 'keypress', null, ctrlV
 92  eq 'coffee> ', output.lastWrite(0)
 93
 94testRepl "multiline continuation changes prompt", (input, output) ->
 95  input.emit 'keypress', null, ctrlV
 96  input.emitLine ''
 97  eq '....... ', output.lastWrite(0)
 98
 99testRepl "evaluates multiline", (input, output) ->
100  # Stubs. Could assert on their use.
101  output.cursorTo = (pos) ->
102  output.clearLine = ->
103
104  input.emit 'keypress', null, ctrlV
105  input.emitLine 'do ->'
106  input.emitLine '  1 + 1'
107  input.emit 'keypress', null, ctrlV
108  eq '2', output.lastWrite()
109
110testRepl "variables in scope are preserved", (input, output) ->
111  input.emitLine 'a = 1'
112  input.emitLine 'do -> a = 2'
113  input.emitLine 'a'
114  eq '2', output.lastWrite()
115
116testRepl "existential assignment of previously declared variable", (input, output) ->
117  input.emitLine 'a = null'
118  input.emitLine 'a ?= 42'
119  eq '42', output.lastWrite()
120
121testRepl "keeps running after runtime error", (input, output) ->
122  input.emitLine 'a = b'
123  input.emitLine 'a'
124  eq 'undefined', output.lastWrite()
125
126testRepl "#4604: wraps an async function", (input, output) ->
127  return unless try new Function 'async () => {}' # Feature detect support for async functions.
128  input.emitLine 'await new Promise (resolve) -> setTimeout (-> resolve 33), 10'
129  setTimeout ->
130    eq '33', output.lastWrite()
131  , 20
132
133testRepl "transpile REPL", (input, output) ->
134  input.emitLine 'require("./test/importing/transpile_import").getSep()'
135  eq "'#{path.sep.replace '\\', '\\\\'}'", output.lastWrite()
136
137process.on 'exit', ->
138  try
139    fs.unlinkSync historyFile
140  catch exception # Already deleted, nothing else to do.