diff --git a/.emmyrc.json b/.emmyrc.json
new file mode 100644
index 0000000..0e12414
--- /dev/null
+++ b/.emmyrc.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json",
+ "workspace": {
+ "ignoreDir": [
+ ".rocks",
+ "build",
+ "tmp"
+ ]
+ },
+ "runtime": {
+ "version": "LuaJIT"
+ },
+ "diagnostics": {
+ "disable": [
+ "need-check-nil",
+ "redefined-local",
+ "unresolved-require"
+ ],
+ "globals": [
+ "box"
+ ]
+ }
+}
diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml
index 1bf02ea..8c6fee2 100644
--- a/.github/workflows/packaging.yml
+++ b/.github/workflows/packaging.yml
@@ -15,7 +15,7 @@ jobs:
if: |
github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
steps:
- name: Check module version
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
@@ -32,7 +32,7 @@ jobs:
github.event_name == 'push' ||
github.event.pull_request.head.repo.full_name != github.repository
needs: version-check
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
strategy:
fail-fast: false
@@ -41,6 +41,7 @@ jobs:
- { os: 'debian', dist: 'stretch' }
- { os: 'debian', dist: 'buster' }
- { os: 'debian', dist: 'bullseye' }
+ - { os: 'debian', dist: 'bookworm' }
- { os: 'el', dist: '7' }
- { os: 'el', dist: '8' }
- { os: 'fedora', dist: '30' }
@@ -54,6 +55,7 @@ jobs:
- { os: 'ubuntu', dist: 'bionic' }
- { os: 'ubuntu', dist: 'focal' }
- { os: 'ubuntu', dist: 'jammy' }
+ - { os: 'ubuntu', dist: 'noble' }
env:
OS: ${{ matrix.platform.os }}
@@ -61,12 +63,12 @@ jobs:
steps:
- name: Clone the module
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Clone the packpack tool
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
repository: packpack/packpack
path: packpack
diff --git a/.github/workflows/push_rockspec.yml b/.github/workflows/push_rockspec.yml
index ae3e383..381c689 100644
--- a/.github/workflows/push_rockspec.yml
+++ b/.github/workflows/push_rockspec.yml
@@ -17,7 +17,7 @@ jobs:
version-check:
# We need this job to run only on push with tag.
if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
steps:
- name: Check module version
uses: tarantool/actions/check-module-version@master
@@ -27,7 +27,7 @@ jobs:
require('test.rock_utils').assert_nonbuiltin('checks')
push-scm-rockspec:
- runs-on: [ ubuntu-20.04 ]
+ runs-on: [ ubuntu-24.04 ]
if: github.ref == 'refs/heads/master' && github.event.workflow_run.conclusion == 'success'
steps:
- uses: actions/checkout@master
@@ -38,7 +38,7 @@ jobs:
files: ${{ env.ROCK_NAME }}-scm-1.rockspec
push-tagged-rockspec:
- runs-on: [ ubuntu-20.04 ]
+ runs-on: [ ubuntu-24.04 ]
if: startsWith(github.ref, 'refs/tags')
needs: version-check
steps:
diff --git a/.github/workflows/reusable_testing.yml b/.github/workflows/reusable_testing.yml
index efe987f..518408a 100644
--- a/.github/workflows/reusable_testing.yml
+++ b/.github/workflows/reusable_testing.yml
@@ -5,13 +5,13 @@ on:
inputs:
artifact_name:
description: The name of the tarantool build artifact
- default: ubuntu-focal
+ default: ubuntu-jammy
required: false
type: string
jobs:
run_tests:
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-24.04
steps:
- name: Clone the checks module
uses: actions/checkout@v4
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 3e46f23..5c489c2 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -8,12 +8,12 @@ jobs:
strategy:
fail-fast: false
matrix:
- tarantool: ['1.10', '2.5', '2.6', '2.7', '2.8', '2.10']
+ tarantool: ['1.10','2.11', '3.3']
- runs-on: [ubuntu-20.04]
+ runs-on: [ubuntu-22.04]
steps:
- - uses: actions/checkout@v3
- - uses: tarantool/setup-tarantool@v2
+ - uses: actions/checkout@v4
+ - uses: tarantool/setup-tarantool@v3
with:
tarantool-version: ${{ matrix.tarantool }}
@@ -36,9 +36,9 @@ jobs:
strategy:
fail-fast: false
- runs-on: [ubuntu-20.04]
+ runs-on: [ubuntu-22.04]
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Setup LuaJIT
run: sudo apt install -y luajit
diff --git a/.luacheckrc b/.luacheckrc
index 57c02f0..7f11a70 100644
--- a/.luacheckrc
+++ b/.luacheckrc
@@ -2,3 +2,12 @@ include_files = {'**/*.lua', '*.luacheckrc', '*.rockspec'}
exclude_files = {'.rocks/', 'tmp/', 'build/'}
max_line_length = 120
redefined = false
+globals = {
+ "box",
+}
+ignore = {
+ -- Accessing an undefined field of a global variable
.
+ "143/table",
+ -- Unused variable with `_` prefix.
+ "212/_.*",
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b66ea7b..903bb80 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+## [Unreleased]
+
+### Added
+
+### Changed
+
+### Fixed
+
+### Removed
+
+## [3.4.0] - 2025-10-21
+
+This release introduces bumped CMake version to avoid compatibility
+problem with CMake 4.x.
+
+### Changed
+
+- Bump CMake version to avoid compatibility problem with CMake 4.x (#66).
+
## [3.3.0] - 2023-04-19
### Added
@@ -16,6 +35,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Override built-in checks, if installed.
## [3.2.0] - 2023-01-27
+
### Added
- "error" type supported.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2025061..ef330dd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.10...3.31 FATAL_ERROR)
project(checks NONE)
diff --git a/checks.lua b/checks.lua
index 35060a8..c61997b 100644
--- a/checks.lua
+++ b/checks.lua
@@ -1,3 +1,12 @@
+---The `checks` module provides the ability to check the types of arguments
+---passed to a Lua function. It is designed to reveal mistakes in code, not to
+---validate user input.
+---
+---The returned module table is callable: `checks(type_1, ...)` is equivalent
+---to `checks.checks(type_1, ...)`. It exposes the `checks` function and the
+---`_VERSION` string field.
+---
+---@alias checks.qualifier string|table
local ffi = require('ffi')
ffi.cdef[[
@@ -18,14 +27,14 @@ local _qualifiers_cache = {
-- },
}
---- Check that string (or substring) starts with given string
--- Optionally restricting the matching with the given offsets
--- @function startswith
--- @string inp original string
--- @string head the substring to check against
--- @int[opt] _start start index of matching boundary
--- @int[opt] _end end index of matching boundary
--- @returns boolean
+---Check that the given string (or substring) starts with the given string,
+---optionally restricting the matching with the given offsets.
+---
+---@param inp string The original string.
+---@param head string The substring to check against.
+---@param _start? integer Start index of the matching boundary (default: `1`).
+---@param _end? integer End index of the matching boundary (default: `#inp`).
+---@return boolean `true` if `inp` starts with `head`, `false` otherwise.
local function startswith(inp, head, _start, _end)
if type(inp) ~= 'string' then
error(err_string_arg:format(1, 'string.startswith', 'string',
@@ -69,6 +78,13 @@ local function startswith(inp, head, _start, _end)
end
+---Check that a value conforms to the given string type qualifier.
+---
+---@param value any The value to check.
+---@param expected_type string The string type qualifier, e.g. `'string'`,
+--- `'?number|string'`, or `'?'` for any type.
+---@return boolean? `true` if the value conforms to the type qualifier.
+---@return string? error_message The formatted error message if the check fails.
local function check_string_type(value, expected_type)
-- 1. Check any value.
if expected_type == '?' then
@@ -76,6 +92,7 @@ local function check_string_type(value, expected_type)
end
-- 2. Parse type qualifier
+ ---@type { [integer]: string, optional: boolean }?
local qualifier = _qualifiers_cache[expected_type]
if qualifier == nil then
qualifier = { optional = false }
@@ -123,6 +140,11 @@ local function check_string_type(value, expected_type)
)
end
+---Format a table key for an error message: `.key` for strings and `[n]`
+---for numbers.
+---
+---@param key any The table key.
+---@return string The formatted key name.
local function keyname_fmt(key)
if type(key) == 'string' then
return string.format('.%s', key)
@@ -133,6 +155,12 @@ local function keyname_fmt(key)
end
end
+---Check that a table conforms to the given table type qualifier.
+---
+---@param tbl table? The table to check.
+---@param expected_fields table The table type qualifier.
+---@return boolean? `true` if the table conforms to the type qualifier.
+---@return string? error_message The formatted error message if the check fails.
local function check_table_type(tbl, expected_fields)
if tbl == nil then
tbl = nil
@@ -144,11 +172,13 @@ local function check_table_type(tbl, expected_fields)
if type(expected_type) == 'string' then
local ok, efmt = check_string_type(value, expected_type)
if not ok then
+ ---@cast efmt string
return nil, string.format(efmt, '%s'..keyname_fmt(expected_key), '%s')
end
elseif type(expected_type) == 'table' then
local ok, efmt = check_string_type(value, '?table')
if not ok then
+ ---@cast efmt string
return nil, string.format(efmt, '%s'..keyname_fmt(expected_key), '%s')
end
@@ -159,6 +189,7 @@ local function check_table_type(tbl, expected_fields)
local ok, efmt = check_table_type(value, expected_type)
if not ok then
+ ---@cast efmt string
return nil, string.format(efmt, '%s'..keyname_fmt(expected_key), '%s')
end
else
@@ -187,12 +218,27 @@ local function check_table_type(tbl, expected_fields)
return true
end
+---Checks that the arguments of the calling function conform to the specified
+---types. Must be called at the top of the function being checked; each type
+---qualifier corresponds to the argument at the same position.
+---
+---String qualifiers check Lua types, Tarantool-specific types (`uint64`,
+---`int64`, `decimal`, `uuid`, etc.), metatable `__type` values, and custom
+---checker names; they can be combined into union types (`'number|string'`) and
+---made optional (`'?string'`). Table qualifiers validate the values of a table
+---argument.
+---
+---@param ... checks.qualifier|number Type qualifiers, one per argument to
+--- check. The first argument may also be a stack level (used internally).
local function checks(...)
local skip = 0
+ ---@type integer
local level = 1
- if type(...) == 'number' then
- level = ...
+ local first = ...
+ if type(first) == 'number' then
+ ---@cast first integer
+ level = first
skip = 1
end
level = level + 1 -- escape the checks level
@@ -216,6 +262,7 @@ local function checks(...)
local ok, efmt = check_string_type(value, expected_type)
if not ok then
local info = debug.getinfo(level, 'nl')
+ ---@cast efmt string
local err = string.format(efmt, '#'..tostring(i), info.name)
error(err, level)
end
@@ -224,18 +271,23 @@ local function checks(...)
local ok, efmt = check_string_type(value, '?table')
if not ok then
local info = debug.getinfo(level, 'nl')
+ ---@cast efmt string
local err = string.format(efmt, '#'..tostring(i), info.name)
error(err, level)
end
if rawget(_G, '_checks_v2_compatible') and value == nil then
value = {}
+ -- In emmylua-check 0.22.0 the debug.setlocal index
+ -- parameter is mistyped as `string`; it is an integer.
+ ---@diagnostic disable-next-line: param-type-mismatch
debug.setlocal(level, i, value)
end
local ok, efmt = check_table_type(value, expected_type)
if not ok then
local info = debug.getinfo(level, 'nl')
+ ---@cast efmt string
local err = string.format(efmt, argname, info.name)
error(err, level)
end
@@ -249,15 +301,39 @@ local function checks(...)
end
end
+---The `checks` function is also available as a global, so it can be used
+---without loading the module (Tarantool 2.11.0 and later).
rawset(_G, 'checks', checks)
+---The `checkers` global table provides access to checkers for different types.
+---It can be extended with custom checkers that perform arbitrary validations.
+---
+---@class checks.checkers
+---@field datetime fun(arg: any): boolean Check that the value is a datetime object.
+---@field decimal fun(arg: any): boolean Check that the value has the decimal type.
+---@field error fun(arg: any): boolean Check that the value is an error object.
+---@field int64 fun(arg: any): boolean Check that the value is an int64 value.
+---@field interval fun(arg: any): boolean Check that the value is an interval object.
+---@field tuple fun(arg: any): boolean Check that the value is a tuple.
+---@field uint64 fun(arg: any): boolean Check that the value is a uint64 value.
+---@field uuid fun(arg: any): boolean Check that the value is a uuid object.
+---@field uuid_bin fun(arg: any): boolean Check that the value is a uuid as a 16-byte binary string.
+---@field uuid_str fun(arg: any): boolean Check that the value is a uuid as a 36-byte hexadecimal string.
local checkers = rawget(_G, 'checkers') or {}
rawset(_G, 'checkers', checkers)
+---When set to `true`, substitutes `nil` table arguments with empty tables for
+---backward compatibility with v2.1.
+---@type boolean
local _checks_v2_compatible = rawget(_G, '_checks_v2_compatible') or false
rawset(_G, '_checks_v2_compatible', _checks_v2_compatible)
-local ffi = require('ffi')
+---Check whether the specified value is a `uint64` value: an integer Lua number
+---in the range from 0 to 2^53-1 (inclusive), a cdata `ctype`, or a
+---cdata `ctype` in the range from 0 to `LLONG_MAX`.
+---
+---@param arg any The value to check.
+---@return boolean `true` if the value is a `uint64` value, `false` otherwise.
function checkers.uint64(arg)
if type(arg) == 'number' then
-- Double floating point format has 52 fraction bits
@@ -277,6 +353,13 @@ function checkers.uint64(arg)
return false
end
+---Check whether the specified value is an `int64` value: an integer Lua
+---number in the range from -2^53+1 to 2^53-1 (inclusive), a cdata
+---`ctype`, or a cdata `ctype` in the range from 0 to
+---`LLONG_MAX`.
+---
+---@param arg any The value to check.
+---@return boolean `true` if the value is an `int64` value, `false` otherwise.
function checkers.int64(arg)
if type(arg) == 'number' then
return (arg > -2^53) and (arg < 2^53) and (math.floor(arg) == arg)
@@ -293,6 +376,7 @@ function checkers.int64(arg)
return false
end
+---Check whether the specified value is a tuple.
local has_box = rawget(_G, 'box') ~= nil
if has_box and box.tuple ~= nil then
checkers.tuple = box.tuple.is
@@ -303,11 +387,19 @@ if has_decimal then
-- There is a decimal.is_decimal check since 2.4, but we
-- reimplement it here to support older versions which have decimal.
local cdata_t = ffi.typeof(decimal.new(0))
+ ---Check whether the specified value has the decimal type.
+ ---
+ ---@param arg any The value to check.
+ ---@return boolean `true` if the value has the decimal type, `false` otherwise.
checkers.decimal = function(arg)
return ffi.istype(cdata_t, arg)
end
end
+---Register a checker for a cdata type checked via FFI.
+---
+---@param checks_type string The name of the checker to register in `checkers`.
+---@param c_type string The C type name, e.g. `'struct tt_uuid'`.
local function add_ffi_type_checker(checks_type, c_type)
local has_cdata_t, cdata_t = pcall(ffi.typeof, c_type)
if has_cdata_t then
@@ -322,6 +414,11 @@ end
-- https://github.com/tarantool/tarantool/blob/7682d34162be34648172d91008e9185301bce8f6/src/lua/uuid.lua#L29
add_ffi_type_checker('uuid', 'struct tt_uuid')
+---Check whether the specified value is a uuid represented by a 36-byte
+---hexadecimal string.
+---
+---@param arg any The value to check.
+---@return boolean `true` if the value is a uuid string, `false` otherwise.
function checkers.uuid_str(arg)
if type(arg) == 'string' and #arg == 36 then
local match = arg:match(
@@ -339,6 +436,11 @@ function checkers.uuid_str(arg)
end
end
+---Check whether the specified value is a uuid represented by a 16-byte binary
+---string.
+---
+---@param arg any The value to check.
+---@return boolean `true` if the value is a uuid binary string, `false` otherwise.
function checkers.uuid_bin(arg)
if type(arg) == 'string' and #arg == 16 then
return true
@@ -349,6 +451,7 @@ end
add_ffi_type_checker('error', 'struct error')
+---Check whether the specified value is a datetime object.
local has_datetime, datetime = pcall(require, 'datetime')
if has_datetime then
checkers.datetime = datetime.is_datetime
@@ -356,7 +459,7 @@ end
add_ffi_type_checker('interval', 'struct interval')
-return setmetatable(
+local M = setmetatable(
{
checks = checks,
_VERSION = require('checks.version'),
@@ -368,3 +471,5 @@ return setmetatable(
end
}
)
+
+return M
diff --git a/checks/version.lua b/checks/version.lua
index 37ef5c9..a37cd51 100644
--- a/checks/version.lua
+++ b/checks/version.lua
@@ -1,4 +1,4 @@
-- Сontains the module version.
-- Requires manual update in case of release commit.
-return '3.3.0'
+return '3.4.0'
diff --git a/debian/prebuild.sh b/debian/prebuild.sh
index ecc64d2..3f2a4be 100755
--- a/debian/prebuild.sh
+++ b/debian/prebuild.sh
@@ -2,4 +2,13 @@
set -e -o pipefail
-curl -LsSf https://www.tarantool.io/release/1.10/installer.sh | sudo bash
+if [[ $DIST == "noble" ]] || [[ $DIST == "bookworm" ]]; then
+ curl -LsSf https://www.tarantool.io/release/3/installer.sh | sudo bash
+elif [[ $DIST == "impish" ]] || [[ $DIST == "jammy" ]]; then
+ curl -LsSf https://www.tarantool.io/release/2/installer.sh | sudo bash
+else
+ curl -LsSf https://www.tarantool.io/release/1.10/installer.sh | sudo bash
+fi
+
+sudo apt install -y tt
+tt version
diff --git a/test/perftest.lua b/test/perftest.lua
index 13502e7..1a83176 100755
--- a/test/perftest.lua
+++ b/test/perftest.lua
@@ -134,7 +134,7 @@ for _, case in pairs(cases) do
local name = ('test_%s_%s'):format(json.encode(case.check), case.argtype):gsub('%.', '_')
g[name] = function(_)
- local fn = function(arg) -- luacheck: no unused args
+ local fn = function(_arg)
checks(case.check)
end
diff --git a/test/test.lua b/test/test.lua
index 1f55aa3..652d5b6 100755
--- a/test/test.lua
+++ b/test/test.lua
@@ -19,41 +19,41 @@ end
local testdata = {}
local _l_number_optstring = 2 + debug.getinfo(1).currentline
-function testdata.fn_number_optstring(arg1, arg2) -- luacheck: no unused args
+function testdata.fn_number_optstring(_arg1, _arg2)
checks('number', '?string')
end
local _l_number_or_string = 2 + debug.getinfo(1).currentline
-function testdata.fn_number_or_string(arg1) -- luacheck: no unused args
+function testdata.fn_number_or_string(_arg1)
checks('number|string')
end
local _l_positive_number = 2 + debug.getinfo(1).currentline
-function testdata.fn_positive_number(arg1) -- luacheck: no unused args
+function testdata.fn_positive_number(_arg1)
checks('positive_number')
end
-function testdata.fn_anytype(arg1) -- luacheck: no unused args
+function testdata.fn_anytype(_arg1)
checks('?')
end
local _l_nil_or_number_or_string = 2 + debug.getinfo(1).currentline
-function testdata.fn_nil_or_number_or_string(arg1) -- luacheck: no unused args
+function testdata.fn_nil_or_number_or_string(_arg1)
checks('nil|number|string')
end
local _l_optnumber_or_optstring = 2 + debug.getinfo(1).currentline
-function testdata.fn_optnumber_or_optstring(arg1) -- luacheck: no unused args
+function testdata.fn_optnumber_or_optstring(_arg1)
checks('?number|?string')
end
local _l_varargs = 2 + debug.getinfo(1).currentline
-function testdata.fn_varargs(arg1, ...) -- luacheck: no unused args
+function testdata.fn_varargs(_arg1, ...) -- luacheck: ignore 212
checks('string')
end
local _l_options = 2 + debug.getinfo(1).currentline
-function testdata.fn_options(options) -- luacheck: no unused args
+function testdata.fn_options(_options)
checks({
mystring = '?string',
mynumber = '?number',
@@ -61,17 +61,17 @@ function testdata.fn_options(options) -- luacheck: no unused args
end
local _l_array = 2 + debug.getinfo(1).currentline
-function testdata.fn_array(array) -- luacheck: no unused args
+function testdata.fn_array(_array)
checks({'number', 'number'})
end
local _l_table = 2 + debug.getinfo(1).currentline
-function testdata.fn_table(table) -- luacheck: no unused args
+function testdata.fn_table(_table)
checks({mykey = 'number'})
end
local _l_inception = 2 + debug.getinfo(1).currentline
-function testdata.fn_inception(options) -- luacheck: no unused args
+function testdata.fn_inception(_options)
checks({
we = {
need = {
@@ -90,27 +90,27 @@ local function deepchecks()
end
local _l_deepcheck = 2 + debug.getinfo(1).currentline
-function testdata.fn_deepcheck(arg1) -- luacheck: no unused args
+function testdata.fn_deepcheck(_arg1)
deepchecks()
end
local _l_excess_checks = 2 + debug.getinfo(1).currentline
-function testdata.fn_excess_checks(arg1) -- luacheck: no unused args
+function testdata.fn_excess_checks(_arg1)
checks('?number', '?string')
end
local _l_missing_checks = 2 + debug.getinfo(1).currentline
-function testdata.fn_missing_checks(arg1, arg2) -- luacheck: no unused args
+function testdata.fn_missing_checks(_arg1, _arg2)
checks('?number')
end
local _l_bad_check_type_1 = 2 + debug.getinfo(1).currentline
-function testdata.bad_check_type_1(arg1, arg2) -- luacheck: no unused args
+function testdata.bad_check_type_1(_arg1, _arg2)
checks("?string", 5)
end
local _l_bad_check_type_2 = 2 + debug.getinfo(1).currentline
-function testdata.bad_check_type_2(arg1, arg2) -- luacheck: no unused args
+function testdata.bad_check_type_2(_arg1, _arg2)
checks({param = 5})
end
@@ -294,12 +294,12 @@ local err_cases = {
{
code = 'fn_options({mynumber = "bad"})',
line = _l_options,
- error = 'bad argument options.mynumber to fn_options (?number expected, got string)',
+ error = 'bad argument _options.mynumber to fn_options (?number expected, got string)',
},
{
code = 'fn_options({badfield = "bad"})',
line = _l_options,
- error = 'unexpected argument options.badfield to fn_options',
+ error = 'unexpected argument _options.badfield to fn_options',
},
-- fn_array
@@ -311,32 +311,32 @@ local err_cases = {
{
code = 'fn_array()',
line = _l_array,
- error = 'bad argument array[1] to fn_array (number expected, got nil)',
+ error = 'bad argument _array[1] to fn_array (number expected, got nil)',
},
{
code = 'fn_array(nil)',
line = _l_array,
- error = 'bad argument array[1] to fn_array (number expected, got nil)',
+ error = 'bad argument _array[1] to fn_array (number expected, got nil)',
},
{
code = 'fn_array(box.NULL)',
line = _l_array,
- error = 'bad argument array[1] to fn_array (number expected, got nil)',
+ error = 'bad argument _array[1] to fn_array (number expected, got nil)',
},
{
code = 'fn_array({})',
line = _l_array,
- error = 'bad argument array[1] to fn_array (number expected, got nil)',
+ error = 'bad argument _array[1] to fn_array (number expected, got nil)',
},
{
code = 'fn_array({"str1"})',
line = _l_array,
- error = 'bad argument array[1] to fn_array (number expected, got string)',
+ error = 'bad argument _array[1] to fn_array (number expected, got string)',
},
{
code = 'fn_array({1})',
line = _l_array,
- error = 'bad argument array[2] to fn_array (number expected, got nil)',
+ error = 'bad argument _array[2] to fn_array (number expected, got nil)',
},
{
code = 'fn_array({1, 2})',
@@ -344,7 +344,7 @@ local err_cases = {
{
code = 'fn_array({1, 2, 3})',
line = _l_array,
- error = 'unexpected argument array[3] to fn_array',
+ error = 'unexpected argument _array[3] to fn_array',
},
-- fn_table
@@ -356,17 +356,17 @@ local err_cases = {
{
code = 'fn_table()',
line = _l_table,
- error = 'bad argument table.mykey to fn_table (number expected, got nil)',
+ error = 'bad argument _table.mykey to fn_table (number expected, got nil)',
},
{
code = 'fn_table({})',
line = _l_table,
- error = 'bad argument table.mykey to fn_table (number expected, got nil)',
+ error = 'bad argument _table.mykey to fn_table (number expected, got nil)',
},
{
code = 'fn_table({mykey = "str"})',
line = _l_table,
- error = 'bad argument table.mykey to fn_table (number expected, got string)',
+ error = 'bad argument _table.mykey to fn_table (number expected, got string)',
},
{
code = 'fn_table({mykey = 0})',
@@ -374,7 +374,7 @@ local err_cases = {
{
code = 'fn_table({mykey = 0, excess = 1})',
line = _l_table,
- error = 'unexpected argument table.excess to fn_table',
+ error = 'unexpected argument _table.excess to fn_table',
},
-- fn_inception
@@ -387,7 +387,7 @@ local err_cases = {
{
code = 'fn_inception({we = false})',
line = _l_inception,
- error = 'bad argument options.we to fn_inception (?table expected, got boolean)',
+ error = 'bad argument _options.we to fn_inception (?table expected, got boolean)',
},
{
code = 'fn_inception({we = {}})',
@@ -407,7 +407,7 @@ local err_cases = {
{
code = 'fn_inception({we = {need = {to = {go = {deeper = {}}}}}})',
line = _l_inception,
- error = 'bad argument options.we.need.to.go.deeper to fn_inception (?number expected, got table)',
+ error = 'bad argument _options.we.need.to.go.deeper to fn_inception (?number expected, got table)',
},
-- fn_deepcheck
@@ -429,7 +429,7 @@ local err_cases = {
{
code = 'fn_missing_checks()',
line = _l_missing_checks,
- error = 'checks: argument "arg2" is not checked',
+ error = 'checks: argument "_arg2" is not checked',
},
{
code = 'bad_check_type_1()',
@@ -456,6 +456,7 @@ for _, case in pairs(err_cases) do
g[name] = function(_)
local fn = loadstring(case.code)
+ ---@cast fn function
local ok, err = pcall(fn)
if case.error == nil then
@@ -582,34 +583,34 @@ for _, case in pairs(options_v2_cases) do
end
------------------------------------------------------------------------------
-function testdata.fn_int64(arg) -- luacheck: no unused args
+function testdata.fn_int64(_arg)
checks('int64')
end
-function testdata.fn_uint64(arg) -- luacheck: no unused args
+function testdata.fn_uint64(_arg)
checks('uint64')
end
local uuid = require('uuid')
testdata.myid = uuid()
-function testdata.fn_uuid(arg) -- luacheck: no unused args
+function testdata.fn_uuid(_arg)
checks('uuid')
end
-function testdata.fn_uuid_str(arg) -- luacheck: no unused args
+function testdata.fn_uuid_str(_arg)
checks('uuid_str')
end
-function testdata.fn_uuid_bin(arg) -- luacheck: no unused args
+function testdata.fn_uuid_bin(_arg)
checks('uuid_bin')
end
-function testdata.fn_tuple(arg) -- luacheck: no unused args
+function testdata.fn_tuple(_arg)
checks('tuple')
end
-function testdata.fn_decimal(arg) -- luacheck: no unused args
+function testdata.fn_decimal(_arg)
checks('decimal')
end
@@ -618,13 +619,13 @@ if has_decimal then
testdata.decimal = decimal
end
-function testdata.fn_error(arg) -- luacheck: no unused args
+function testdata.fn_error(_arg)
checks('error')
end
local has_error = (box.error ~= nil) and (box.error.new ~= nil)
-function testdata.fn_datetime(arg) -- luacheck: no unused args
+function testdata.fn_datetime(_arg)
checks('datetime')
end
@@ -633,7 +634,7 @@ if has_datetime then
testdata.datetime = datetime
end
-function testdata.fn_interval(arg) -- luacheck: no unused args
+function testdata.fn_interval(_arg)
checks('interval')
end
@@ -1095,6 +1096,7 @@ for _, case in pairs(ret_cases) do
t.skip_if(case.skip, "type unsupported")
local fn = loadstring(case.code)
+ ---@cast fn function
local ok, err = pcall(fn)
t.assert_equals(case.ok, ok, err)
end
diff --git a/test/types.lua b/test/types.lua
new file mode 100644
index 0000000..07e6b2b
--- /dev/null
+++ b/test/types.lua
@@ -0,0 +1,6 @@
+---@meta
+---
+--- Tarantool extensions to the standard Lua `table` library.
+---
+---@class tablelib
+---@field deepcopy fun(t: table): table Deep-copies a table.