1
0
Fork 0
mirror of https://github.com/jashkenas/coffeescript.git synced 2022-11-09 12:23:24 -05:00
jashkenas--coffeescript/test/repl.coffee
Geoffrey Booth 3108244c20 Fix stack trace (#4428)
* Revert aee27fbff0

* Patch Jison’s output so that it requires `fs` only if we’re truly in a CommonJS/Node environment, not a browser environment that may happen to have globals named `require` and `exports` (as would be the case if require.js is being used). Fixes #4391.

* Temporary fix for exceptions getting thrown when trying to generate a stack trace for a file that has been deleted since compilation; fixes #3890, but not well. A better solution would not try to recompile the file when trying to retrieve its stack trace.

* Save the test REPL history in the system temp folder, not in the CoffeeScript project folder

* Rewrite `getSourceMap` to never read a file from disk, and therefore not throw IO-related exceptions; source maps are either retrieved from memory, or the related source code is retrieved from memory to generate a new source map. Fixes #3890 the proper way.

* Add test to verify that stack traces reference the correct line number. Closes #4418.

* Get the parser working in the browser compiler again; rather than detecting a CommonJS environment generally, just check for `fs` before trying to use it

* Follow Node’s standard of 4-space indentation of stack trace data

* Better .gitignore

* Fix caching of compiled code and source maps; add more tests to verify correct line numbers in stack traces

* Better fallback value for the parser source

* Fix the stack traces and tests when running in a browser

* Update the browser compiler so that @murrayju doesn’t have any extra work to do to test this branch
2017-01-22 13:20:18 -08:00

112 lines
2.9 KiB
CoffeeScript

return if global.testingBrowser
os = require 'os'
fs = require 'fs'
path = require 'path'
# REPL
# ----
Stream = require 'stream'
class MockInputStream extends Stream
constructor: ->
@readable = true
resume: ->
emitLine: (val) ->
@emit 'data', new Buffer("#{val}\n")
class MockOutputStream extends Stream
constructor: ->
@writable = true
@written = []
write: (data) ->
#console.log 'output write', arguments
@written.push data
lastWrite: (fromEnd = -1) ->
@written[@written.length - 1 + fromEnd].replace /\r?\n$/, ''
# Create a dummy history file
historyFile = path.join os.tmpdir(), '.coffee_history_test'
fs.writeFileSync historyFile, '1 + 2\n'
testRepl = (desc, fn) ->
input = new MockInputStream
output = new MockOutputStream
repl = Repl.start {input, output, historyFile}
test desc, -> fn input, output, repl
ctrlV = { ctrl: true, name: 'v'}
testRepl 'reads history file', (input, output, repl) ->
input.emitLine repl.rli.history[0]
eq '3', output.lastWrite()
testRepl "starts with coffee prompt", (input, output) ->
eq 'coffee> ', output.lastWrite(0)
testRepl "writes eval to output", (input, output) ->
input.emitLine '1+1'
eq '2', output.lastWrite()
testRepl "comments are ignored", (input, output) ->
input.emitLine '1 + 1 #foo'
eq '2', output.lastWrite()
testRepl "output in inspect mode", (input, output) ->
input.emitLine '"1 + 1\\n"'
eq "'1 + 1\\n'", output.lastWrite()
testRepl "variables are saved", (input, output) ->
input.emitLine "foo = 'foo'"
input.emitLine 'foobar = "#{foo}bar"'
eq "'foobar'", output.lastWrite()
testRepl "empty command evaluates to undefined", (input, output) ->
input.emitLine ''
eq 'undefined', output.lastWrite()
testRepl "ctrl-v toggles multiline prompt", (input, output) ->
input.emit 'keypress', null, ctrlV
eq '------> ', output.lastWrite(0)
input.emit 'keypress', null, ctrlV
eq 'coffee> ', output.lastWrite(0)
testRepl "multiline continuation changes prompt", (input, output) ->
input.emit 'keypress', null, ctrlV
input.emitLine ''
eq '....... ', output.lastWrite(0)
testRepl "evaluates multiline", (input, output) ->
# Stubs. Could assert on their use.
output.cursorTo = (pos) ->
output.clearLine = ->
input.emit 'keypress', null, ctrlV
input.emitLine 'do ->'
input.emitLine ' 1 + 1'
input.emit 'keypress', null, ctrlV
eq '2', output.lastWrite()
testRepl "variables in scope are preserved", (input, output) ->
input.emitLine 'a = 1'
input.emitLine 'do -> a = 2'
input.emitLine 'a'
eq '2', output.lastWrite()
testRepl "existential assignment of previously declared variable", (input, output) ->
input.emitLine 'a = null'
input.emitLine 'a ?= 42'
eq '42', output.lastWrite()
testRepl "keeps running after runtime error", (input, output) ->
input.emitLine 'a = b'
input.emitLine 'a'
eq 'undefined', output.lastWrite()
process.on 'exit', ->
fs.unlinkSync historyFile