An open API service indexing awesome lists of open source software.

https://github.com/nixel2007/validate


https://github.com/nixel2007/validate

hacktoberfest

Last synced: 5 months ago
JSON representation

Awesome Lists containing this project

README

          

# validate

[![Тестирование](https://github.com/nixel2007/validate/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/nixel2007/validate/actions/workflows/test.yml?query=branch%3Amaster)
[![Quality Gate](https://sonar.openbsl.ru/api/project_badges/measure?project=validate&metric=alert_status)](https://sonar.openbsl.ru/dashboard?id=validate)
[![Coverage](https://sonar.openbsl.ru/api/project_badges/measure?project=validate&metric=coverage)](https://sonar.openbsl.ru/dashboard?id=validate)

Валидация объектов на основе правил-аннотаций для OneScript.

Библиотека позволяет описывать ограничения прямо на свойствах объектов через аннотации и выполнять проверку одним вызовом валидатора. Поддерживается проверка вложенных объектов, настраиваемые сообщения и простое расширение набора правил.

Для навигации по коллекциям используйте переключающую аннотацию `&ДляКаждого`:
- `&ДляКаждого("Значение")` — переключает контекст на элементы коллекции (значение режима можно опустить)
- `&ДляКаждого("Ключ")` — переключает контекст на ключи коллекции (только для коллекций, итерируемых как КлючИЗначение)

## Требования

- OneScript 1.9.2 или выше

## Установка

- Через OPM (OneScript Package Manager):

```bash
opm install validate
```

- Локально в проект: добавьте зависимость в ваш packagedef:

```bsl
.ЗависитОт("validate", "0.1.0")
```

## Быстрый старт

Опишите ограничения аннотациями на полях вашего объекта:

```bsl
&Заполнено(Сообщение = "Произвольное сообщение")
Перем Поле1 Экспорт;

&Заполнено
Перем Поле2 Экспорт;

&Минимум(-10)
&Максимум(10)
Перем Поле3 Экспорт;

&Валидно
Перем ВложенныйОбъект Экспорт;

&Тип("Число")
Перем Поле4 Экспорт;

// Элементы массива — строки
&Тип("Массив")
&ДляКаждого
&Тип("Строка")
Перем КоллекцияСтрок Экспорт;

// Значения структуры — числа
&Тип("Структура")
&ДляКаждого
&Тип("Число")
Перем СтруктураЧисел Экспорт;

// Ключи соответствия — числа
&Тип("Соответствие")
&ДляКаждого("Ключ")
&Тип("Число")
Перем СоответствиеЧисловыхКлючей Экспорт;
```

Выполните валидацию и выведите ошибки:

```bsl
Валидатор = Новый Валидатор;
Объект = Новый ТестовыйОбъект; // ваш класс с аннотациями

Результат = Валидатор.Валидировать(Объект);
Если Результат.Количество() > 0 Тогда
Сообщить(Валидатор.ОписаниеОшибокВалидации(Результат));
КонецЕсли;
```

Пример строки в отчете об ошибках:

```
[filled]: Объект: <ТипОбъекта>, Свойство: Поле2, Сообщение: Значение не заполнено
```

## Подробные примеры работы с Валидатором

### Пример 1: Создание класса с аннотациями

Создайте класс с аннотациями валидации:

```bsl
// Класс ПользовательДанные.os

&Заполнено(Сообщение = "Имя пользователя обязательно для заполнения")
Перем Имя Экспорт;

&Заполнено
&Минимум(18)
&Максимум(120)
Перем Возраст Экспорт;

&Заполнено
Перем Email Экспорт;

&Минимум(0)
&Максимум(100000)
Перем Зарплата Экспорт;

&Истина
Перем Активен Экспорт;
```

### Пример 2: Валидация данных (корректных и некорректных)

```bsl
// Создаем валидатор
Валидатор = Новый Валидатор;

// Сначала валидируем корректные данные
Пользователь = Новый ПользовательДанные;
Пользователь.Имя = "Иван Иванов";
Пользователь.Возраст = 30;
Пользователь.Email = "ivan@example.com";
Пользователь.Зарплата = 50000;
Пользователь.Активен = Истина;

РезультатВалидации = Валидатор.Валидировать(Пользователь);

// Проверяем результат - для корректных данных ошибок не будет
Если РезультатВалидации.Количество() = 0 Тогда
Сообщить("Данные корректны! Валидация прошла успешно.");
Иначе
Сообщить("Неожиданные ошибки при валидации корректных данных");
КонецЕсли;

// Теперь валидируем некорректные данные
НекорректныйПользователь = Новый ПользовательДанные;
НекорректныйПользователь.Имя = ""; // Пустое имя
НекорректныйПользователь.Возраст = 15; // Меньше минимума
НекорректныйПользователь.Зарплата = 150000; // Больше максимума
НекорректныйПользователь.Активен = Ложь; // Должно быть Истина

РезультатВалидации = Валидатор.Валидировать(НекорректныйПользователь);

// Выводим все ошибки
Если РезультатВалидации.Количество() > 0 Тогда
Сообщить("Найдено нарушений: " + РезультатВалидации.Количество());
Сообщить(Валидатор.ОписаниеОшибокВалидации(РезультатВалидации));
Иначе
Сообщить("Ошибка: валидация должна была найти нарушения");
КонецЕсли;
```

### Пример 3: Обработка отдельных нарушений

```bsl
// Создаем объект с ошибками
Пользователь = Новый ПользовательДанные;
Пользователь.Возраст = 200; // Превышает максимум
// Остальные поля не заполнены

РезультатВалидации = Валидатор.Валидировать(Пользователь);

// Обрабатываем каждое нарушение отдельно
Для Каждого Нарушение Из РезультатВалидации Цикл

ИмяСвойства = Нарушение.ИмяСвойства();
Сообщение = Нарушение.Сообщение();
КодОшибки = Нарушение.Код();

// Можно обрабатывать разные типы ошибок по-разному
Если КодОшибки = "filled" Тогда
Сообщить("Поле не заполнено: " + ИмяСвойства + " - " + Сообщение);
ИначеЕсли КодОшибки = "max" Тогда
Сообщить("Превышен максимум для поля: " + ИмяСвойства + " - " + Сообщение);
ИначеЕсли КодОшибки = "min" Тогда
Сообщить("Значение меньше минимума для поля: " + ИмяСвойства + " - " + Сообщение);
Иначе
Сообщить("Ошибка валидации [" + КодОшибки + "]: " + ИмяСвойства + " - " + Сообщение);
КонецЕсли;

КонецЦикла;
```

### Пример 4: Валидация вложенных объектов

```bsl
// Класс ПользовательДанные.os (сокращенная версия)
&Заполнено
Перем Имя Экспорт;

&Валидно // Эта аннотация указывает, что нужно валидировать вложенный объект
Перем Адрес Экспорт;

// Класс Адрес.os
&Заполнено
Перем Город Экспорт;

&Заполнено
&Минимум(100000)
&Максимум(999999)
Перем Индекс Экспорт;

// Создаем пользователя с адресом
Пользователь = Новый ПользовательДанные;
Пользователь.Имя = "Петр Петров";

// Создаем адрес с ошибкой
Адрес = Новый Адрес;
Адрес.Город = "Москва";
Адрес.Индекс = 12345; // Меньше минимума

Пользователь.Адрес = Адрес;

// Валидация проверит и основной объект, и вложенный
// благодаря аннотации &Валидно у поля Адрес
РезультатВалидации = Валидатор.Валидировать(Пользователь);

Если РезультатВалидации.Количество() > 0 Тогда
Сообщить("Ошибки валидации:");
Сообщить(Валидатор.ОписаниеОшибокВалидации(РезультатВалидации));
КонецЕсли;
```

## Поддерживаемые аннотации

- `&Заполнено(Сообщение = "...")` — значение поля должно быть заполнено. Код нарушения: `filled`.
- `&Истина` — булево значение должно быть Истина. Код нарушения: `true`.
- `&Ложь` — булево значение должно быть Ложь. Код нарушения: `false`.
- `&Минимум(<число>)` — значение не меньше минимума. Код нарушения: `min`.
- `&Максимум(<число>)` — значение не больше максимума. Код нарушения: `max`.
- `&Тип(<строка>)` — значение должно иметь указанный тип. Код нарушения: `type`.
- `&Валидно` — рекурсивная проверка вложенного объекта. Код нарушения: `valid`.

Переключение контекста коллекций задаётся аннотацией `&ДляКаждого`; её можно указывать несколько раз для вложенных коллекций.

Сообщение об ошибке можно переопределить параметром аннотации `Сообщение`.

### Примеры для коллекций

- Элементы массива в диапазоне 0..10:

```bsl
&Тип("Массив")
&ДляКаждого
&Тип("Число")
&Минимум(0)
&Максимум(10)
Перем МассивЧиселСДиапазоном Экспорт;
```

- Ключи соответствия больше 5 (минимум 6):

```bsl
&Тип("Соответствие")
&ДляКаждого("Ключ")
&Тип("Число")
&Минимум(6)
Перем СоответствиеКлючиБольше5 Экспорт;
```

Примечание: при `&ДляКаждого("Ключ")` для коллекций без ключей (например, `Массив`) будет выброшено исключение.

## Расширение и кастомизация

- Конструктор валидатора поддерживает подмену фабрики валидаций и контейнера аннотаций:

```bsl
Валидатор = Новый Валидатор(МояФабрикаВалидаций, МойКонтейнерАннотаций);
```

- По умолчанию используется `СтандартнаяФабрикаВалидаций`, где назначено соответствие аннотаций и классов валидаций (`ВалидацияОграниченияЗаполнено`, `...Минимум`, `...Максимум`, `...Истина`, `...Ложь`, `...Тип`, `...Валидно`).
- Можно добавлять собственные аннотации в контейнер и свои реализации классов валидаций/ограничений.

## Запуск тестов

В проект включены авто-тесты на 1testrunner. Запустить можно так:

```bash
oscript tasks/test.os
```

Результаты в формате JUnit сохраняются в каталоге `out`.

### Покрытие кода

Для прогона тестов со сбором покрытия используйте задачу из `tasks/coverage.os`:

```bash
oscript tasks/coverage.os
```

Скрипт сохранит статистику в `out/stat.json` и сформирует отчеты:

- `out/genericCoverage.xml` — Generic Coverage (используется Sonar)
- `out/cobertura.xml` — отчет в формате Cobertura (используется плагином Coverage Gutters в VSCode)

---

## Лицензия

Этот проект лицензируется под лицензией MIT. Подробности см. в файле [LICENSE.md](./LICENSE.md).