Merge pull request #847 from MihailRis/client-side-tests

client-side `--script`, `--test` support (part 1)
This commit is contained in:
MihailRis 2026-07-25 21:59:10 +03:00 • committed by GitHub
commit 4295af15cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
55 changed files with 1660 additions and 590 deletions

View file

@ -92,6 +92,11 @@ socket:recv_async(
[опционально] usetable: boolean=false
) -> nil|table|Bytearray
-- Оборачивает сокет в io_stream (см. ../io_stream.md)
socket:as_stream(
[опционально] binary_mode: boolean=true
) -> io_stream
-- Закрывает соединение
socket:close()

View file

@ -7,7 +7,7 @@
- [расширения для string](#расширения-для-string)
- [расширения для math](#расширения-для-math)
- [расширения для bit](#расширения-для-bit)
- [Дополнительные глобальные функции](#дополнительные-глобальные-функции)
- [дополнительные глобальные функции](#дополнительные-глобальные-функции)
## Расширения для table
```lua
@ -62,6 +62,12 @@ table.sub(arr: table, start: number | nil, stop: number | nil) -> table
table.insert_unique(t: table, val: any)
table.insert_unique(t: table, pos: int, val: any)
-- Возвращает таблицу, содержащую все ключи переданной таблицы, включая числовые.
table.keys(t: table) -> table
-- Добавляет в таблицу t все пары ключ-значение из таблицы extension, при этом если в extension присутствует ключ из t, то его значение будет перезаписано.
table.extend(t: table, extension: table) -> table
-- Конвертирует переданную таблицу в строку.
table.tostring(t: table) -> string
```

View file

@ -18,7 +18,7 @@
Поток имеет три различных вида режима:
- Режим общего поведения (`general` / `mode`)
- Режим сброса (`flush` / `flushMode`)
- Режим сброса (`flush` / `flush_mode`)
- Двоичный режим (`binary`)
@ -27,34 +27,34 @@
Определяет, как поток обрабатывает чтение и запись,
имеет три подрежима:
| Режим | Описание |
|---------------|--------|
| `"default"` | Прямой режим. `read` может вернуть меньше байт, чем запрошено. `write` сразу отправляет данные в низкоуровневый дескриптор. Нет буферизации. |
| Режим | Описание |
|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
| `"default"` | Прямой режим. `read` может вернуть меньше байт, чем запрошено. `write` сразу отправляет данные в низкоуровневый дескриптор. Нет буферизации. |
| `"yield"` | Как `default`, но при нехватке данных в `read(n)` поток будет вызывать `coroutine.yield()`, пока не соберёт ровно `n` байт. Удобно для корутин. |
| `"buffered"` | Включает внутренние буферы чтения и записи. `read` берёт данные из буфера, `write` — складывает в буфер. При превышении `maxBufferSize` — ошибка `buffer overflow`. |
| `"buffered"` | Включает внутренние буферы чтения и записи. `read` берёт данные из буфера , `write` — складывает в буфер. |
### flush
Работает только в режиме `"buffered"`,
имеет два подрежима:
| Режим | Что делает `flush()` |
|------------------|----------------------|
| `"all"` (по умолчанию) | Сначала сбрасывает буфер записи → низкоуровневый `write`, затем вызывает `ioLib.flush(descriptor)` |
| `"buffer"` | Сбрасывает только буфер записи, без вызова системного `flush` |
| Режим | Что делает `flush()` |
|------------------------|-----------------------------------------------------------------------------------------------------|
| `"all"` (по умолчанию) | Сначала сбрасывает буфер записи → низкоуровневый `write`, затем вызывает `io_lib.flush(descriptor)` |
| `"buffer"` | Сбрасывает только буфер записи, без вызова системного `flush` |
### binary
**Независимый флаг** (включается через `set_binary_mode(true)` или при создании потока).
Определяет, в каком виде методы `read` и `write` принимают и возвращают данные:
| binary = true | binary = false (по умолчанию) |
|-----------------------------------------|----------------------------------------|
| binary = true | binary = false (по умолчанию) |
|------------------------------------------------------------|----------------------------------------|
| Данные — это **байты** (`Bytearray`, таблица чисел 0..255) | Данные — это **текстовые строки** |
| `read(n)` → `Bytearray` или `table<number>`| `read()` → одна строка |
| `read("i4 f")` → распаковка через `byteutil.unpack` | `read(n)` → n строк в таблице |
| `write(Bytearray)` → запись байтов | `write("hello")` → строка + `\n` |
| `write("i4", 42)` → `byteutil.pack` | `write({"a","b"})` → две строки с `\n`|
| `read(n)` → `Bytearray` или `table<int>` | `read()` → одна строка |
| `read("i4 f")` → распаковка через `byteutil.unpack` | `read(n)` → n строк в таблице |
| `write(Bytearray)` → запись байтов | `write("hello")` → строка + `\n` |
| `write("i4", 42)` → `byteutil.pack` | `write({"a","b"})` → две строки с `\n` |
`read_line` / `write_line` — работают как в текстовом режиме
@ -90,25 +90,25 @@ io_stream:set_flush_mode(string)
--[[
Читает данные из потока
В двоичном режиме:
Если arg - number, то читает из потока arg байт и возвращает ввиде Bytearray или таблицы, если useTable = true
Если arg - int, то читает из потока arg байт и возвращает ввиде Bytearray или таблицы, если use_table = true
Если arg - string, то функция интерпретирует arg как шаблон для byteutil. Прочитает кол-во байт, которое определено шаблоном, передаст их в byteutil.unpack и вернёт результат
В текстовом режиме:
Если arg - number, то читает нужное кол-во строк с окончанием CRLF/LF из arg и возвращает ввиде таблицы. Также, если trimEmptyLines = true, то удаляет пустые строки с начала и конца из итоговой таблицы
Если arg - int, то читает нужное кол-во строк с окончанием CRLF/LF из arg и возвращает ввиде таблицы. Также, если trim_empty_lines = true, то удаляет пустые строки с начала и конца из итоговой таблицы
Если arg не определён, то читает одну строку с окончанием CRLF/LF и возвращает её.
--]]
io_stream:read(
[опционально] arg: number | string,
[опционально] useTable | trimEmptyLines: boolean
) -> Bytearray | table<number> | string | table<string> | ...
[опционально] arg: int | string,
[опционально] use_table = false | trim_empty_lines = true: boolean
) -> Bytearray | table<int> | string | table<string> | ...
--[[
Записывает данные в поток
В двоичном режиме:
Если arg - string, то функция интерпретирует arg как шаблон для byteutil, передаст его и ... в byteutil.pack и результат запишет в поток
Если arg - Bytearray | table<number>, то записывает байты в поток
Если arg - Bytearray | table<int>, то записывает байты в поток
В текстовом режиме:
Если arg - string, то записывает строку в поток (вместе с окончанием LF)
@ -116,7 +116,7 @@ io_stream:read(
Если arg - table<string>, то записывает каждую строку из таблицы отдельно
--]]
io_stream:write(
arg: Bytearray | table<number> | string | table<string>,
arg: Bytearray | table<int> | string | table<string>,
[опционально] ...
)
@ -128,53 +128,59 @@ io_stream:write_line(string)
--[[
В двоичном режиме:
Читает все доступные байты из потока и возвращает ввиде Bytearray или table<number>, если useTable = true
Читает все доступные байты из потока и возвращает ввиде Bytearray или table<int>, если use_table = true
В текстовом режиме:
Читает все доступные строки из потока в table<string> если useTable = true, или в одну строку вместе с окончаниями, если нет
Читает все доступные строки из потока в table<string> если use_table = true, или в одну строку вместе с окончаниями, если нет
--]]
io_stream:read_fully(
[опционально] useTable: boolean
) -> Bytearray | table<number> | table<string> | string
[опционально] use_table: boolean
) -> Bytearray | table<int> | table<string> | string
--[[
Устанавливает позицию в потоке
Если length определён, то возвращает true, если length байт доступно к чтению. Иначе возвращает false.
Если не определён, то возвращает количество байт, которое можно прочитать.
В не буферизированном режиме потока может всегда возвращать 0 или false, если поток не поддерживает available.
--]]
io_stream:available(
[опционально] length: int
) -> int | boolean
--[[
Устанавливает позицию в потоке (всегда в байтах)
Режимы:
b - Задаёт позицию относительно начало файла
c - Задаёт позицию относительно текущей позиции
e - Задаёт позицию относительно конца файла
Может бросать ошибку, если поток не поддерживает seek.
--]]
io_stream:seek(
mode: string
offset: number
offset: int
)
-- Возвращает текущую позицию в потоке от начала.
-- Может бросать ошибку, если поток не поддерживает tell.
io_stream:tell() -> int
```
## Методы Buffered-режима
```lua
--[[
Если length определён, то возвращает true, если length байт доступно к чтению. Иначе возвращает false
Если не определён, то возвращает количество байт, которое можно прочитать
--]]
io_stream:available(
[опционально] length: number
) -> number | boolean
-- Возвращает максимальный размер буферов
io_stream:get_max_buffer_size() -> number
io_stream:get_max_buffer_size() -> int
-- Задаёт новый максимальный размер буферов
io_stream:set_max_buffer_size(max_size: number)
io_stream:set_max_buffer_size(max_size: int)
```
## Методы контроля состояния потока
```lua
-- Возвращает true, если поток открыт на данный момент
io_stream:is_alive() -> bool
@ -185,16 +191,27 @@ io_stream:is_closed() -> bool
io_stream:close()
-- Записывает все данные из write-буфера в поток в buffer/all flush-режимах
-- Вызывает ioLib.flush() в all flush-режиме
-- Вызывает ioLib.flush() в all flush-режиме, или ничего не делает, если
-- ioLib не поддерживает flush.
io_stream:flush()
-- Создаёт новый поток из Bytearray.
-- Может использоваться одновременно как для чтения, так и для записи.
-- Результат записи будет записан в тот же Bytearray, что был передан в функцию.
io_stream.wrap_bytearray(
buffer: Bytearray,
-- по-умолчанию равен true, поскольку функция из вводных аргументов
-- будет использоваться преимущественно для работы с двоичными данными.
[опционально] binary_mode: boolean = true
) -> io_stream
-- Создаёт новый поток с переданным дескриптором и использующим переданную I/O библиотеку. (Более подробно в core:io_stream.lua)
io_stream.new(
descriptor: int,
binaryMode: bool,
ioLib: table,
binary_mode: boolean,
io_lib: table,
[опционально] mode: string = "default",
[опционально] flushMode: string = "all"
[опционально] flush_mode: string = "all"
) -> io_stream
```