Files
neovim/test/unit/helpers.moon
2014-07-30 18:25:43 -04:00

132 lines
3.4 KiB
Plaintext

ffi = require 'ffi'
lpeg = require 'lpeg'
formatc = require 'test.unit.formatc'
Set = require 'test.unit.set'
Preprocess = require 'test.unit.preprocess'
Paths = require 'test.config.paths'
-- add some standard header locations
for i,p in ipairs(Paths.include_paths)
Preprocess.add_to_include_path(p)
-- load neovim shared library
libnvim = ffi.load Paths.test_libnvim_path
trim = (s) ->
s\match'^%s*(.*%S)' or ''
-- a Set that keeps around the lines we've already seen
export cdefs
if cdefs == nil
cdefs = Set!
export imported
if imported == nil
imported = Set!
-- some things are just too complex for the LuaJIT C parser to digest. We
-- usually don't need them anyway.
filter_complex_blocks = (body) ->
result = {}
for line in body\gmatch("[^\r\n]+")
-- remove all lines that contain Objective-C block syntax, the LuaJIT ffi
-- doesn't understand it.
if string.find(line, "(^)", 1, true) ~= nil
continue
if string.find(line, "_ISwupper", 1, true) ~= nil
continue
result[#result + 1] = line
table.concat(result, "\n")
-- use this helper to import C files, you can pass multiple paths at once,
-- this helper will return the C namespace of the nvim library.
-- cimport = (path) ->
cimport = (...) ->
-- filter out paths we've already imported
paths = [path for path in *{...} when not imported\contains(path)]
for path in *paths
imported\add(path)
if #paths == 0
return libnvim
-- preprocess the header
stream = Preprocess.preprocess_stream(unpack(paths))
body = stream\read("*a")
stream\close!
-- format it (so that the lines are "unique" statements), also filter out
-- Objective-C blocks
body = formatc(body)
body = filter_complex_blocks(body)
-- add the formatted lines to a set
new_cdefs = Set!
for line in body\gmatch("[^\r\n]+")
new_cdefs\add(trim(line))
-- subtract the lines we've already imported from the new lines, then add
-- the new unique lines to the old lines (so they won't be imported again)
new_cdefs\diff(cdefs)
cdefs\union(new_cdefs)
if new_cdefs\size! == 0
-- if there's no new lines, just return
return libnvim
-- request a sorted version of the new lines (same relative order as the
-- original preprocessed file) and feed that to the LuaJIT ffi
new_lines = new_cdefs\to_table!
ffi.cdef(table.concat(new_lines, "\n"))
return libnvim
cppimport = (path) ->
return cimport Paths.test_include_path .. '/' .. path
cimport './src/nvim/types.h'
-- take a pointer to a C-allocated string and return an interned
-- version while also freeing the memory
internalize = (cdata, len) ->
ffi.gc cdata, ffi.C.free
return ffi.string cdata, len
cstr = ffi.typeof 'char[?]'
to_cstr = (string) ->
cstr (string.len string) + 1, string
export vim_init_called
-- initialize some global variables, this is still necessary to unit test
-- functions that rely on global state.
vim_init = ->
if vim_init_called ~= nil
return
-- import os_unix.h for mch_early_init(), which initializes some globals
os = cimport './src/nvim/os_unix.h'
os.mch_early_init!
vim_init_called = true
-- C constants.
NULL = ffi.cast 'void*', 0
OK = 1
FAIL = 0
return {
cimport: cimport
cppimport: cppimport
internalize: internalize
eq: (expected, actual) -> assert.are.same expected, actual
neq: (expected, actual) -> assert.are_not.same expected, actual
ffi: ffi
lib: libnvim
cstr: cstr
to_cstr: to_cstr
vim_init: vim_init
NULL: NULL
OK: OK
FAIL: FAIL
}