summaryrefslogtreecommitdiff
path: root/test/plugins/ffi
diff options
context:
space:
mode:
authorfesily <fesil@foxmail.com>2023-05-12 15:23:05 +0800
committerfesily <fesil@foxmail.com>2023-05-12 15:23:05 +0800
commitbb4558c1a2ecba1b345de9f6a0b238022ecebfee (patch)
tree996f9fc358a2ccf1bc9fe7fbc3b7107d0ba16fed /test/plugins/ffi
parent86dcb1a7e5eed8cf2e1b7109b4c0debf6967c485 (diff)
downloadlua-language-server-bb4558c1a2ecba1b345de9f6a0b238022ecebfee.zip
rename test
Diffstat (limited to 'test/plugins/ffi')
-rw-r--r--test/plugins/ffi/builder.lua181
-rw-r--r--test/plugins/ffi/cdef.lua61
-rw-r--r--test/plugins/ffi/init.lua37
-rw-r--r--test/plugins/ffi/parser.lua150
4 files changed, 429 insertions, 0 deletions
diff --git a/test/plugins/ffi/builder.lua b/test/plugins/ffi/builder.lua
new file mode 100644
index 00000000..47e39db3
--- /dev/null
+++ b/test/plugins/ffi/builder.lua
@@ -0,0 +1,181 @@
+local ffi = require 'plugins.ffi'
+local util = require 'utility'
+rawset(_G, 'TEST', true)
+
+local function removeEmpty(lines)
+ local removeLines = {}
+ for i, v in ipairs(lines) do
+ if v ~= '\n' then
+ removeLines[#removeLines+1] = v:gsub('^%s+', '')
+ end
+ end
+ return removeLines
+end
+
+local function formatLines(lines)
+ if not lines or #lines == 0 then
+ return {}
+ end
+ table.remove(lines, 1)
+ return removeEmpty(lines)
+end
+
+---@param str string
+local function splitLines(str)
+ local lines = {}
+ local i = 1
+ for line in str:gmatch("[^\r\n]+") do
+ lines[i] = line
+ i = i + 1
+ end
+ return lines
+end
+
+function TEST(wanted)
+ wanted = removeEmpty(splitLines(wanted))
+ return function (script)
+ local lines = formatLines(ffi.compileCodes({ script }))
+ assert(util.equal(wanted, lines), util.dump(lines))
+ end
+end
+
+TEST [[
+ m.B = 5
+ m.A = 0
+ m.D = 7
+ m.C = 6
+]] [[
+ enum {
+ A,
+ B=5,
+ C,
+ D,
+ };
+]]
+
+TEST [[
+ m.B = 2
+ m.A = 1
+ m.C = 5
+ ---@alias ffi.namespace*.enum@a 1 | 2 | 'B' | 'A' | 5 | 'C'
+]][[
+ enum a {
+ A = 1,
+ B = 2,
+ C = A|B+2,
+ };
+]]
+
+TEST [[
+ ---@param a boolean
+ ---@param b boolean
+ ---@param c integer
+ ---@param d integer
+ function m.test(a, b, c, d) end
+]] [[
+ void test(bool a, _Bool b, size_t c, ssize_t d);
+]]
+
+TEST [[
+ ---@param a integer
+ ---@param b integer
+ ---@param c integer
+ ---@param d integer
+ function m.test(a, b, c, d) end
+]] [[
+ void test(int8_t a, int16_t b, int32_t c, int64_t d);
+]]
+
+TEST [[
+ ---@param a integer
+ ---@param b integer
+ ---@param c integer
+ ---@param d integer
+ function m.test(a, b, c, d) end
+]] [[
+ void test(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
+]]
+
+TEST [[
+ ---@param a integer
+ ---@param b integer
+ ---@param c integer
+ ---@param d integer
+ function m.test(a, b, c, d) end
+]] [[
+ void test(unsigned char a, unsigned short b, unsigned long c, unsigned int d);
+]]
+
+TEST [[
+ ---@param a integer
+ ---@param b integer
+ ---@param c integer
+ ---@param d integer
+ function m.test(a, b, c, d) end
+]] [[
+ void test(unsigned char a, unsigned short b, unsigned long c, unsigned int d);
+]]
+
+TEST [[
+ ---@param a integer
+ ---@param b integer
+ ---@param c integer
+ ---@param d integer
+ function m.test(a, b, c, d) end
+]] [[
+ void test(signed char a, signed short b, signed long c, signed int d);
+]]
+
+TEST [[
+ ---@param a integer
+ ---@param b integer
+ ---@param c integer
+ ---@param d integer
+ function m.test(a, b, c, d) end
+]] [[
+ void test(char a, short b, long c, int d);
+]]
+
+TEST [[
+ ---@param a number
+ ---@param b number
+ ---@param c integer
+ ---@param d integer
+ function m.test(a, b, c, d) end
+]] [[
+ void test(float a, double b, int8_t c, uint8_t d);
+]]
+
+TEST [[
+ ---@alias H ffi.namespace*.void
+
+ function m.test() end
+]] [[
+ typedef void H;
+
+ H test();
+]]
+
+TEST [[
+ ---@class ffi.namespace*.a
+
+ ---@param a ffi.namespace*.a
+ function m.test(a) end
+]] [[
+ typedef struct {} a;
+
+ void test(a* a);
+]]
+
+TEST [[
+ ---@class ffi.namespace*.struct@a
+ ---@field a integer
+ ---@field b ffi.namespace*.char*
+
+ ---@param a ffi.namespace*.struct@a
+ function m.test(a) end
+]] [[
+ struct a {int a;char* b;};
+
+ void test(struct a* a);
+]]
diff --git a/test/plugins/ffi/cdef.lua b/test/plugins/ffi/cdef.lua
new file mode 100644
index 00000000..cf3992d3
--- /dev/null
+++ b/test/plugins/ffi/cdef.lua
@@ -0,0 +1,61 @@
+
+local files = require 'files'
+local code = require 'plugins.ffi.searchCode'
+local cdefRerence = require 'plugins.ffi.cdefRerence'
+
+rawset(_G, 'TEST', true)
+
+function TEST(wanted)
+ ---@async
+ return function (script)
+ files.setText(TESTURI, script)
+ local codeResults = code(cdefRerence(), TESTURI)
+ assert(codeResults)
+ table.sort(codeResults)
+ assert(table.concat(codeResults, '|') == wanted, table.concat(codeResults, '|') .. ' ~= ' .. wanted)
+ files.remove(TESTURI)
+ end
+end
+
+TEST 'aaa|bbb' [[
+local ffi = require 'ffi'
+local cdef = ffi.cdef
+cdef('aaa')
+cdef = function ()
+end
+cdef('bbb')
+]]
+
+TEST 'aaa' [[
+local ffi = require 'ffi'
+
+ffi.cdef('aaa')
+]]
+
+TEST 'aa.aa' [[
+local ffi = require 'ffi'
+local t1 = ffi
+
+t1.cdef"aa.aa"
+]]
+
+TEST 'aaa' [[
+local ffi = require 'ffi'
+local code = 'aaa'
+ffi.cdef(code)
+]]
+
+TEST 'aaa|bbb' [[
+local ffi = require 'ffi'
+local code = 'aaa'
+code = 'bbb'
+local t1 = ffi
+t1.cdef(code)
+]]
+
+TEST 'aa.aa' [[
+local ffi = require 'ffi'
+local cdef = ffi.cdef
+
+cdef"aa.aa"
+]]
diff --git a/test/plugins/ffi/init.lua b/test/plugins/ffi/init.lua
new file mode 100644
index 00000000..2a232192
--- /dev/null
+++ b/test/plugins/ffi/init.lua
@@ -0,0 +1,37 @@
+local lclient = require 'lclient'
+local ws = require 'workspace'
+local furi = require 'file-uri'
+local files = require 'files'
+
+--TODO how to changed the runtime version?
+local template = require 'config.template'
+
+template['Lua.runtime.version'].default = 'LuaJIT'
+
+
+---@async
+local function TestBuilder()
+ local builder = require 'plugins.ffi'.initBuilder()
+ files.setText(TESTURI, [[
+ local ffi = require 'ffi'
+ ffi.cdef 'void test();'
+ ]])
+
+ builder(TESTURI)
+end
+
+---@async
+lclient():start(function (languageClient)
+ languageClient:registerFakers()
+ local rootUri = furi.encode '/'
+ languageClient:initialize {
+ rootUri = rootUri,
+ }
+
+ ws.awaitReady(rootUri)
+
+ require 'plugins.ffi.cdef'
+ require 'plugins.ffi.parser'
+ require 'plugins.ffi.builder'
+ TestBuilder()
+end)
diff --git a/test/plugins/ffi/parser.lua b/test/plugins/ffi/parser.lua
new file mode 100644
index 00000000..983b64c3
--- /dev/null
+++ b/test/plugins/ffi/parser.lua
@@ -0,0 +1,150 @@
+local utility = require 'utility'
+local cdriver = require 'plugins.ffi.c-parser.cdriver'
+
+rawset(_G, 'TEST', true)
+local ctypes = require 'plugins.ffi.c-parser.ctypes'
+ctypes.TESTMODE = true
+
+function TEST(wanted, full)
+ return function (script)
+ local rrr = cdriver.process_context(script .. "$EOF$")
+ assert(rrr)
+ if full then
+ for i, v in ipairs(rrr) do
+ assert(utility.equal(v, wanted[i]))
+ end
+ else
+ assert(utility.equal(rrr[1], wanted))
+ end
+ end
+end
+
+
+TEST {
+ name = 'union@a',
+ type = {
+ name = 'a',
+ type = 'union',
+ fields = {
+ { name = 'b', type = { 'int' } },
+ { name = 'c', type = { 'int8_t' } }
+ }
+ }
+} [[
+ union a{
+ int b;
+ int8_t c;
+ };
+]]
+
+TEST {
+ name = 'union@a',
+ type = {
+ name = 'a',
+ type = 'union',
+ }
+} [[
+ union a{};
+]]
+
+TEST {
+ name = 'enum@anonymous',
+ type = {
+ type = 'enum',
+ values = {
+ { name = 'a', value = { '1' } },
+ { name = 'b', value = { 'a' } },
+ }
+ }
+} [[
+ enum {
+ a = 1,
+ b = a,
+ };
+]]
+
+TEST {
+ name = 'enum@a',
+ type = {
+ name = 'a',
+ type = 'enum',
+ values = {
+ { name = 'b', value = { op = '|', { '1' }, { '2' } } },
+ }
+ }
+} [[
+ enum a{
+ b = 1|2,
+ };
+]]
+
+TEST {
+ name = 'enum@a',
+ type = {
+ name = 'a',
+ type = 'enum',
+ }
+} [[
+ enum a{};
+]]
+
+TEST {
+ name = 'struct@a',
+ type = {
+ name = 'a',
+ type = 'struct',
+ fields = {
+ { name = 'f', type = { 'int' } },
+ { name = 'b', type = { 'int', '*', '*' } }
+ }
+ }
+} [[
+ struct a {int f,**b;};
+]]
+
+TEST {
+ name = 'struct@a',
+ type = {
+ name = 'a',
+ type = 'struct',
+ fields = {
+ { name = 'f', type = { 'int' } },
+ }
+ }
+} [[
+ struct a {int f;};
+]]
+
+TEST({
+ { name = "struct@anonymous", type = { type = 'struct' } },
+ {
+ name = 'a',
+ type = {
+ name = 'a',
+ type = 'typedef',
+ def = {
+ { type = 'struct', }
+ }
+ }
+ }
+}, true) [[
+ typedef struct {} a;
+]]
+
+TEST {
+ name = 'a',
+ type = {
+ name = 'a',
+ type = 'function',
+ params = {
+ { type = { 'int' }, name = 'b' },
+ },
+ ret = {
+ type = { 'int' }
+ },
+ vararg = false
+ },
+
+} [[
+ int a(int b);
+]]