Clone wiki

bluejay / Home

TODO: Quick Lua intro/notes for non-Lua programmers (new page) - Tables (structure; index begins at 1)

Using BlueJay

To build, use Dub: dub build.

To run unit tests: dub test

To run scripts in the test directory: dub run -- ./test

The cleanup() Function

If you create a cleanup() function in a test script, it will automatically be called at the end of the script's execution — even after a failed assertion.

#!/bin/env bluejay
-- Write to a file, then delete it on exit.

function cleanup()
    Util:removeFile('output.txt')
end

Util:writeFile('output.txt', 'hello')

The Library API

The Lua 5.1 base and string libraries are available within tests; please refer to the Lua documentation concerning those functions.

Script Tables

The System Table

The system table contains three rows: OS, Arch, and endl

Possible values for OS:

  • Windows
  • Linux
  • macOS

Possible values for Arch:

  • x86
  • x86_64
  • ARM

System.endl is the line ending character(s) for the system.

print(System.OS)
if (System.Arch == "x86") then
    print("Hello")
end

The Env Table

The Env table provides a read-only view to the system's environment variables at the moment bluejay begins executing the script.

Util:pprint(Env)
print(Env["PATH"]

The Test Object

Test:run

Execute a file or command on the shell and return the standard output and return code.

-- Test:run([executable to run], [OPTIONAL argument list])

local returnValue = Test:run('echo', 'Some text.')
assert(returnValue.ReturnCode == 0)
print(returnValue.Output)

To run an application at a relative path on Windows, add quotation marks. e.g., Test:run('"./bluejay"', 'mytest.bj')

Test:spawn

Execute a file or command on the shell in a new process and return the process ID.

-- Test:spawn([command to run], [OPTIONAL argument list])

local pid = 0
pid = Test:spawn('echo', 'Some text.')
assert(pid > 0)

See the documentation for Test:run for more information.

Test:diff

Similar to the UNIX diff command, but is line-separator agnostic, so you can diff a UNIX text file on Windows. Returns true if the files are the same; otherwise, false.

-- Test:diff([file1], [file2])

assert(Test:diff('file0.txt', 'file1.txt'), 'The files are different.')

Test:throws

Execute the given Lua function and return true if it throws an error, or false otherwise. Note that only functions may be passed; not arbitrary Lua code.

The code must be passed as a string so that throws may evaluate it; if you pass the code itself, Lua will evaluate the function and pass its result to throws.

-- Test:throws([string of function call that may throw])

assert(not Test:throws("print('Some text.')")

Library functions (e.g., Util:strip) cannot currently be passed to throws; wrap them in a global function and pass that instead:

strip = function(str)
    Util:strip(str)
end

assert(not Test:throws('strip(" some string ")'))

The Util Object

Util contains miscellaneous functions useful for writing tests. The following is organized by string handling functions, filesystem functions, and other functions.

Util:split

Splits a string by line into a table of strings.

-- Util:split([string])

local tbl = Util:split("line 1\nline 2")
assert(tbl[1] == "line 1")
assert(tbl[2] == "line 2")

Util:strip

Strips leading and trailing whitespace from the specified string and returns the result.

-- Util:strip([string])

assert(Util:strip("    asdf\t") == "asdf")

Util:copyFile

Copy a file.

-- Util:copyFile([relative-or-absolute path to source], [relative-or-absolute path to destination])

local f = Util:getTempFile()
Util:copyFile(f, './my_new_file')

Util:cwd

Returns the current working directory (generally the project's base directory).

-- Util:cwd()

print(Util:cwd())

Util:dirExists

Returns true if the specified directory exists, false otherwise.

-- Util:dirExists([relative-or-absolute directory path])

assert(Util:dirExists('/'))

Util:fileExists

Returns true if the specified file exists, false otherwise.

-- Util:fileExists([relative-or-absolute file path])

assert(Util:fileExists('some-file.txt'))

Util:fixPath

Fixes UNIX paths for Windows, and Windows paths for Unix (e.g., replaces directory separators).

if System.OS = 'Windows' then
    assert(Util:fixPath('/some/dir') == '\\some\\dir')
    assert(Util:fixPath('/some/dir/' == '\\some\\dir')
else
    assert(Util:fixPath('\\some\\dir') == '/some/dir')
    assert(Util:fixPath('\\some\\dir\\') == '/some/dir')
    assert(Util:fixPath('c:\\some\\dir') == '/some/dir')
end

Util:getTempDir

Creates a directory in the system's temporary directory with a unique name.

-- Util:getTempDir()

local dir = Util:getTempDir()
print(dir)
assert(Util:dirExists(dir))

Util:getTempFile

Creates a file in the system's temporary directory with a unique name.

-- Util:getTempFile()

local file = Util:getTempFile()
print(file)
assert(Util:fileExists(file))

Util:listDir

Lists the contents of the specified directory.

-- Util:listDir([directory], [OPTIONAL filter])

assert(# Util:listDir(Util:cwd()) > 0)
Util:pprint(Util:listDir(Util:cwd(), '*.txt'))

Util:removeDir

Removes a directory and its contents if it exists. Returns true if the directory is then nonexistent, otherwise returns false.

-- Util:removeDir([relative-or-absolute directory path])

Util:removeDir("/tmp/somedir")

Util:removeFile

Removes the specified file. If the file exists after attempting to delete it, returns false; otherwise returns true.

-- Util:removeFile([relative-or-absolute file path])

Util:removeFile("/tmp/some_file")

Util:readFile

Read text from the specified file as a string.

-- Util:readFile([file path])

local text = Util:readFile('some-file.txt')

Util:writeFile

Write text to the specified file. Note that newlines will be system-dependent.

-- Util:writeFile([file path], [text to write])

Util:writeFile('some-file.txt', 'This is text.')

Util:pprint

Pretty-print a Lua table. You can optionally pass a maximum number of levels to print, which can be useful for deeply-nested tables.

-- Util:pprint([some table], [OPTIONAL max-length])

Util:pprint(Env)
t = {"asdf", sdfg={1, 2, 3, 4}, qwer={"asdf", wer={3,4,5,6}}}
Util:pprint(t, 2)

The Script Object

Script:exit

Exits the script, with an optional return code. The cleanup() function is still executed.

Note that the return code is currently ignored.

-- Script:exit([OPTIONAL exit code])

if (System.OS == Windows) then
    Script:exit()
else
    Script:exit(100)
end

Updated