Usage
@qio/console provides a list of testable terminal based utilities such as getStrLn and putStrLn that abstract out the dependency on stdin and stdout streams.
Prerequisite reading: Getting Started.
Printing on the screen
The following program would simply print Welcome on the screen.
+ import {putStrLn} from '@qio/console'
+
+ const program = putStrLn('Welcome')
Taking user input
User input can be taken using getStrLn.
- import {putStrLn} from '@qio/console'
+ import {putStrLn, getStrLn} from '@qio/console'
- const program = putStrLn('Welcome')
+ const program = getStrLn('Enter name: ')
+ .chain(name => putStrLn('Welcome', name))
Environment Requirements
By default getStrLn and putStrLn have a dependency on ITextTerminalEnv. Because of this dependency, the program is of type: QIO<void, never, ITextTerminalEnv>.
The default env is shipped with @qio/console as TTY and can be used as follows:
- import {putStrLn, getStrLn} from '@qio/console'
+ import {putStrLn, getStrLn, TTY} from '@qio/console'
const program = getStrLn('Enter name: ')
.chain(name => putStrLn('Welcome', name))
+ .provide({tty: TTY})
Above TTY is of type ITextTerminalEnv.
Running the program
import {putStrLn, getStrLn, TTY} from '@qio/console'
+ import {defaultRuntime} from '@qio/core'
const program = getStrLn('Enter name: ')
.chain(name => putStrLn('Welcome', name))
.provide({tty: TTY})
+ defaultRuntime().unsafeExecute(program)
program can be executed like any other QIO using the defaultRuntime.
Using Test Env
QIO allows passing of mock ITextTerminalEnv.
- import {putStrLn, getStrLn, TTY} from '@qio/console'
+ import {putStrLn, getStrLn, testTTY} from '@qio/console'
- import {defaultRuntime} from '@qio/core'
+ const testTTYEnv = testTTY()
const program = getStrLn('Enter name: ')
.chain(name => putStrLn('Welcome', name))
- .provide({tty: TTY})
+ .provide({tty: testTTYEnv})
defaultRuntime().unsafeExecute(program)
Instead of using TTY we use testTTY function to create a mock ITextTerminal.
Add mock input
Mock responses can be added using testTTY() as key value pairs.
import {putStrLn, getStrLn, testTTY} from '@qio/console'
- import {defaultRuntime} from '@qio/core'
+ import {QIO, defaultRuntime} from '@qio/core'
+ const mockInput = {
+ 'Enter name: ': QIO.resolve('Bob')
+ }
+
- const testTTYEnv = testTTY()
+ const testTTYEnv = testTTY(mockInput)
const program = getStrLn('Enter name: ')
.chain(name => putStrLn('Welcome', name))
.provide({tty: testTTYEnv})
defaultRuntime().unsafeExecute(program)
Running the program will automatically input Bob when the name is asked.
Using Test Runtime
Replacing the defaultRuntime with testRuntime will allow synchronous evaluation of the program:
import {putStrLn, getStrLn, testTTY} from '@qio/console'
- import {QIO, defaultRuntime} from '@qio/core'
+ import {QIO, testRuntime} from '@qio/core'
+ import * as assert from 'assert'
const mockInput = {
'Enter name: ': QIO.resolve('Bob')
}
const testTTYEnv = testTTY(mockInput)
const program = getStrLn('Enter name: ')
.chain(name => putStrLn('Welcome', name))
.provide({tty: testTTYEnv})
- defaultRuntime().unsafeExecute(program)
+ testRuntime().unsafeExecuteSync(program)
Asserting the output
import {QIO, testRuntime} from '@qio/core'
+ import * as assert from 'assert'
const mockInput = {
'Enter name: ': QIO.resolve('Bob')
}
const testTTYEnv = testTTY(mockInput)
const program = getStrLn('Enter name: ')
.chain(name => putStrLn('Welcome', name))
.provide({tty: testTTYEnv})
testRuntime().unsafeExecuteSync(program)
+
+ const actual = testTTYEnv.stdout
+ const expected = [
+ 'Enter name: Bob',
+ 'Welcome Bob'
+ ]
+
+ assert.deepStrictEqual(actual, expected)
The stdout property is only available in the env created by testEnv. This is used mainly to assert what's being outputted on the terminal.