mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
REPL tests based on direct interaction with input and output stream. Includes multiline tests.
This commit is contained in:
parent
537c5f4b70
commit
47bd05e9a0
4 changed files with 74 additions and 37 deletions
1
Cakefile
1
Cakefile
|
@ -172,6 +172,7 @@ runTests = (CoffeeScript) ->
|
|||
|
||||
# Convenience aliases.
|
||||
global.CoffeeScript = CoffeeScript
|
||||
global.Repl = require './lib/coffee-script/repl'
|
||||
|
||||
# Our test helper function for delimiting different test cases.
|
||||
global.test = (description, fn) ->
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
rli.prompt(true);
|
||||
return;
|
||||
}
|
||||
if (!rli.line.match(/^\s*$/)) {
|
||||
if (!((rli.line == null) || rli.line.match(/^\s*$/))) {
|
||||
return;
|
||||
}
|
||||
multiline.enabled = !multiline.enabled;
|
||||
|
|
|
@ -54,7 +54,7 @@ addMultilineHandler = (repl) ->
|
|||
rli.prompt true
|
||||
return
|
||||
# no-op unless the current line is empty
|
||||
return unless rli.line.match /^\s*$/
|
||||
return unless not rli.line? or rli.line.match /^\s*$/
|
||||
# eval, print, loop
|
||||
multiline.enabled = not multiline.enabled
|
||||
rli.line = ''
|
||||
|
|
106
test/repl.coffee
106
test/repl.coffee
|
@ -1,46 +1,82 @@
|
|||
# REPL
|
||||
# ----
|
||||
Stream = require 'stream'
|
||||
|
||||
# TODO: add more tests
|
||||
{spawn} = require 'child_process'
|
||||
PROMPT = 'coffee> '
|
||||
class MockInputStream extends Stream
|
||||
constructor: () ->
|
||||
@readable = true
|
||||
|
||||
testOutput = (expected, actual) ->
|
||||
eq expected, actual.slice(0, expected.length)
|
||||
actual.substr expected.length
|
||||
resume: ->
|
||||
|
||||
testCommands = (input, expectedOutput) ->
|
||||
input = [input] if typeof input is 'string'
|
||||
expectedOutput = [expectedOutput] if typeof expectedOutput in ['string', 'undefined']
|
||||
output = ''
|
||||
coffee = spawn 'bin/coffee'
|
||||
input.push 'process.exit()'
|
||||
emitLine: (val) ->
|
||||
@emit 'data', new Buffer("#{val}\n")
|
||||
|
||||
coffee.stdout.on 'data', (data) ->
|
||||
output += data.toString().replace(/\u001b\[\d{0,2}m/g, '')
|
||||
coffee.stdin.write "#{input.shift()}\n"
|
||||
class MockOutputStream extends Stream
|
||||
constructor: () ->
|
||||
@writable = true
|
||||
@written = []
|
||||
|
||||
coffee.on 'exit', ->
|
||||
output = testOutput PROMPT, output
|
||||
while expectedOutput.length > 0
|
||||
output = testOutput "#{expectedOutput.shift()}\n#{PROMPT}", output
|
||||
eq '', output
|
||||
write: (data) ->
|
||||
#console.log 'output write', arguments
|
||||
@written.push data
|
||||
|
||||
test "comments are ignored", ->
|
||||
testCommands "1 + 1 #foo", "2"
|
||||
lastWrite: (fromEnd=-1) ->
|
||||
@written[@written.length - 1 + fromEnd].replace /\n$/, ''
|
||||
|
||||
test "output in inspect mode", ->
|
||||
testCommands '"1 + 1\\n"', "'1 + 1\\n'"
|
||||
testRepl = (desc, fn) ->
|
||||
input = new MockInputStream()
|
||||
output = new MockOutputStream()
|
||||
Repl.start {input, output}
|
||||
fn input, output
|
||||
|
||||
test "variables are saved", ->
|
||||
input = [
|
||||
"foo = 'foo'"
|
||||
'foobar = "#{foo}bar"'
|
||||
]
|
||||
testCommands input, [
|
||||
"'foo'"
|
||||
"'foobar'"
|
||||
]
|
||||
assertEqual = (expected, value) ->
|
||||
eq expected, value, "Expected '#{value}' to equal '#{expected}'"
|
||||
|
||||
test "empty command evaluates to undefined", ->
|
||||
testCommands "", undefined
|
||||
|
||||
testRepl "starts with coffee prompt", (input, output) ->
|
||||
assertEqual 'coffee> ', output.lastWrite(0)
|
||||
|
||||
testRepl "writes eval to output", (input, output) ->
|
||||
input.emitLine '1+1'
|
||||
assertEqual '2', output.lastWrite()
|
||||
|
||||
testRepl "comments are ignored", (input, output) ->
|
||||
input.emitLine '1 + 1 #foo'
|
||||
assertEqual '2', output.lastWrite()
|
||||
|
||||
testRepl "output in inspect mode", (input, output) ->
|
||||
input.emitLine '"1 + 1\\n"'
|
||||
assertEqual "'1 + 1\\n'", output.lastWrite()
|
||||
|
||||
testRepl "variables are saved", (input, output) ->
|
||||
input.emitLine "foo = 'foo'"
|
||||
input.emitLine 'foobar = "#{foo}bar"'
|
||||
assertEqual "'foobar'", output.lastWrite()
|
||||
|
||||
testRepl "empty command evaluates to undefined", (input, output) ->
|
||||
input.emitLine ''
|
||||
assertEqual 'undefined', output.lastWrite()
|
||||
|
||||
ctrlV = { ctrl: true, name: 'v'}
|
||||
testRepl "ctrl-v toggles multiline prompt", (input, output) ->
|
||||
input.emit 'keypress', null, ctrlV
|
||||
assertEqual '------> ', output.lastWrite(0)
|
||||
input.emit 'keypress', null, ctrlV
|
||||
assertEqual 'coffee> ', output.lastWrite(0)
|
||||
|
||||
testRepl "multiline continuation changes prompt", (input, output) ->
|
||||
input.emit 'keypress', null, ctrlV
|
||||
input.emitLine ''
|
||||
assertEqual '....... ', 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 '(->'
|
||||
input.emitLine ' 1 + 1'
|
||||
input.emitLine ')()'
|
||||
input.emit 'keypress', null, ctrlV
|
||||
assertEqual '2', output.lastWrite()
|
||||
|
|
Loading…
Add table
Reference in a new issue