summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/completion/common.lua18
-rw-r--r--test/crossfile/completion.lua31
-rw-r--r--test/crossfile/infer.lua53
-rw-r--r--test/diagnostics/common.lua37
-rw-r--r--test/diagnostics/init.lua37
-rw-r--r--test/diagnostics/type-check.lua121
-rw-r--r--test/hover/init.lua61
-rw-r--r--test/references/all.lua13
-rw-r--r--test/references/common.lua15
-rw-r--r--test/tclient/tests/change-workspace-folder.lua18
-rw-r--r--test/tclient/tests/modify-luarc.lua50
-rw-r--r--test/type_inference/init.lua67
12 files changed, 483 insertions, 38 deletions
diff --git a/test/completion/common.lua b/test/completion/common.lua
index e0668ea3..8d23822a 100644
--- a/test/completion/common.lua
+++ b/test/completion/common.lua
@@ -1006,12 +1006,12 @@ t.<??>
]]
{
{
- label = 'a.b.c',
+ label = "'a.b.c'",
kind = define.CompletionItemKind.Field,
textEdit = {
start = 40002,
finish = 40002,
- newText = '["a.b.c"]',
+ newText = "['a.b.c']",
},
additionalTextEdits = {
{
@@ -1032,12 +1032,12 @@ t. <??>
]]
{
{
- label = 'a.b.c',
+ label = "'a.b.c'",
kind = define.CompletionItemKind.Field,
textEdit = {
start = 40005,
finish = 40005,
- newText = '["a.b.c"]',
+ newText = "['a.b.c']",
},
additionalTextEdits = {
{
@@ -1058,7 +1058,7 @@ t['<??>']
]]
{
{
- label = 'a.b.c',
+ label = "'a.b.c'",
kind = define.CompletionItemKind.Field,
textEdit = {
start = 40003,
@@ -1075,12 +1075,12 @@ z<??>
]]
{
{
- label = 'z.b.c',
+ label = "'z.b.c'",
kind = define.CompletionItemKind.Field,
textEdit = {
start = 20000,
finish = 20001,
- newText = '_ENV["z.b.c"]',
+ newText = "_ENV['z.b.c']",
},
},
}
@@ -1094,12 +1094,12 @@ z<??>
]]
{
{
- label = 'z.b.c',
+ label = "'z.b.c'",
kind = define.CompletionItemKind.Field,
textEdit = {
start = 20000,
finish = 20001,
- newText = '_G["z.b.c"]',
+ newText = "_G['z.b.c']",
},
},
}
diff --git a/test/crossfile/completion.lua b/test/crossfile/completion.lua
index d613f621..113b0327 100644
--- a/test/crossfile/completion.lua
+++ b/test/crossfile/completion.lua
@@ -127,6 +127,37 @@ end
TEST {
{
path = 'abc.lua',
+ content = [[
+ ---@meta
+
+ ---@class A
+ ---@field f1 integer
+ ---@field f2 boolean
+
+ ---@type A[]
+ X = {}
+]],
+ },
+ {
+ path = 'test.lua',
+ content = [[ X[1].<??>]],
+ main = true,
+ },
+ completion = {
+ {
+ label = 'f1',
+ kind = CompletionItemKind.Field,
+ },
+ {
+ label = 'f2',
+ kind = CompletionItemKind.Field,
+ },
+ }
+}
+
+TEST {
+ {
+ path = 'abc.lua',
content = '',
},
{
diff --git a/test/crossfile/infer.lua b/test/crossfile/infer.lua
index 2f2c35ad..de29007b 100644
--- a/test/crossfile/infer.lua
+++ b/test/crossfile/infer.lua
@@ -110,3 +110,56 @@ end
},
infer = 'V',
}
+
+TEST {
+ { path = 'a.lua', content = [[
+X = 1
+X = true
+]], },
+ { path = 'b.lua', content = [[
+print(<?X?>)
+]], },
+ infer = 'integer',
+}
+
+TEST {
+ { path = 'a.lua', content = [[
+---@meta
+X = 1
+X = true
+]], },
+ { path = 'b.lua', content = [[
+print(<?X?>)
+]], },
+ infer = 'boolean|integer',
+}
+
+TEST {
+ { path = 'a.lua', content = [[
+return 1337, "string", true
+]], },
+ { path = 'b.lua', content = [[
+local <?a?>, b, c = require 'a
+]], },
+ infer = 'integer',
+}
+
+TEST {
+ { path = 'a.lua', content = [[
+return 1337, "string", true
+]], },
+ { path = 'b.lua', content = [[
+local a, <?b?>, c = require 'a
+]], },
+ infer = 'unknown',
+}
+
+TEST {
+ { path = 'a.lua', content = [[
+return 1337, "string", true
+]], },
+ { path = 'b.lua', content = [[
+local a, b, <?c?> = require 'a
+]], },
+ infer = 'nil',
+}
diff --git a/test/diagnostics/common.lua b/test/diagnostics/common.lua
index b91380b8..a1dbe819 100644
--- a/test/diagnostics/common.lua
+++ b/test/diagnostics/common.lua
@@ -2231,3 +2231,40 @@ mt.init = function ()
obj.x = 1
end
]]
+
+TEST [[
+---@class A
+X = {}
+
+function <!X.f!>() end
+
+function <!X.f!>() end
+]]
+
+TEST [[
+---@meta
+
+---@class A
+X = {}
+
+function X.f() end
+
+function X.f() end
+]]
+
+TEST [[
+---@class A
+X = {}
+
+if true then
+ function X.f() end
+else
+ function X.f() end
+end
+]]
+
+TESTWITH 'global-in-nil-env' [[
+local function foo(_ENV)
+ Joe = "human"
+end
+]]
diff --git a/test/diagnostics/init.lua b/test/diagnostics/init.lua
index 2d2374a5..827d4d08 100644
--- a/test/diagnostics/init.lua
+++ b/test/diagnostics/init.lua
@@ -27,7 +27,7 @@ local function founded(targets, results)
end
---@diagnostic disable: await-in-sync
-function TEST(script, ...)
+function TEST(script)
local newScript, catched = catch(script, '!')
files.setText(TESTURI, newScript)
files.open(TESTURI)
@@ -47,6 +47,41 @@ function TEST(script, ...)
end
files.remove(TESTURI)
+
+ return function (callback)
+ callback(origins)
+ end
+end
+
+function TESTWITH(code)
+ return function (script)
+ local newScript, catched = catch(script, '!')
+ files.setText(TESTURI, newScript)
+ files.open(TESTURI)
+ local origins = {}
+ local results = {}
+ core(TESTURI, false, function (result)
+ if code ~= result.code then
+ return
+ end
+ results[#results+1] = { result.start, result.finish }
+ origins[#origins+1] = result
+ end)
+
+ if results[1] then
+ if not founded(catched['!'] or {}, results) then
+ error(('%s\n%s'):format(util.dump(catched['!']), util.dump(results)))
+ end
+ else
+ assert(#catched['!'] == 0)
+ end
+
+ files.remove(TESTURI)
+
+ return function (callback)
+ callback(origins)
+ end
+ end
end
require 'diagnostics.common'
diff --git a/test/diagnostics/type-check.lua b/test/diagnostics/type-check.lua
index 908920b9..4abe5855 100644
--- a/test/diagnostics/type-check.lua
+++ b/test/diagnostics/type-check.lua
@@ -1117,6 +1117,127 @@ local B = "World"
local x = A
]]
+TEST [[
+local enum = { a = 1, b = 2 }
+
+---@type { [integer] : boolean }
+local t = {
+ <![enum.a]!> = 1,
+ <![enum.b]!> = 2,
+ <![3]!> = 3,
+}
+]]
+
+TEST [[
+local x
+
+if X then
+ x = 'A'
+elseif X then
+ x = 'B'
+else
+ x = 'C'
+end
+
+local y = x
+
+<!y!> = nil
+]]
+(function (diags)
+ local diag = diags[1]
+ assert(diag.message == [[
+已显式定义变量的类型为 `string` ,不能再将其类型转换为 `nil`。
+- `nil` 无法匹配 `string`
+- 类型 `nil` 无法匹配 `string`]])
+end)
+
+
+TEST [[
+---@type 'A'|'B'|'C'|'D'|'E'|'F'|'G'|'H'|'I'|'J'|'K'|'L'|'M'|'N'|'O'|'P'|'Q'|'R'|'S'|'T'|'U'|'V'|'W'|'X'|'Y'|'Z'
+local x
+
+<!x!> = nil
+]]
+(function (diags)
+ local diag = diags[1]
+ assert(diag.message == [[
+已显式定义变量的类型为 `'A'|'B'|'C'|'D'|'E'...(+21)` ,不能再将其类型转换为 `nil`。
+- `nil` 无法匹配 `'A'|'B'|'C'|'D'|'E'...(+21)`
+- `nil` 无法匹配 `'A'|'B'|'C'|'D'|'E'...(+21)` 中的任何子类
+- 类型 `nil` 无法匹配 `'Z'`
+- 类型 `nil` 无法匹配 `'Y'`
+- 类型 `nil` 无法匹配 `'X'`
+- 类型 `nil` 无法匹配 `'W'`
+- 类型 `nil` 无法匹配 `'V'`
+- 类型 `nil` 无法匹配 `'U'`
+- 类型 `nil` 无法匹配 `'T'`
+- 类型 `nil` 无法匹配 `'S'`
+- 类型 `nil` 无法匹配 `'R'`
+- 类型 `nil` 无法匹配 `'Q'`
+...(+13)
+- 类型 `nil` 无法匹配 `'C'`
+- 类型 `nil` 无法匹配 `'B'`
+- 类型 `nil` 无法匹配 `'A'`]])
+end)
+
+TEST [[
+---@param v integer
+---@return boolean
+local function is_string(v)
+ return type(v) == 'string'
+end
+
+print(is_string(3))
+]]
+
+TEST [[
+---@class SomeClass
+---@field [1] string
+-- ...
+
+---@param some_param SomeClass|SomeClass[]
+local function some_fn(some_param) return end
+
+some_fn { { "test" } } -- <- diagnostic: "Cannot assign `table` to `string`."
+]]
+
+TEST [[
+---@param p integer|string
+local function get_val(p)
+ local is_number = type(p) == 'number'
+ return is_number and p or p
+end
+
+get_val('hi')
+]]
+
+TESTWITH 'param-type-mismatch' [[
+---@class Class
+local Class = {}
+
+---@param source string
+function Class.staticCreator(source)
+
+end
+
+Class.staticCreator(<!true!>)
+Class<!:!>staticCreator() -- Expecting a waring
+]]
+
+TESTWITH 'assign-type-mismatch' [[
+---@type string[]
+local arr = {
+ <!3!>,
+}
+]]
+
+TESTWITH 'assign-type-mismatch' [[
+---@type (string|boolean)[]
+local arr2 = {
+ <!3!>, -- no warnings
+}
+]]
+
config.remove(nil, 'Lua.diagnostics.disable', 'unused-local')
config.remove(nil, 'Lua.diagnostics.disable', 'unused-function')
config.remove(nil, 'Lua.diagnostics.disable', 'undefined-global')
diff --git a/test/hover/init.lua b/test/hover/init.lua
index 751299bb..e77d8c98 100644
--- a/test/hover/init.lua
+++ b/test/hover/init.lua
@@ -238,14 +238,14 @@ TEST [[
string.<?sub?>()
]]
[[
-function string.sub(s: string, i: integer, j?: integer)
+function string.sub(s: string|number, i: integer, j?: integer)
-> string
]]
TEST[[
('xx'):<?sub?>()
]]
-[[function string.sub(s: string, i: integer, j?: integer)
+[[function string.sub(s: string|number, i: integer, j?: integer)
-> string]]
TEST [[
@@ -272,7 +272,7 @@ TEST [[
string.<?lower?>()
]]
[[
-function string.lower(s: string)
+function string.lower(s: string|number)
-> string
]]
@@ -490,7 +490,7 @@ local self: {
id: integer = 1,
remove: function,
__index: table,
- __name: string = "obj",
+ __name: string = 'obj',
}
]]
@@ -610,7 +610,7 @@ end
local <?r?> = a(1)
]]
[[
-local r: string = "a"
+local r: string = 'a'
]]
TEST[[
@@ -620,7 +620,7 @@ end
local _, <?r?> = pcall(a, 1)
]]
[[
-local r: string = "a"
+local r: string = 'a'
]]
TEST[[
@@ -633,7 +633,7 @@ local n: integer
TEST[[
local <?x?> = '\a'
]]
-[[local x: string = "\007"]]
+[[local x: string = '\007']]
TEST [[
local <?t?> = {
@@ -827,9 +827,9 @@ local <?t?> = {
]]
[[
local t: {
- [1]: string = "aaa",
- [2]: string = "bbb",
- [3]: string = "ccc",
+ [1]: string = 'aaa',
+ [2]: string = 'bbb',
+ [3]: string = 'ccc',
}
]]
@@ -1712,13 +1712,13 @@ local <?t?> = {
]]
[[
local t: {
- x: string = "e",
- y: string = "f",
- ['z']: string = "g",
- [10]: string = "d",
- [1]: string = "a",
- [2]: string = "b",
- [3]: string = "c"|"h",
+ x: string = 'e',
+ y: string = 'f',
+ ['z']: string = 'g',
+ [10]: string = 'd',
+ [1]: string = 'a',
+ [2]: string = 'b',
+ [3]: string = 'c'|'h',
}
]]
@@ -1830,7 +1830,7 @@ local t = {
local <?x?> = t[#t]
]]
[[
-local x: string = "x"
+local x: string = 'x'
]]
TEST [[
@@ -1864,10 +1864,10 @@ local <?x?> = {
]]
[[
local x: {
- x: string = "",
- y: string = "",
- _x: string = "",
- _y: string = "",
+ x: string = '',
+ y: string = '',
+ _x: string = '',
+ _y: string = '',
}
]]
@@ -2430,3 +2430,20 @@ local t: {
['y']: integer = 2,
}
]]
+
+TEST [[
+local enum = { a = 1, b = 2 }
+
+local <?t?> = {
+ [enum.a] = true,
+ [enum.b] = 2,
+ [3] = {}
+}
+]]
+[[
+local t: {
+ [1]: boolean = true,
+ [2]: integer = 2,
+ [3]: table,
+}
+]]
diff --git a/test/references/all.lua b/test/references/all.lua
index 9395df86..3c376c21 100644
--- a/test/references/all.lua
+++ b/test/references/all.lua
@@ -126,3 +126,16 @@ end
local v1 = Master:foobar("", Dog)
v1.<!eat!>()
]]
+
+TEST [[
+---@class A
+A = {}
+
+function A:<~TestA~>()
+end
+
+---@param param A
+function TestB(param)
+ param:<!TestA!>()
+end
+]]
diff --git a/test/references/common.lua b/test/references/common.lua
index 484418ae..9cf128a7 100644
--- a/test/references/common.lua
+++ b/test/references/common.lua
@@ -231,3 +231,18 @@ local t2
t2.<!x!> = 1
]]
+
+TEST [[
+---@alias lang 'en' | 'de'
+
+---@class A
+local a
+
+---@type lang
+a.test = 'en'
+
+---@class B
+local b
+
+b.<?<!test!>?> = a.test
+]]
diff --git a/test/tclient/tests/change-workspace-folder.lua b/test/tclient/tests/change-workspace-folder.lua
index abd385cb..a9b0e36a 100644
--- a/test/tclient/tests/change-workspace-folder.lua
+++ b/test/tclient/tests/change-workspace-folder.lua
@@ -98,4 +98,22 @@ lclient():start(function (client)
assert(files.getState(rootUri .. '/ws1/test.lua') == nil)
assert(files.getState(rootUri .. '/ws2/test.lua') == nil)
assert(files.getState(rootUri .. '/ws3/test.lua') ~= nil)
+
+ -- normalize uri
+ client:notify('workspace/didChangeWorkspaceFolders', {
+ event = {
+ added = {
+ {
+ name = 'ws2',
+ uri = rootUri .. '%2F%77%73%32'--[[/ws2]],
+ },
+ },
+ removed = {},
+ },
+ })
+
+ ws.awaitReady(rootUri .. '/ws2')
+ assert(files.getState(rootUri .. '/ws1/test.lua') == nil)
+ assert(files.getState(rootUri .. '/ws2/test.lua') ~= nil)
+ assert(files.getState(rootUri .. '/ws3/test.lua') ~= nil)
end)
diff --git a/test/tclient/tests/modify-luarc.lua b/test/tclient/tests/modify-luarc.lua
index 240ae582..62d97a41 100644
--- a/test/tclient/tests/modify-luarc.lua
+++ b/test/tclient/tests/modify-luarc.lua
@@ -6,6 +6,7 @@ local jsonb = require 'json-beautify'
local client = require 'client'
local provider = require 'provider'
local json = require 'json'
+local config = require 'config'
local configPath = LOGPATH .. '/modify-luarc.json'
@@ -324,4 +325,53 @@ lclient():start(function (languageClient)
}
}
}))
+
+ -------------------------------
+ -- merrge other configs --
+ -------------------------------
+
+ util.saveFile(configPath, jsonb.beautify(json.createEmptyObject()))
+
+ provider.updateConfig()
+
+ config.add(nil, 'Lua.diagnostics.globals', 'x')
+ config.add(nil, 'Lua.diagnostics.globals', 'y')
+
+ client.setConfig({
+ {
+ action = 'add',
+ key = 'Lua.diagnostics.globals',
+ value = 'z',
+ }
+ })
+
+ assert(util.equal(jsonc.decode_jsonc(util.loadFile(configPath)), {
+ ['diagnostics.globals'] = { 'x', 'y', 'z' }
+ }))
+
+ -------------------------------
+
+ util.saveFile(configPath, jsonb.beautify(json.createEmptyObject()))
+
+ provider.updateConfig()
+
+ config.prop(nil, 'Lua.runtime.special', 'kx', 'require')
+ config.prop(nil, 'Lua.runtime.special', 'ky', 'require')
+
+ client.setConfig({
+ {
+ action = 'prop',
+ key = 'Lua.runtime.special',
+ prop = 'kz',
+ value = 'require',
+ }
+ })
+
+ assert(util.equal(jsonc.decode_jsonc(util.loadFile(configPath)), {
+ ['runtime.special'] = {
+ ['kx'] = 'require',
+ ['ky'] = 'require',
+ ['kz'] = 'require',
+ }
+ }))
end)
diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua
index 4fbefd48..bc70fbf4 100644
--- a/test/type_inference/init.lua
+++ b/test/type_inference/init.lua
@@ -178,7 +178,7 @@ TEST 'boolean' [[
<?x?> = a == b
]]
-TEST 'integer' [[
+TEST 'unknown' [[
<?x?> = a << b
]]
@@ -186,7 +186,7 @@ TEST 'integer' [[
<?x?> = 1 << 2
]]
-TEST 'string' [[
+TEST 'unknown' [[
<?x?> = a .. b
]]
@@ -202,7 +202,7 @@ TEST 'string' [[
<?x?> = 'a' .. 1.0
]]
-TEST 'number' [[
+TEST 'unknown' [[
<?x?> = a + b
]]
@@ -227,11 +227,11 @@ local a
<?x?> = - a
]]
-TEST 'integer' [[
+TEST 'unknown' [[
<?x?> = 1 + X
]]
-TEST 'number' [[
+TEST 'unknown' [[
<?x?> = 1.0 + X
]]
@@ -2416,7 +2416,7 @@ local <?z?> = f()
TEST 'integer|table' [[
local function returnI()
- return a + 1
+ return 1
end
local function f()
@@ -2620,6 +2620,17 @@ end
print(<?n?>)
]]
+TEST 'integer' [[
+---@type integer?
+local n
+
+if not n then
+ os.exit()
+end
+
+print(<?n?>)
+]]
+
TEST 'table' [[
---@type table?
local n
@@ -4199,3 +4210,47 @@ x.y = nil
print(<?y?>)
]]
+
+TEST 'function' [[
+function X()
+ <?Y?>()
+end
+
+function Y()
+end
+]]
+
+TEST 'A_Class' [[
+---@class A_Class
+local A = { x = 5 }
+
+function A:func()
+ for i = 1, <?self?>.x do
+ print(i)
+ end
+
+ self.y = 3
+ self.y = self.y + 3
+end
+]]
+
+TEST 'number' [[
+---@type number?
+local n
+local <?v?> = n or error('')
+]]
+
+TEST 'Foo' [[
+---@class Foo
+---@operator mul(Foo): Foo
+---@operator mul(Bar): Foo
+---@class Bar
+
+---@type Foo
+local foo
+
+---@type Foo|Bar
+local fooOrBar
+
+local <?b?> = foo * fooOrBar
+]]