diff --git a/.github/instructions/copilot.instructions.md b/.github/instructions/copilot.instructions.md new file mode 100644 index 0000000..8ee8bd8 --- /dev/null +++ b/.github/instructions/copilot.instructions.md @@ -0,0 +1,13 @@ +## Общее + +Этот проект написан на языке 1С:Предприятие 8 и выполняется в независимой реализации виртуальной машины под названием OneScript или oscript. Документация доступна на сайте https://oscript.io, исходный код движка - https://github.com/EvilBeaver/OneScript + + +## Тестирование + +Для запуска тестов используется команда: + +```sh +oscript tasks/test.os +``` +Не запускай тесты другим способом! \ No newline at end of file diff --git a/README.md b/README.md index 5fbb72c..8931f74 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,466 @@ Добавляет в скрипт функционал "Утверждений" (assertions). Возможны 2 стиля использования: -Модуль "Утверждения" - утверждения в стиле фреймворка xUnitFor1C -Свойство глобального контекста "Ожидаем" - [fluent-API утверждений в стиле BDD](http://habrahabr.ru/post/260013/) +* **Модуль "Утверждения"** - утверждения в стиле фреймворка xUnitFor1C +* **Свойство глобального контекста "Ожидаем"** - [fluent-API утверждений в стиле BDD](http://habrahabr.ru/post/260013/) -## Пример +## Краткий пример - МояПеременная = ВычислитьЧтоТоТам(); +```bsl +МояПеременная = ВычислитьЧтоТоТам(); - // xUnit style - Утверждения.ПроверитьРавенство(1, МояПеременная, "Моя переменная должна быть строго равна 1"); - - // BDD style - Ожидаем.Что(МояПеременная).Равно(1); +// xUnit style +Утверждения.ПроверитьРавенство(1, МояПеременная, "Моя переменная должна быть строго равна 1"); + +// BDD style +Ожидаем.Что(МояПеременная).Равно(1); +``` + +## Модуль "Ожидаем" + +BDD стиль предоставляет fluent API для создания более читаемых утверждений. + +### Базовый синтаксис + +```bsl +Ожидаем.Что(ПроверяемоеЗначение).МетодПроверки(ПараметрыПроверки); +``` + +### Отрицание + +#### `Не_()` / `ЭтоНе()` + +Инвертирует результат следующей проверки. + +```bsl +Ожидаем.Что(Значение).Не_().Равно(0); +Ожидаем.Что(Строка).ЭтоНе().Заполнено(); +``` + +### Логические проверки + +#### `ЭтоИстина()` / `ЕстьИстина()` + +Проверяет, что значение равно `Истина`. + +```bsl +Ожидаем.Что(УсловиеВыполнено).ЭтоИстина(); +``` + +#### `ЭтоЛожь()` / `ЕстьЛожь()` + +Проверяет, что значение равно `Ложь`. + +```bsl +Ожидаем.Что(ОшибкаВозникла).ЭтоЛожь(); +``` + +#### `Равно(ОжидаемоеЗначение)` + +Проверяет равенство значений. + +```bsl +Ожидаем.Что(Результат).Равно(42); +Ожидаем.Что(Статус).Равно("Готов"); +``` + +### Числовые сравнения в BDD + +#### `Больше(МеньшееЗначение)` + +Проверяет, что значение больше указанного. + +```bsl +Ожидаем.Что(Количество).Больше(0); +``` + +#### `БольшеИлиРавно(МеньшееИлиРавноеЗначение)` / `Минимум(МинимальноеЗначение)` + +Проверяет, что значение больше или равно указанному. + +```bsl +Ожидаем.Что(Возраст).БольшеИлиРавно(18); +Ожидаем.Что(Зарплата).Минимум(10000); +``` + +#### `Меньше(БольшееЗначение)` + +Проверяет, что значение меньше указанного. + +```bsl +Ожидаем.Что(ВремяОтклика).Меньше(1000); +``` + +#### `МеньшеИлиРавно(БольшееИлиРавноеЗначение)` / `Максимум(МаксимальноеЗначение)` + +Проверяет, что значение меньше или равно указанному. + +```bsl +Ожидаем.Что(Оценка).МеньшеИлиРавно(10); +Ожидаем.Что(Размер).Максимум(1024); +``` + +#### `Между(НачальноеЗначение, КонечноеЗначение)` + +Проверяет, что значение находится в указанном диапазоне. + +```bsl +Ожидаем.Что(Процент).Между(0, 100); +``` + +### Проверки существования и заполненности + +#### `Заполнено()` + +Проверяет, что значение заполнено. + +```bsl +Ожидаем.Что(НомерЗаказа).Заполнено(); +``` + +#### `Существует()` + +Проверяет, что значение не равно `Неопределено` и не равно `Null`. + +```bsl +Ожидаем.Что(НайденныйЭлемент).Существует(); +``` + +#### `ЭтоНеопределено()` / `ЕстьНеопределено()` + +Проверяет, что значение равно `Неопределено`. + +```bsl +Ожидаем.Что(НеинициализированнаяПеременная).ЭтоНеопределено(); +``` + +#### `ЭтоNull()` / `ЕстьNull()` + +Проверяет, что значение равно `Null`. + +```bsl +Ожидаем.Что(ПустаяСсылка).ЭтоNull(); +``` + +### Проверки типов в BDD + +#### `ИмеетТип(ТипИлиИмяТипа)` + +Проверяет соответствие типа значения ожидаемому. + +```bsl +Ожидаем.Что(МойОбъект).ИмеетТип("Структура"); +Ожидаем.Что(СписокЗначений).ИмеетТип(Тип("Массив")); +``` + +### Работа с коллекциями + +#### `Содержит(ИскомоеЗначение)` + +Проверяет содержание элемента в коллекции или подстроки в строке. + +```bsl +// Для строк +Ожидаем.Что(ТекстОшибки).Содержит("не найден"); + +// Для массивов +Ожидаем.Что(СписокФайлов).Содержит("config.json"); + +// Для структур/соответствий - проверяет значения +Ожидаем.Что(Настройки).Содержит("Администратор"); +``` + +#### `ИмеетДлину(ОжидаемаяДлина)` + +Проверяет длину строки или количество элементов в коллекции. + +```bsl +Ожидаем.Что(Пароль).ИмеетДлину(8); +Ожидаем.Что(МассивДанных).ИмеетДлину(5); +``` + +### Проверки методов и исключений + +#### `ИмеетМетод(ИмяМетода)` + +Проверяет наличие метода у объекта. + +```bsl +Ожидаем.Что(МойОбъект).ИмеетМетод("ВыполнитьОбработку"); +``` + +#### `Метод(ИмяМетода, ПараметрыМетода).ВыбрасываетИсключение(ФрагментИсключения)` + +Проверяет, что вызов метода вызывает исключение. + +```bsl +Ожидаем.Что(КалькуляторОбъект).Метод("Разделить", Новый Массив).ВыбрасываетИсключение("деление на ноль"); +``` + +### Работа с таблицами значений + +#### `РавнаТаблице(ОжидаемоеЗначение, СравнитьТолькоСТруктуру = Ложь)` + +Сравнивает таблицы значений. + +```bsl +Ожидаем.Что(ПолученнаяТаблица).РавнаТаблице(ОжидаемаяТаблица); +``` + +#### `ИмеетРавнуюСтруктуруСТаблицей(ОжидаемоеЗначение)` + +Сравнивает только структуру таблиц (колонки и их типы). + +```bsl +Ожидаем.Что(НоваяТаблица).ИмеетРавнуюСтруктуруСТаблицей(ШаблонТаблицы); +``` + +#### `СодержитСтрокуТаблицы(ОжидаемоеЗначение)` + +Проверяет наличие строки с указанными значениями в таблице. + +```bsl +СтрокаПоиска = Новый Структура("Код, Наименование", "001", "Товар1"); +Ожидаем.Что(ТаблицаТоваров).СодержитСтрокуТаблицы(СтрокаПоиска); +``` + +### Модификаторы сравнения + +#### `БезУчетаПорядкаСтрок()` + +Игнорирует порядок строк при сравнении таблиц. + +```bsl +Ожидаем.Что(Таблица1).БезУчетаПорядкаСтрок().РавнаТаблице(Таблица2); +``` + +#### `БезУчетаПорядкаКолонок()` + +Игнорирует порядок колонок при сравнении таблиц. + +```bsl +Ожидаем.Что(Таблица1).БезУчетаПорядкаКолонок().РавнаТаблице(Таблица2); +``` + +#### `БезУчетаИменКолонок()` + +Игнорирует имена колонок при сравнении таблиц. + +```bsl +Ожидаем.Что(Таблица1).БезУчетаИменКолонок().РавнаТаблице(Таблица2); +``` + +#### `НеУчитыватьПорядокВМассиве()` + +Игнорирует порядок элементов при сравнении массивов. + +```bsl +Ожидаем.Что(Массив1).НеУчитыватьПорядокВМассиве().РавноМассиву(Массив2); +``` + +### Продвинутые сравнения + +#### `Идентично(ОжидаемоеЗначение)` + +Выполняет глубокое сравнение объектов (структур, массивов, таблиц). + +```bsl +Ожидаем.Что(СложнаяСтруктура).Идентично(ОжидаемаяСтруктура); +``` + +#### `РавноМассиву(ОжидаемоеЗначение)` + +Сравнивает массивы с детальной диагностикой различий. + +```bsl +Ожидаем.Что(ПолученныйМассив).РавноМассиву(ОжидаемыйМассив); +``` + +#### `РавноСтруктуреИлиСоответствию(ОжидаемоеЗначение)` + +Сравнивает структуры или соответствия с детальной диагностикой. + +```bsl +Ожидаем.Что(НастройкиСистемы).РавноСтруктуреИлиСоответствию(ОжидаемыеНастройки); +``` + +## Цепочки утверждений + +BDD стиль поддерживает цепочки утверждений для комплексных проверок: + +```bsl +Ожидаем.Что(Пользователь) + .ИмеетТип("Структура") + .Содержит("Администратор") + .ИмеетДлину(3); + +Ожидаем.Что(Таблица) + .БезУчетаПорядкаСтрок() + .БезУчетаПорядкаКолонок() + .РавнаТаблице(ЭталонТаблица); +``` +## Модуль "Утверждения" + +### Основные проверки + +#### `Проверить(Условие, ДопСообщениеОшибки = "")` + +Проверяет, что условие истинно. + +```bsl +Утверждения.Проверить(Истина, "Условие должно быть истинным"); +``` + +#### `ПроверитьИстину(Условие, ДопСообщениеОшибки = "")` + +Синоним для `Проверить()`. Проверяет, что значение равно `Истина`. + +```bsl +Утверждения.ПроверитьИстину(ПолучитьБулевоЗначение()); +``` + +#### `ПроверитьЛожь(Условие, ДопСообщениеОшибки = "")` + +Проверяет, что значение равно `Ложь`. + +```bsl +Утверждения.ПроверитьЛожь(ПользовательНеАвторизован); +``` + +### Сравнения значений + +#### `ПроверитьРавенство(ПервоеЗначение, ВтороеЗначение, ДопСообщениеОшибки = "")` + +Проверяет равенство двух значений. + +```bsl +Утверждения.ПроверитьРавенство(42, ПолучитьЧисло()); +Утверждения.ПроверитьРавенство("Привет", ПолучитьСтроку()); +``` + +#### `ПроверитьНеРавенство(ПервоеЗначение, ВтороеЗначение, ДопСообщениеОшибки = "")` + +Проверяет неравенство двух значений. + +```bsl +Утверждения.ПроверитьНеРавенство("", ИмяПользователя); +``` + +### Числовые сравнения + +#### `ПроверитьБольше(Больше, Меньше, ДопСообщениеОшибки = "")` + +Проверяет, что первое значение больше второго. + +```bsl +Утверждения.ПроверитьБольше(100, ПолученнаяСумма); +``` + +#### `ПроверитьБольшеИлиРавно(Больше, Меньше, ДопСообщениеОшибки = "")` + +Проверяет, что первое значение больше или равно второму. + +```bsl +Утверждения.ПроверитьБольшеИлиРавно(0, КоличествоЭлементов); +``` + +#### `ПроверитьМеньше(ПроверяемоеЗначение1, ПроверяемоеЗначение2, СообщениеОбОшибке = "")` + +Проверяет, что первое значение меньше второго. + +```bsl +Утверждения.ПроверитьМеньше(ВремяВыполнения, МаксимальноеВремя); +``` + +#### `ПроверитьМеньшеИлиРавно(ПроверяемоеЗначение1, ПроверяемоеЗначение2, СообщениеОбОшибке = "")` + +Проверяет, что первое значение меньше или равно второму. + +```bsl +Утверждения.ПроверитьМеньшеИлиРавно(РазмерФайла, МаксимальныйРазмер); +``` + +### Проверки заполненности + +#### `ПроверитьЗаполненность(ПроверяемоеЗначение, ДопСообщениеОшибки = "")` + +Проверяет, что значение заполнено (с помощью `ЗначениеЗаполнено()`). + +```bsl +Утверждения.ПроверитьЗаполненность(НомерДокумента); +Утверждения.ПроверитьЗаполненность(ДатаСоздания); +``` + +#### `ПроверитьНеЗаполненность(ПроверяемоеЗначение, ДопСообщениеОшибки = "")` + +Проверяет, что значение не заполнено. + +```bsl +Утверждения.ПроверитьНеЗаполненность(ДатаУдаления); +``` + +### Проверки типов + +#### `ПроверитьТип(Значение, ТипИлиИмяТипа, ДопСообщениеОшибки = "")` + +Проверяет соответствие типа значения ожидаемому типу. + +```bsl +Утверждения.ПроверитьТип(ПолученныйОбъект, "Структура"); +Утверждения.ПроверитьТип(ПолученныйОбъект, Тип("Массив")); +``` + +### Проверки дат + +#### `ПроверитьДату(Дата, Период, ДопСообщениеОшибки = "")` + +Проверяет, что дата входит в указанный период. + +```bsl +Период = Новый Структура("ДатаНачала, ДатаОкончания", НачалоДня(ТекущаяДата()), КонецДня(ТекущаяДата())); +Утверждения.ПроверитьДату(ДатаОперации, Период); +``` + +#### `ПроверитьРавенствоДатСТочностью2Секунды(Дата, Дата2, ДопСообщениеОшибки = "")` + +Проверяет равенство дат с точностью до 2 секунд. + +```bsl +Утверждения.ПроверитьРавенствоДатСТочностью2Секунды(ВремяВыполнения, ОжидаемоеВремя); +``` + +### Строковые проверки + +#### `ПроверитьЧтоВСтрокеСодержатсяТолькоЦифры(ИсходнаяСтрока, ДопСообщениеОшибки = "")` + +Проверяет, что строка содержит только цифры. + +```bsl +Утверждения.ПроверитьЧтоВСтрокеСодержатсяТолькоЦифры(Телефон); +``` + +#### `ПроверитьВхождение(Строка, ПодстрокаПоиска, ДопСообщениеОшибки = "")` + +Проверяет, что строка содержит указанную подстроку. + +```bsl +Утверждения.ПроверитьВхождение(ОтветСервера, "success"); +``` + +### Проверки исключений и методов + +#### `ПроверитьКодСОшибкой(Код, Ошибка, ДопСообщениеОшибки = "")` + +Проверяет, что выполнение кода вызывает ошибку с указанным текстом. + +```bsl +Утверждения.ПроверитьКодСОшибкой("ВызватьИсключение ""Тестовая ошибка""", "Тестовая ошибка"); +``` + +#### `ПроверитьМетодСуществует(Объект, ИмяМетода, ДопСообщениеОшибки = "")` + +Проверяет наличие метода у объекта. + +```bsl +Утверждения.ПроверитьМетодСуществует(МойОбъект, "ВыполнитьОбработку"); +``` \ No newline at end of file diff --git a/packagedef b/packagedef index 545c77e..b510d37 100644 --- a/packagedef +++ b/packagedef @@ -1,6 +1,6 @@  Описание.Имя("asserts") - .Версия("1.4.1") + .Версия("1.5.0") .ВерсияСреды("1.0.21") .ВключитьФайл("src") .ВключитьФайл("tests") diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\224\320\224\320\220\321\201\321\201\320\265\321\200\321\202.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\224\320\224\320\220\321\201\321\201\320\265\321\200\321\202.os" index 7402b06..b3d3bb8 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\224\320\224\320\220\321\201\321\201\320\265\321\200\321\202.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\221\320\224\320\224\320\220\321\201\321\201\320\265\321\200\321\202.os" @@ -6,11 +6,13 @@ Перем ФлагОтрицанияДляСообщения; Перем СтатусыРезультатаТестирования; Перем ПараметрыСравненияТаблиц; +Перем ПараметрыСравненияМассивов; Функция Что(Знач ПроверяемоеЗначениеПараметр, Знач Сообщение = "") Экспорт ПроверяемоеЗначение = ПроверяемоеЗначениеПараметр; ДопСообщениеОшибки = Сообщение; ФлагОтрицания = Ложь; + ФлагОтрицанияДляСообщения = Ложь; Возврат ЭтотОбъект; КонецФункции @@ -19,6 +21,7 @@ ПроверяемоеЗначение = ПроверяемоеЗначениеПараметр; ДопСообщениеОшибки = Сообщение; ФлагОтрицания = Ложь; + ФлагОтрицанияДляСообщения = Ложь; СтатусыРезультатаТестирования = Новый Структура; СтатусыРезультатаТестирования.Вставить("ОшибкаПроверки", "Failed"); @@ -29,6 +32,9 @@ ПараметрыСравненияТаблиц.Вставить("УчитыватьПорядокСтрок", Истина); ПараметрыСравненияТаблиц.Вставить("УчитыватьПорядокКолонок", Истина); ПараметрыСравненияТаблиц.Вставить("УчитыватьИменаКолонок", Истина); + + ПараметрыСравненияМассивов = Новый Структура; + ПараметрыСравненияМассивов.Вставить("УчитыватьПорядокЗначений", Истина); КонецПроцедуры Функция Не_() Экспорт @@ -374,6 +380,350 @@ Возврат ЭтотОбъект; КонецФункции +Функция НеУчитыватьПорядокВМассиве() Экспорт + ПараметрыСравненияМассивов.Вставить("УчитыватьПорядокЗначений", Ложь); + + Возврат ЭтотОбъект; +КонецФункции + +Функция Идентично(Знач ОжидаемоеЗначение) Экспорт + + ТипОжидаемогоЗначения = ТипЗнч(ОжидаемоеЗначение); + ТипПроверяемогоЗначения = ТипЗнч(ПроверяемоеЗначение); + + // Проверяем соответствие типов + Если ТипПроверяемогоЗначения <> ТипОжидаемогоЗначения тогда + СообщениеОшибки = СформироватьСообщениеОбОшибке(Строка(ПроверяемоеЗначение), СтрШаблон("Будет идентично (%1)", ОжидаемоеЗначение)); + СообщениеОшибки = СообщениеОшибки + СтрШаблон("%3 Тип проверяемого значения (%1) НЕ РАВЕН типу ожидаемого значения (%2).", + ТипПроверяемогоЗначения, ТипОжидаемогоЗначения, Символы.ПС); + ВызватьОшибкуПроверки(СообщениеОшибки); + КонецЕсли; + + // Направляем в соответствующие методы в зависимости от типа + Если ТипОжидаемогоЗначения = Тип("ТаблицаЗначений") тогда + РавнаТаблице(ОжидаемоеЗначение, Ложь); + ИначеЕсли ТипОжидаемогоЗначения = Тип("Массив") тогда + РавноМассиву(ОжидаемоеЗначение); + ИначеЕсли ТипОжидаемогоЗначения = Тип("Структура") + Или ТипОжидаемогоЗначения = Тип("Соответствие") тогда + РавноСтруктуреИлиСоответствию(ОжидаемоеЗначение); + Иначе + // Для примитивных типов используем обычное сравнение + Равно(ОжидаемоеЗначение); + КонецЕсли; + + Возврат ЭтотОбъект; +КонецФункции + +Функция РавноМассиву(Знач ОжидаемоеЗначение) Экспорт + + Если Не ТипЗнч(ОжидаемоеЗначение) = Тип("Массив") тогда + СообщениеОшибки = СформироватьСообщениеОбОшибке(ОжидаемоеЗначение, "ИМЕЕТ ТИП <Массив>."); + ВызватьОшибкуПроверки(СообщениеОшибки); + КонецЕсли; + + // Используем функцию с детализацией + РезультатСравнения = МассивыИдентичныСДетализацией(ПроверяемоеЗначение, ОжидаемоеЗначение, ""); + Если Не ЛогическоеВыражениеВерно(РезультатСравнения.Идентичны) тогда + СообщениеОшибки = СформироватьСообщениеОбОшибке(ПроверяемоеЗначение, СтрШаблон("РАВНО массиву (%1)%2%3", + ОжидаемоеЗначение, Символы.ПС, РезультатСравнения.ОписаниеОшибки)); + ВызватьОшибкуПроверки(СообщениеОшибки); + КонецЕсли; + + Возврат ЭтотОбъект; +КонецФункции + +Функция РавноСтруктуреИлиСоответствию(Знач ОжидаемоеЗначение) Экспорт + + ТипОжидаемогоЗначения = ТипЗнч(ОжидаемоеЗначение); + Если Не (ТипОжидаемогоЗначения = Тип("Структура") + Или ТипОжидаемогоЗначения = Тип("Соответствие")) тогда + СообщениеОшибки = СформироватьСообщениеОбОшибке(ОжидаемоеЗначение, "ИМЕЕТ ТИП <Структура> или <Соответствие>."); + ВызватьОшибкуПроверки(СообщениеОшибки); + КонецЕсли; + + // Используем функцию с детализацией + РезультатСравнения = СтруктурыИлиСоответствияИдентичныСДетализацией(ПроверяемоеЗначение, ОжидаемоеЗначение, ""); + Если Не ЛогическоеВыражениеВерно(РезультатСравнения.Идентичны) тогда + ТипНазвание = ?(ТипОжидаемогоЗначения = Тип("Структура"), "структуре", "соответствию"); + СообщениеОшибки = СформироватьСообщениеОбОшибке(ПроверяемоеЗначение, СтрШаблон("РАВНО %1 (%2)%3%4", + ТипНазвание, ОжидаемоеЗначение, Символы.ПС, РезультатСравнения.ОписаниеОшибки)); + ВызватьОшибкуПроверки(СообщениеОшибки); + КонецЕсли; + + Возврат ЭтотОбъект; +КонецФункции + +// Проверяет идентичность массивов с детализацией ошибок +// Параметры: +// Массив1 - Массив - первый массив для сравнения +// Массив2 - Массив - второй массив для сравнения +// ПутьКЭлементу - Строка - путь к текущему элементу для отчета об ошибке +// Возвращаемое значение: +// Структура - результат сравнения с полями Идентичны (Булево) и ОписаниеОшибки (Строка) +Функция МассивыИдентичныСДетализацией(Знач Массив1, Знач Массив2, Знач ПутьКЭлементу) + + Результат = Новый Структура("Идентичны, ОписаниеОшибки", Истина, ""); + + // Проверяем типы + Если ТипЗнч(Массив1) <> Тип("Массив") Или ТипЗнч(Массив2) <> Тип("Массив") тогда + Результат.Идентичны = Ложь; + Результат.ОписаниеОшибки = СтрШаблон("Различие в %1: ожидался массив, но получен %2 и %3", + ?(ПутьКЭлементу = "", "корне", ПутьКЭлементу), ТипЗнч(Массив1), ТипЗнч(Массив2)); + Возврат Результат; + КонецЕсли; + + // Проверяем длину + Если Массив1.Количество() <> Массив2.Количество() тогда + Результат.Идентичны = Ложь; + Результат.ОписаниеОшибки = СтрШаблон("Различие в %1: разное количество элементов - ожидалось %2, получено %3", + ?(ПутьКЭлементу = "", "корне", ПутьКЭлементу), Массив2.Количество(), Массив1.Количество()); + Возврат Результат; + КонецЕсли; + + УчитыватьПорядокЗначений = Истина; + Если ПараметрыСравненияМассивов.Свойство("УчитыватьПорядокЗначений") тогда + УчитыватьПорядокЗначений = ПараметрыСравненияМассивов.УчитыватьПорядокЗначений; + КонецЕсли; + + Если УчитыватьПорядокЗначений тогда + // Проверяем все элементы по порядку + Для Индекс = 0 По Массив1.Количество() - 1 Цикл + НовыйПуть = ?(ПутьКЭлементу = "", СтрШаблон("[%1]", Индекс), СтрШаблон("%1[%2]", ПутьКЭлементу, Индекс)); + РезультатСравненияЭлемента = ЭлементыИдентичныСДетализацией(Массив1[Индекс], Массив2[Индекс], НовыйПуть); + Если Не РезультатСравненияЭлемента.Идентичны тогда + Результат.Идентичны = Ложь; + Результат.ОписаниеОшибки = РезультатСравненияЭлемента.ОписаниеОшибки; + Возврат Результат; + КонецЕсли; + КонецЦикла; + Иначе + // Сравниваем элементы без учета порядка (упрощенная реализация для детализации) + ОжидаемыеЭлементы = Новый Массив; + Для Каждого Элемент Из Массив2 Цикл + ОжидаемыеЭлементы.Добавить(Элемент); + КонецЦикла; + + Для ИндексФакт = 0 По Массив1.Количество() - 1 Цикл + ФактическийЭлемент = Массив1[ИндексФакт]; + НайденИндекс = -1; + Для ИндексОжид = 0 По ОжидаемыеЭлементы.Количество() - 1 Цикл + РезультатСравненияБазовый = ЭлементыИдентичныСДетализацией(ФактическийЭлемент, ОжидаемыеЭлементы[ИндексОжид], ""); + Если РезультатСравненияБазовый.Идентичны тогда + НайденИндекс = ИндексОжид; + Прервать; + КонецЕсли; + КонецЦикла; + + Если НайденИндекс = -1 тогда + Результат.Идентичны = Ложь; + НовыйПуть = ?(ПутьКЭлементу = "", СтрШаблон("[%1]", ИндексФакт), СтрШаблон("%1[%2]", ПутьКЭлементу, ИндексФакт)); + Результат.ОписаниеОшибки = СтрШаблон("Элемент %1 со значением %2 не найден в ожидаемом массиве", + НовыйПуть, КраткоеПредставлениеЗначения(ФактическийЭлемент)); + Возврат Результат; + Иначе + ОжидаемыеЭлементы.Удалить(НайденИндекс); + КонецЕсли; + КонецЦикла; + КонецЕсли; + + Возврат Результат; +КонецФункции + +// Проверяет идентичность структур или соответствий с детализацией ошибок +// Параметры: +// Объект1 - Структура, Соответствие - первый объект для сравнения +// Объект2 - Структура, Соответствие - второй объект для сравнения +// ПутьКЭлементу - Строка - путь к текущему элементу для отчета об ошибке +// Возвращаемое значение: +// Структура - результат сравнения с полями Идентичны (Булево) и ОписаниеОшибки (Строка) +Функция СтруктурыИлиСоответствияИдентичныСДетализацией(Знач Объект1, Знач Объект2, Знач ПутьКЭлементу) + + Результат = Новый Структура("Идентичны, ОписаниеОшибки", Истина, ""); + + ТипОбъекта1 = ТипЗнч(Объект1); + ТипОбъекта2 = ТипЗнч(Объект2); + + // Проверяем типы + Если ТипОбъекта1 <> ТипОбъекта2 тогда + Результат.Идентичны = Ложь; + Результат.ОписаниеОшибки = СтрШаблон("Различие в %1: ожидался %2, получен %3", + ?(ПутьКЭлементу = "", "корне", ПутьКЭлементу), ТипОбъекта2, ТипОбъекта1); + Возврат Результат; + КонецЕсли; + + Если Не (ТипОбъекта1 = Тип("Структура") Или ТипОбъекта1 = Тип("Соответствие")) тогда + Результат.Идентичны = Ложь; + Результат.ОписаниеОшибки = СтрШаблон("Различие в %1: ожидались структура или соответствие, получен %2", + ?(ПутьКЭлементу = "", "корне", ПутьКЭлементу), ТипОбъекта1); + Возврат Результат; + КонецЕсли; + + // Проверяем количество элементов + Если Объект1.Количество() <> Объект2.Количество() тогда + Результат.Идентичны = Ложь; + Результат.ОписаниеОшибки = СтрШаблон("Различие в %1: разное количество элементов - ожидалось %2, получено %3", + ?(ПутьКЭлементу = "", "корне", ПутьКЭлементу), Объект2.Количество(), Объект1.Количество()); + Возврат Результат; + КонецЕсли; + + // Проверяем все ключи и значения + Для Каждого КлючЗначение Из Объект2 Цикл + Ключ = КлючЗначение.Ключ; + ОжидаемоеЗначение = КлючЗначение.Значение; + + Если Не СодержитКлюч(Объект1, Ключ) тогда + Результат.Идентичны = Ложь; + НовыйПуть = ?(ПутьКЭлементу = "", СтрШаблон(".%1", Ключ), СтрШаблон("%1.%2", ПутьКЭлементу, Ключ)); + Результат.ОписаниеОшибки = СтрШаблон("Ключ %1 отсутствует в фактическом объекте", НовыйПуть); + Возврат Результат; + КонецЕсли; + + ФактическоеЗначение = ПолучитьЗначениеПоКлючу(Объект1, Ключ); + НовыйПуть = ?(ПутьКЭлементу = "", СтрШаблон(".%1", Ключ), СтрШаблон("%1.%2", ПутьКЭлементу, Ключ)); + РезультатСравненияЗначения = ЭлементыИдентичныСДетализацией(ФактическоеЗначение, ОжидаемоеЗначение, НовыйПуть); + Если Не РезультатСравненияЗначения.Идентичны тогда + Результат.Идентичны = Ложь; + Результат.ОписаниеОшибки = РезультатСравненияЗначения.ОписаниеОшибки; + Возврат Результат; + КонецЕсли; + КонецЦикла; + + // Проверяем, что в фактическом объекте нет лишних ключей + Для Каждого КлючЗначение Из Объект1 Цикл + Ключ = КлючЗначение.Ключ; + Если Не СодержитКлюч(Объект2, Ключ) тогда + Результат.Идентичны = Ложь; + НовыйПуть = ?(ПутьКЭлементу = "", СтрШаблон(".%1", Ключ), СтрШаблон("%1.%2", ПутьКЭлементу, Ключ)); + Результат.ОписаниеОшибки = СтрШаблон("Лишний ключ %1 в фактическом объекте", НовыйПуть); + Возврат Результат; + КонецЕсли; + КонецЦикла; + + Возврат Результат; +КонецФункции + +// Рекурсивно проверяет идентичность двух элементов с детализацией ошибок +// Параметры: +// Элемент1 - Произвольный - первый элемент для сравнения +// Элемент2 - Произвольный - второй элемент для сравнения +// ПутьКЭлементу - Строка - путь к текущему элементу для отчета об ошибке +// Возвращаемое значение: +// Структура - результат сравнения с полями Идентичны (Булево) и ОписаниеОшибки (Строка) +Функция ЭлементыИдентичныСДетализацией(Знач Элемент1, Знач Элемент2, Знач ПутьКЭлементу) + + Результат = Новый Структура("Идентичны, ОписаниеОшибки", Истина, ""); + + ТипЭлемента1 = ТипЗнч(Элемент1); + ТипЭлемента2 = ТипЗнч(Элемент2); + + // Сначала проверяем типы + Если ТипЭлемента1 <> ТипЭлемента2 тогда + Результат.Идентичны = Ложь; + Результат.ОписаниеОшибки = СтрШаблон("Различие в %1: ожидался %2, получен %3", + ?(ПутьКЭлементу = "", "корне", ПутьКЭлементу), ТипЭлемента2, ТипЭлемента1); + Возврат Результат; + КонецЕсли; + + // Для структур и соответствий + Если ТипЭлемента1 = Тип("Структура") Или ТипЭлемента1 = Тип("Соответствие") тогда + Возврат СтруктурыИлиСоответствияИдентичныСДетализацией(Элемент1, Элемент2, ПутьКЭлементу); + КонецЕсли; + + // Для массивов + Если ТипЭлемента1 = Тип("Массив") тогда + Возврат МассивыИдентичныСДетализацией(Элемент1, Элемент2, ПутьКЭлементу); + КонецЕсли; + + // Для таблиц значений + Если ТипЭлемента1 = Тип("ТаблицаЗначений") тогда + // Используем существующую логику сравнения таблиц без детализации + Различия = РазличияТаблиц(Элемент1, Элемент2, Ложь); + Если Различия.Количество() > 0 тогда + Результат.Идентичны = Ложь; + Результат.ОписаниеОшибки = СтрШаблон("Различие в %1: таблицы значений не идентичны", + ?(ПутьКЭлементу = "", "корне", ПутьКЭлементу)); + КонецЕсли; + Возврат Результат; + КонецЕсли; + + // Для остальных типов - простое сравнение + Если Элемент1 <> Элемент2 тогда + Результат.Идентичны = Ложь; + Результат.ОписаниеОшибки = СтрШаблон("Различие в %1: ожидалось %2, получено %3", + ?(ПутьКЭлементу = "", "корне", ПутьКЭлементу), + КраткоеПредставлениеЗначения(Элемент2), + КраткоеПредставлениеЗначения(Элемент1)); + КонецЕсли; + + Возврат Результат; +КонецФункции + +// Возвращает краткое представление значения для сообщений об ошибках +// Параметры: +// Значение - Произвольный - значение для представления +// Возвращаемое значение: +// Строка - краткое представление значения +Функция КраткоеПредставлениеЗначения(Знач Значение) + + ТипЗначения = ТипЗнч(Значение); + + Если Значение = Неопределено тогда + Возврат "Неопределено"; + ИначеЕсли ТипЗначения = Тип("Строка") тогда + Если СтрДлина(Значение) > 50 тогда + Возврат """" + Лев(Значение, 47) + "..."""; + Иначе + Возврат """" + Значение + """"; + КонецЕсли; + ИначеЕсли ТипЗначения = Тип("Число") Или ТипЗначения = Тип("Булево") тогда + Возврат Строка(Значение); + ИначеЕсли ТипЗначения = Тип("Дата") тогда + Возврат Формат(Значение, "ДФ=dd.MM.yyyy ВФ=HH:mm:ss"); + ИначеЕсли ТипЗначения = Тип("Массив") тогда + Возврат СтрШаблон("Массив(%1)", Значение.Количество()); + ИначеЕсли ТипЗначения = Тип("Структура") тогда + Возврат СтрШаблон("Структура(%1)", Значение.Количество()); + ИначеЕсли ТипЗначения = Тип("Соответствие") тогда + Возврат СтрШаблон("Соответствие(%1)", Значение.Количество()); + ИначеЕсли ТипЗначения = Тип("ТаблицаЗначений") тогда + Возврат СтрШаблон("ТаблицаЗначений(%1х%2)", Значение.Количество(), Значение.Колонки.Количество()); + Иначе + Возврат Строка(ТипЗначения); + КонецЕсли; + +КонецФункции + +// Проверяет содержит ли объект указанный ключ +Функция СодержитКлюч(Знач Объект, Знач Ключ) + + ТипОбъекта = ТипЗнч(Объект); + + Если ТипОбъекта = Тип("Структура") тогда + Возврат Объект.Свойство(Ключ); + ИначеЕсли ТипОбъекта = Тип("Соответствие") тогда + Возврат Объект.Получить(Ключ) <> Неопределено; + Иначе + ВызватьИсключение "Неподдерживаемый тип объекта для проверки ключа: " + ТипОбъекта; + КонецЕсли; + +КонецФункции + +// Получает значение по ключу из объекта +Функция ПолучитьЗначениеПоКлючу(Знач Объект, Знач Ключ) + + ТипОбъекта = ТипЗнч(Объект); + + Если ТипОбъекта = Тип("Структура") тогда + Возврат Объект[Ключ]; + ИначеЕсли ТипОбъекта = Тип("Соответствие") тогда + Возврат Объект.Получить(Ключ); + Иначе + ВызватьИсключение "Неподдерживаемый тип объекта для получения значения по ключу: " + ТипОбъекта; + КонецЕсли; + +КонецФункции + // { Helpers Функция ФорматДСО(Знач ДопСообщениеОшибки) Если ДопСообщениеОшибки = "" Тогда diff --git a/tests/bdd-assertions-identity-tests.os b/tests/bdd-assertions-identity-tests.os new file mode 100644 index 0000000..13e11c8 --- /dev/null +++ b/tests/bdd-assertions-identity-tests.os @@ -0,0 +1,1313 @@ +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьСтроки() Экспорт + // Arrange + ОжидаемоеЗначение = "Привет, мир!"; + ФактическоеЗначение = "Привет, мир!"; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьСтроки() Экспорт + // Arrange + ОжидаемоеЗначение = "Привет, мир!"; + ФактическоеЗначение = "Привет, Вася!"; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьЧисел() Экспорт + // Arrange + ОжидаемоеЗначение = 42; + ФактическоеЗначение = 42; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьБулевыхЗначений() Экспорт + // Act & Assert + Ожидаем.Что(Истина).Идентично(Истина); + Ожидаем.Что(Ложь).Идентично(Ложь); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьДат() Экспорт + // Arrange + ОжидаемоеЗначение = Дата("20250709120000"); + ФактическоеЗначение = Дата("20250709120000"); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьНеопределено() Экспорт + // Arrange + ОжидаемоеЗначение = Неопределено; + ФактическоеЗначение = Неопределено; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Выбросить_Исключение_При_Разных_Типах() Экспорт + // Arrange + ПроверяемоеЗначение = "123"; + ОжидаемоеЗначение = 123; + + // Act & Assert + Попытка + Ожидаем.Что(ПроверяемоеЗначение).Идентично(ОжидаемоеЗначение); + Исключение + // Ожидаемое поведение - исключение должно быть выброшено при сравнении разных типов + Если СтрНайти(ИнформацияОбОшибке().Описание, "НЕ РАВЕН типу ожидаемого значения") > 0 Тогда + Возврат; + КонецЕсли; + КонецПопытки; + + ВызватьИсключение "Ожидали, что будет выброшено исключение при сравнении разных типов, а это не так"; +КонецПроцедуры + +// Тесты для массивов + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьПустыхМассивов() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Массив; + ФактическоеЗначение = Новый Массив; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьМассивов() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить("элемент1"); + ОжидаемоеЗначение.Добавить("элемент2"); + ОжидаемоеЗначение.Добавить(123); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить("элемент1"); + ФактическоеЗначение.Добавить("элемент2"); + ФактическоеЗначение.Добавить(123); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьМассивовРазнойДлины() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить("элемент1"); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить("элемент1"); + ФактическоеЗначение.Добавить("элемент2"); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьМассивовСРазнымиЭлементами() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить("элемент1"); + ОжидаемоеЗначение.Добавить("элемент2"); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить("элемент1"); + ФактическоеЗначение.Добавить("элемент3"); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьВложенныхМассивов() Экспорт + // Arrange + ВложенныйМассив1 = Новый Массив; + ВложенныйМассив1.Добавить("вложенный1"); + ВложенныйМассив1.Добавить("вложенный2"); + + ВложенныйМассив2 = Новый Массив; + ВложенныйМассив2.Добавить("вложенный1"); + ВложенныйМассив2.Добавить("вложенный2"); + + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить("элемент1"); + ОжидаемоеЗначение.Добавить(ВложенныйМассив1); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить("элемент1"); + ФактическоеЗначение.Добавить(ВложенныйМассив2); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_БезУчетаПорядкаЗначений() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить("элемент1"); + ОжидаемоеЗначение.Добавить("элемент2"); + ОжидаемоеЗначение.Добавить("элемент3"); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить("элемент3"); + ФактическоеЗначение.Добавить("элемент1"); + ФактическоеЗначение.Добавить("элемент2"); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).НеУчитыватьПорядокВМассиве().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +// Тесты для структур + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьПустыхСтруктур() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Структура; + ФактическоеЗначение = Новый Структура; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьСтруктур() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("Ключ1", "Значение1"); + ОжидаемоеЗначение.Вставить("Ключ2", 123); + ОжидаемоеЗначение.Вставить("Ключ3", Истина); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("Ключ1", "Значение1"); + ФактическоеЗначение.Вставить("Ключ2", 123); + ФактическоеЗначение.Вставить("Ключ3", Истина); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьСтруктурСРазнымиКлючами() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("Ключ1", "Значение1"); + ОжидаемоеЗначение.Вставить("Ключ2", 123); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("Ключ1", "Значение1"); + ФактическоеЗначение.Вставить("Ключ3", 123); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьСтруктурСРазнымиЗначениями() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("Ключ1", "Значение1"); + ОжидаемоеЗначение.Вставить("Ключ2", 123); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("Ключ1", "Значение1"); + ФактическоеЗначение.Вставить("Ключ2", 456); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьВложенныхСтруктур() Экспорт + // Arrange + ВложеннаяСтруктура1 = Новый Структура; + ВложеннаяСтруктура1.Вставить("ВложенныйКлюч", "ВложенноеЗначение"); + + ВложеннаяСтруктура2 = Новый Структура; + ВложеннаяСтруктура2.Вставить("ВложенныйКлюч", "ВложенноеЗначение"); + + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("Ключ1", "Значение1"); + ОжидаемоеЗначение.Вставить("Структура", ВложеннаяСтруктура1); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("Ключ1", "Значение1"); + ФактическоеЗначение.Вставить("Структура", ВложеннаяСтруктура2); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +// Тесты для соответствий + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьПустыхСоответствий() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Соответствие; + ФактическоеЗначение = Новый Соответствие; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьСоответствий() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Соответствие; + ОжидаемоеЗначение.Вставить("Ключ1", "Значение1"); + ОжидаемоеЗначение.Вставить("Ключ2", 123); + + ФактическоеЗначение = Новый Соответствие; + ФактическоеЗначение.Вставить("Ключ1", "Значение1"); + ФактическоеЗначение.Вставить("Ключ2", 123); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьСоответствий() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Соответствие; + ОжидаемоеЗначение.Вставить("Ключ1", "Значение1"); + ОжидаемоеЗначение.Вставить("Ключ2", 123); + + ФактическоеЗначение = Новый Соответствие; + ФактическоеЗначение.Вставить("Ключ1", "Значение1"); + ФактическоеЗначение.Вставить("Ключ2", 456); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +// Тесты для таблиц значений + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьПустыхТаблиц() Экспорт + // Arrange + ОжидаемоеЗначение = Новый ТаблицаЗначений; + ФактическоеЗначение = Новый ТаблицаЗначений; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьТаблиц() Экспорт + // Arrange + ОжидаемоеЗначение = Новый ТаблицаЗначений; + ОжидаемоеЗначение.Колонки.Добавить("Колонка1", Новый ОписаниеТипов("Строка")); + ОжидаемоеЗначение.Колонки.Добавить("Колонка2", Новый ОписаниеТипов("Число")); + + НоваяСтрока = ОжидаемоеЗначение.Добавить(); + НоваяСтрока.Колонка1 = "Значение1"; + НоваяСтрока.Колонка2 = 123; + + ФактическоеЗначение = Новый ТаблицаЗначений; + ФактическоеЗначение.Колонки.Добавить("Колонка1", Новый ОписаниеТипов("Строка")); + ФактическоеЗначение.Колонки.Добавить("Колонка2", Новый ОписаниеТипов("Число")); + + НоваяСтрока = ФактическоеЗначение.Добавить(); + НоваяСтрока.Колонка1 = "Значение1"; + НоваяСтрока.Колонка2 = 123; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьТаблиц() Экспорт + // Arrange + ОжидаемоеЗначение = Новый ТаблицаЗначений; + ОжидаемоеЗначение.Колонки.Добавить("Колонка1", Новый ОписаниеТипов("Строка")); + + НоваяСтрока = ОжидаемоеЗначение.Добавить(); + НоваяСтрока.Колонка1 = "Значение1"; + + ФактическоеЗначение = Новый ТаблицаЗначений; + ФактическоеЗначение.Колонки.Добавить("Колонка1", Новый ОписаниеТипов("Строка")); + + НоваяСтрока = ФактическоеЗначение.Добавить(); + НоваяСтрока.Колонка1 = "Значение2"; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +// Тесты с отрицанием + +&Тест +Процедура ТестДолжен_Проверить_ОтрицаниеИдентичности() Экспорт + // Arrange + ОжидаемоеЗначение = "Привет, мир!"; + ФактическоеЗначение = "Привет, Вася!"; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); + Ожидаем.Что(ФактическоеЗначение).ЭтоНе().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +// Сложные тесты для комбинированных структур данных + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьСложныхВложенныхСтруктур() Экспорт + // Arrange + ВложеннаяСтруктура1 = Новый Структура; + ВложеннаяСтруктура1.Вставить("ИмяПользователя", "Иван"); + ВложеннаяСтруктура1.Вставить("Возраст", 25); + ВложеннаяСтруктура1.Вставить("Активен", Истина); + + МассивПравИдентичности1 = Новый Массив; + МассивПравИдентичности1.Добавить("Чтение"); + МассивПравИдентичности1.Добавить("Запись"); + МассивПравИдентичности1.Добавить("Удаление"); + + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("Пользователь", ВложеннаяСтруктура1); + ОжидаемоеЗначение.Вставить("Права", МассивПравИдентичности1); + ОжидаемоеЗначение.Вставить("ДатаСоздания", '20250101000000'); + + // Создаем идентичную структуру + ВложеннаяСтруктура2 = Новый Структура; + ВложеннаяСтруктура2.Вставить("ИмяПользователя", "Иван"); + ВложеннаяСтруктура2.Вставить("Возраст", 25); + ВложеннаяСтруктура2.Вставить("Активен", Истина); + + МассивПравИдентичности2 = Новый Массив; + МассивПравИдентичности2.Добавить("Чтение"); + МассивПравИдентичности2.Добавить("Запись"); + МассивПравИдентичности2.Добавить("Удаление"); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("Пользователь", ВложеннаяСтруктура2); + ФактическоеЗначение.Вставить("Права", МассивПравИдентичности2); + ФактическоеЗначение.Вставить("ДатаСоздания", '20250101000000'); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьСложныхВложенныхСтруктурСРазнымиЗначениями() Экспорт + // Arrange + ВложеннаяСтруктура1 = Новый Структура; + ВложеннаяСтруктура1.Вставить("ИмяПользователя", "Иван"); + ВложеннаяСтруктура1.Вставить("Возраст", 25); + + МассивПрав1 = Новый Массив; + МассивПрав1.Добавить("Чтение"); + МассивПрав1.Добавить("Запись"); + + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("Пользователь", ВложеннаяСтруктура1); + ОжидаемоеЗначение.Вставить("Права", МассивПрав1); + + // Создаем структуру с другими значениями во вложенном объекте + ВложеннаяСтруктура2 = Новый Структура; + ВложеннаяСтруктура2.Вставить("ИмяПользователя", "Петр"); // Отличается! + ВложеннаяСтруктура2.Вставить("Возраст", 25); + + МассивПрав2 = Новый Массив; + МассивПрав2.Добавить("Чтение"); + МассивПрав2.Добавить("Запись"); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("Пользователь", ВложеннаяСтруктура2); + ФактическоеЗначение.Вставить("Права", МассивПрав2); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьМассивовСВложеннымиСтруктурами() Экспорт + // Arrange + Структура1 = Новый Структура; + Структура1.Вставить("ID", 1); + Структура1.Вставить("Название", "Первый элемент"); + + Структура2 = Новый Структура; + Структура2.Вставить("ID", 2); + Структура2.Вставить("Название", "Второй элемент"); + + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить(Структура1); + ОжидаемоеЗначение.Добавить(Структура2); + + // Создаем идентичные структуры + Структура3 = Новый Структура; + Структура3.Вставить("ID", 1); + Структура3.Вставить("Название", "Первый элемент"); + + Структура4 = Новый Структура; + Структура4.Вставить("ID", 2); + Структура4.Вставить("Название", "Второй элемент"); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить(Структура3); + ФактическоеЗначение.Добавить(Структура4); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьМассивовСВложеннымиСтруктурамиБезУчетаПорядка() Экспорт + // Arrange + Структура1 = Новый Структура; + Структура1.Вставить("ID", 1); + Структура1.Вставить("Название", "Первый элемент"); + + Структура2 = Новый Структура; + Структура2.Вставить("ID", 2); + Структура2.Вставить("Название", "Второй элемент"); + + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить(Структура1); + ОжидаемоеЗначение.Добавить(Структура2); + + // Создаем идентичные структуры в другом порядке + Структура3 = Новый Структура; + Структура3.Вставить("ID", 2); + Структура3.Вставить("Название", "Второй элемент"); + + Структура4 = Новый Структура; + Структура4.Вставить("ID", 1); + Структура4.Вставить("Название", "Первый элемент"); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить(Структура3); // Второй + ФактическоеЗначение.Добавить(Структура4); // Первый + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).НеУчитыватьПорядокВМассиве().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьСоответствийСВложеннымиМассивами() Экспорт + // Arrange + Массив1 = Новый Массив; + Массив1.Добавить("элемент1"); + Массив1.Добавить("элемент2"); + + Массив2 = Новый Массив; + Массив2.Добавить(100); + Массив2.Добавить(200); + + ОжидаемоеЗначение = Новый Соответствие; + ОжидаемоеЗначение.Вставить("Строки", Массив1); + ОжидаемоеЗначение.Вставить("Числа", Массив2); + + // Создаем идентичные массивы + Массив3 = Новый Массив; + Массив3.Добавить("элемент1"); + Массив3.Добавить("элемент2"); + + Массив4 = Новый Массив; + Массив4.Добавить(100); + Массив4.Добавить(200); + + ФактическоеЗначение = Новый Соответствие; + ФактическоеЗначение.Вставить("Строки", Массив3); + ФактическоеЗначение.Вставить("Числа", Массив4); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьГлубокоВложенныхСтруктур() Экспорт + // Arrange - создаем структуру с 3 уровнями вложенности + УровеньТрети = Новый Структура; + УровеньТрети.Вставить("ГлубокоеЗначение", "Самый внутренний"); + + УровеньВторой = Новый Структура; + УровеньВторой.Вставить("ВторойУровень", "Средний"); + УровеньВторой.Вставить("Вложенный", УровеньТрети); + + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("ПервыйУровень", "Внешний"); + ОжидаемоеЗначение.Вставить("Вложенный", УровеньВторой); + + // Создаем идентичную структуру + УровеньТретиКопия = Новый Структура; + УровеньТретиКопия.Вставить("ГлубокоеЗначение", "Самый внутренний"); + + УровеньВторойКопия = Новый Структура; + УровеньВторойКопия.Вставить("ВторойУровень", "Средний"); + УровеньВторойКопия.Вставить("Вложенный", УровеньТретиКопия); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("ПервыйУровень", "Внешний"); + ФактическоеЗначение.Вставить("Вложенный", УровеньВторойКопия); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьГлубокоВложенныхСтруктурСОтличиемВГлубине() Экспорт + // Arrange - создаем структуру с 3 уровнями вложенности + УровеньТрети1 = Новый Структура; + УровеньТрети1.Вставить("ГлубокоеЗначение", "Самый внутренний"); + + УровеньВторой1 = Новый Структура; + УровеньВторой1.Вставить("ВторойУровень", "Средний"); + УровеньВторой1.Вставить("Вложенный", УровеньТрети1); + + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("ПервыйУровень", "Внешний"); + ОжидаемоеЗначение.Вставить("Вложенный", УровеньВторой1); + + // Создаем структуру с отличием на самом глубоком уровне + УровеньТрети2 = Новый Структура; + УровеньТрети2.Вставить("ГлубокоеЗначение", "Другое внутреннее значение"); // Отличается! + + УровеньВторой2 = Новый Структура; + УровеньВторой2.Вставить("ВторойУровень", "Средний"); + УровеньВторой2.Вставить("Вложенный", УровеньТрети2); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("ПервыйУровень", "Внешний"); + ФактическоеЗначение.Вставить("Вложенный", УровеньВторой2); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьСмешанныхТиповДанных() Экспорт + // Arrange - создаем структуру со всеми типами данных + МассивРазныхТипов = Новый Массив; + МассивРазныхТипов.Добавить("Строка"); + МассивРазныхТипов.Добавить(42); + МассивРазныхТипов.Добавить(Истина); + МассивРазныхТипов.Добавить('20250101000000'); + МассивРазныхТипов.Добавить(Неопределено); + + ВложеннаяСтруктура = Новый Структура; + ВложеннаяСтруктура.Вставить("Ключ", "Значение"); + + ВложенноеСоответствие = Новый Соответствие; + ВложенноеСоответствие.Вставить("СоответствиеКлюч", "СоответствиеЗначение"); + + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("Массив", МассивРазныхТипов); + ОжидаемоеЗначение.Вставить("Структура", ВложеннаяСтруктура); + ОжидаемоеЗначение.Вставить("Соответствие", ВложенноеСоответствие); + ОжидаемоеЗначение.Вставить("Строка", "Простая строка"); + ОжидаемоеЗначение.Вставить("Число", 3.14); + ОжидаемоеЗначение.Вставить("Булево", Ложь); + + // Создаем идентичную структуру + МассивРазныхТиповКопия = Новый Массив; + МассивРазныхТиповКопия.Добавить("Строка"); + МассивРазныхТиповКопия.Добавить(42); + МассивРазныхТиповКопия.Добавить(Истина); + МассивРазныхТиповКопия.Добавить('20250101000000'); + МассивРазныхТиповКопия.Добавить(Неопределено); + + ВложеннаяСтруктураКопия = Новый Структура; + ВложеннаяСтруктураКопия.Вставить("Ключ", "Значение"); + + ВложенноеСоответствиеКопия = Новый Соответствие; + ВложенноеСоответствиеКопия.Вставить("СоответствиеКлюч", "СоответствиеЗначение"); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("Массив", МассивРазныхТиповКопия); + ФактическоеЗначение.Вставить("Структура", ВложеннаяСтруктураКопия); + ФактическоеЗначение.Вставить("Соответствие", ВложенноеСоответствиеКопия); + ФактическоеЗначение.Вставить("Строка", "Простая строка"); + ФактическоеЗначение.Вставить("Число", 3.14); + ФактическоеЗначение.Вставить("Булево", Ложь); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьМассивовСНулевымиЗначениями() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить(Неопределено); + ОжидаемоеЗначение.Добавить(Null); + ОжидаемоеЗначение.Добавить(""); + ОжидаемоеЗначение.Добавить(0); + ОжидаемоеЗначение.Добавить(Ложь); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить(Неопределено); + ФактическоеЗначение.Добавить(Null); + ФактическоеЗначение.Добавить(""); + ФактическоеЗначение.Добавить(0); + ФактическоеЗначение.Добавить(Ложь); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьПриОтличииВНулевыхЗначениях() Экспорт + // Arrange + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить(Неопределено); + ОжидаемоеЗначение.Добавить(""); + ОжидаемоеЗначение.Добавить(0); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить(Null); // Отличается от Неопределено! + ФактическоеЗначение.Добавить(""); + ФактическоеЗначение.Добавить(0); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьОченьГлубокойВложенности() Экспорт + // Arrange - создаем структуру с глубокой вложенностью (10 уровней) + ОжидаемоеЗначение = Новый Структура; + ФактическоеЗначение = Новый Структура; + + ТекущаяСтруктураОжидаемая = ОжидаемоеЗначение; + ТекущаяСтруктураФактическая = ФактическоеЗначение; + + Для Уровень = 1 По 10 Цикл + СледующаяСтруктураОжидаемая = Новый Структура; + СледующаяСтруктураФактическая = Новый Структура; + + СледующаяСтруктураОжидаемая.Вставить("Уровень", Уровень); + СледующаяСтруктураОжидаемая.Вставить("Данные", "Уровень" + Формат(Уровень, "ЧГ=0")); + + СледующаяСтруктураФактическая.Вставить("Уровень", Уровень); + СледующаяСтруктураФактическая.Вставить("Данные", "Уровень" + Формат(Уровень, "ЧГ=0")); + + ТекущаяСтруктураОжидаемая.Вставить("Следующий", СледующаяСтруктураОжидаемая); + ТекущаяСтруктураФактическая.Вставить("Следующий", СледующаяСтруктураФактическая); + + ТекущаяСтруктураОжидаемая = СледующаяСтруктураОжидаемая; + ТекущаяСтруктураФактическая = СледующаяСтруктураФактическая; + КонецЦикла; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьМассиваВМассиве() Экспорт + // Arrange - массивы, содержащие другие массивы в разных позициях + ВложенныйМассив1 = Новый Массив; + ВложенныйМассив1.Добавить("a"); + ВложенныйМассив1.Добавить("b"); + + ВложенныйМассив2 = Новый Массив; + ВложенныйМассив2.Добавить(1); + ВложенныйМассив2.Добавить(2); + + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить("начало"); + ОжидаемоеЗначение.Добавить(ВложенныйМассив1); + ОжидаемоеЗначение.Добавить("середина"); + ОжидаемоеЗначение.Добавить(ВложенныйМассив2); + ОжидаемоеЗначение.Добавить("конец"); + + // Создаем идентичную копию + ВложенныйМассив1Копия = Новый Массив; + ВложенныйМассив1Копия.Добавить("a"); + ВложенныйМассив1Копия.Добавить("b"); + + ВложенныйМассив2Копия = Новый Массив; + ВложенныйМассив2Копия.Добавить(1); + ВложенныйМассив2Копия.Добавить(2); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить("начало"); + ФактическоеЗначение.Добавить(ВложенныйМассив1Копия); + ФактическоеЗначение.Добавить("середина"); + ФактическоеЗначение.Добавить(ВложенныйМассив2Копия); + ФактическоеЗначение.Добавить("конец"); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьМассивовСРазнымиВложенными() Экспорт + // Arrange + ВложенныйМассив1 = Новый Массив; + ВложенныйМассив1.Добавить("a"); + ВложенныйМассив1.Добавить("b"); + + ВложенныйМассив2 = Новый Массив; + ВложенныйМассив2.Добавить("a"); + ВложенныйМассив2.Добавить("c"); // Отличается! + + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить("элемент"); + ОжидаемоеЗначение.Добавить(ВложенныйМассив1); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить("элемент"); + ФактическоеЗначение.Добавить(ВложенныйМассив2); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьСложнойИерархии() Экспорт + // Arrange - создаем сложную иерархию с массивами, структурами и соответствиями + + // Подчиненные элементы + Подчиненный1 = Новый Структура; + Подчиненный1.Вставить("ID", 1); + Подчиненный1.Вставить("Название", "Подчиненный 1"); + Подчиненный1.Вставить("Активен", Истина); + + Подчиненный2 = Новый Структура; + Подчиненный2.Вставить("ID", 2); + Подчиненный2.Вставить("Название", "Подчиненный 2"); + Подчиненный2.Вставить("Активен", Ложь); + + МассивПодчиненных = Новый Массив; + МассивПодчиненных.Добавить(Подчиненный1); + МассивПодчиненных.Добавить(Подчиненный2); + + // Основные данные + Основные = Новый Структура; + Основные.Вставить("Подчиненные", МассивПодчиненных); + Основные.Вставить("Количество", МассивПодчиненных.Количество()); + + // Метаданные + Метаданные = Новый Соответствие; + Метаданные.Вставить("ВерсияСхемы", "1.0.0"); + Метаданные.Вставить("ДатаСоздания", '20250109120000'); + Метаданные.Вставить("Автор", "Система"); + + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("Основные", Основные); + ОжидаемоеЗначение.Вставить("Метаданные", Метаданные); + ОжидаемоеЗначение.Вставить("СтатусКод", 200); + + // Создаем идентичную копию + Подчиненный1Копия = Новый Структура; + Подчиненный1Копия.Вставить("ID", 1); + Подчиненный1Копия.Вставить("Название", "Подчиненный 1"); + Подчиненный1Копия.Вставить("Активен", Истина); + + Подчиненный2Копия = Новый Структура; + Подчиненный2Копия.Вставить("ID", 2); + Подчиненный2Копия.Вставить("Название", "Подчиненный 2"); + Подчиненный2Копия.Вставить("Активен", Ложь); + + МассивПодчиненныхКопия = Новый Массив; + МассивПодчиненныхКопия.Добавить(Подчиненный1Копия); + МассивПодчиненныхКопия.Добавить(Подчиненный2Копия); + + ОсновныеКопия = Новый Структура; + ОсновныеКопия.Вставить("Подчиненные", МассивПодчиненныхКопия); + ОсновныеКопия.Вставить("Количество", МассивПодчиненныхКопия.Количество()); + + МетаданныеКопия = Новый Соответствие; + МетаданныеКопия.Вставить("ВерсияСхемы", "1.0.0"); + МетаданныеКопия.Вставить("ДатаСоздания", '20250109120000'); + МетаданныеКопия.Вставить("Автор", "Система"); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("Основные", ОсновныеКопия); + ФактическоеЗначение.Вставить("Метаданные", МетаданныеКопия); + ФактическоеЗначение.Вставить("СтатусКод", 200); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьПриОтличииВГлубине() Экспорт + // Arrange - структуры идентичны, кроме одного значения глубоко внутри + ВложеннаяСтруктура1 = Новый Структура; + ВложеннаяСтруктура1.Вставить("Уровень3", "Значение1"); + + ВложеннаяСтруктура2 = Новый Структура; + ВложеннаяСтруктура2.Вставить("Уровень3", "Значение2"); // Отличается! + + СтруктураУровень2_1 = Новый Структура; + СтруктураУровень2_1.Вставить("Вложенная", ВложеннаяСтруктура1); + + СтруктураУровень2_2 = Новый Структура; + СтруктураУровень2_2.Вставить("Вложенная", ВложеннаяСтруктура2); + + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("Уровень1", "Одинаково"); + ОжидаемоеЗначение.Вставить("Уровень2", СтруктураУровень2_1); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("Уровень1", "Одинаково"); + ФактическоеЗначение.Вставить("Уровень2", СтруктураУровень2_2); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьМассивовСРазнымПорядкомВСоответствии() Экспорт + // Arrange - тестируем сложный случай с порядком в соответствии + Массив1 = Новый Массив; + Массив1.Добавить("элемент1"); + Массив1.Добавить("элемент2"); + Массив1.Добавить("элемент3"); + + Массив2 = Новый Массив; + Массив2.Добавить("элемент3"); // Другой порядок + Массив2.Добавить("элемент1"); + Массив2.Добавить("элемент2"); + + ОжидаемоеЗначение = Новый Соответствие; + ОжидаемоеЗначение.Вставить("Ключ1", Массив1); + ОжидаемоеЗначение.Вставить("Ключ2", "Простое значение"); + + ФактическоеЗначение = Новый Соответствие; + ФактическоеЗначение.Вставить("Ключ1", Массив2); + ФактическоеЗначение.Вставить("Ключ2", "Простое значение"); + + // Act & Assert - с учетом порядка должны быть НЕ идентичны + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); + + // А без учета порядка - идентичны + Ожидаем.Что(ФактическоеЗначение).НеУчитыватьПорядокВМассиве().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьБольшихОбъемовДанных() Экспорт + // Arrange - создаем достаточно большие структуры данных + КоличествоЭлементов = 100; + + ОжидаемоеЗначение = Новый Структура; + ФактическоеЗначение = Новый Структура; + + // Массив с множеством элементов + БольшойМассив1 = Новый Массив; + БольшойМассив2 = Новый Массив; + + Для Индекс = 1 По КоличествоЭлементов Цикл + ЭлементМассива = Новый Структура; + ЭлементМассива.Вставить("Индекс", Индекс); + ЭлементМассива.Вставить("Значение", "Элемент_" + Формат(Индекс, "ЧГ=0")); + ЭлементМассива.Вставить("Активен", Индекс % 2 = 1); + + БольшойМассив1.Добавить(ЭлементМассива); + + // Создаем копию элемента + ЭлементМассиваКопия = Новый Структура; + ЭлементМассиваКопия.Вставить("Индекс", Индекс); + ЭлементМассиваКопия.Вставить("Значение", "Элемент_" + Формат(Индекс, "ЧГ=0")); + ЭлементМассиваКопия.Вставить("Активен", Индекс % 2 = 1); + + БольшойМассив2.Добавить(ЭлементМассиваКопия); + КонецЦикла; + + ОжидаемоеЗначение.Вставить("БольшойМассив", БольшойМассив1); + ОжидаемоеЗначение.Вставить("РазмерМассива", БольшойМассив1.Количество()); + + ФактическоеЗначение.Вставить("БольшойМассив", БольшойМассив2); + ФактическоеЗначение.Вставить("РазмерМассива", БольшойМассив2.Количество()); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьПриОтличииВБольшихДанных() Экспорт + // Arrange - создаем большие структуры с одним отличием + КоличествоЭлементов = 50; + + ОжидаемоеЗначение = Новый Массив; + ФактическоеЗначение = Новый Массив; + + Для Индекс = 1 По КоличествоЭлементов Цикл + Если Индекс = КоличествоЭлементов / 2 Тогда + // В середине делаем отличие + ОжидаемоеЗначение.Добавить("Отличается1"); + ФактическоеЗначение.Добавить("Отличается2"); + Иначе + ЗначениеЭлемента = "Элемент_" + Формат(Индекс, "ЧГ=0"); + ОжидаемоеЗначение.Добавить(ЗначениеЭлемента); + ФактическоеЗначение.Добавить(ЗначениеЭлемента); + КонецЕсли; + КонецЦикла; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьСпециальныхСимволов() Экспорт + // Arrange - проверяем строки со специальными символами + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("ПереносСтроки", "Строка1" + Символы.ПС + "Строка2"); + ОжидаемоеЗначение.Вставить("Табуляция", "Колонка1" + Символы.Таб + "Колонка2"); + ОжидаемоеЗначение.Вставить("Кавычки", "Текст ""в кавычках"""); + ОжидаемоеЗначение.Вставить("Слэш", "Путь\к\файлу"); + ОжидаемоеЗначение.Вставить("Unicode", "Тест с эмодзи: 😀🎉"); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("ПереносСтроки", "Строка1" + Символы.ПС + "Строка2"); + ФактическоеЗначение.Вставить("Табуляция", "Колонка1" + Символы.Таб + "Колонка2"); + ФактическоеЗначение.Вставить("Кавычки", "Текст ""в кавычках"""); + ФактическоеЗначение.Вставить("Слэш", "Путь\к\файлу"); + ФактическоеЗначение.Вставить("Unicode", "Тест с эмодзи: 😀🎉"); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьЧисловыхТипов() Экспорт + // Arrange - проверяем разные числовые типы + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("Целое", 42); + ОжидаемоеЗначение.Вставить("Дробное", 3.14159); + ОжидаемоеЗначение.Вставить("Ноль", 0); + ОжидаемоеЗначение.Вставить("Отрицательное", -123); + ОжидаемоеЗначение.Вставить("БольшоеЧисло", 999999999999); + ОжидаемоеЗначение.Вставить("МалоеДробное", 0.0001); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("Целое", 42); + ФактическоеЗначение.Вставить("Дробное", 3.14159); + ФактическоеЗначение.Вставить("Ноль", 0); + ФактическоеЗначение.Вставить("Отрицательное", -123); + ФактическоеЗначение.Вставить("БольшоеЧисло", 999999999999); + ФактическоеЗначение.Вставить("МалоеДробное", 0.0001); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьПохожихЧисел() Экспорт + // Arrange - числа, которые выглядят похоже, но не равны + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить(3.14159); + ОжидаемоеЗначение.Добавить(1); + ОжидаемоеЗначение.Добавить(0); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить(3.14158); // Отличается в последней цифре + ФактическоеЗначение.Добавить(1); + ФактическоеЗначение.Добавить(0); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьМногомерныхМассивов() Экспорт + // Arrange - создаем "многомерный" массив (массив массивов) + Строка1 = Новый Массив; + Строка1.Добавить(1); + Строка1.Добавить(2); + Строка1.Добавить(3); + + Строка2 = Новый Массив; + Строка2.Добавить(4); + Строка2.Добавить(5); + Строка2.Добавить(6); + + Строка3 = Новый Массив; + Строка3.Добавить(7); + Строка3.Добавить(8); + Строка3.Добавить(9); + + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить(Строка1); + ОжидаемоеЗначение.Добавить(Строка2); + ОжидаемоеЗначение.Добавить(Строка3); + + // Создаем идентичную копию + Строка1Копия = Новый Массив; + Строка1Копия.Добавить(1); + Строка1Копия.Добавить(2); + Строка1Копия.Добавить(3); + + Строка2Копия = Новый Массив; + Строка2Копия.Добавить(4); + Строка2Копия.Добавить(5); + Строка2Копия.Добавить(6); + + Строка3Копия = Новый Массив; + Строка3Копия.Добавить(7); + Строка3Копия.Добавить(8); + Строка3Копия.Добавить(9); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить(Строка1Копия); + ФактическоеЗначение.Добавить(Строка2Копия); + ФактическоеЗначение.Добавить(Строка3Копия); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьМногомерныхМассивовСОшибкой() Экспорт + // Arrange - многомерные массивы с ошибкой в одном элементе + Строка1 = Новый Массив; + Строка1.Добавить(1); + Строка1.Добавить(2); + Строка1.Добавить(3); + + Строка2 = Новый Массив; + Строка2.Добавить(4); + Строка2.Добавить(5); + Строка2.Добавить(6); + + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить(Строка1); + ОжидаемоеЗначение.Добавить(Строка2); + + // Создаем копию с ошибкой + Строка1СОшибкой = Новый Массив; + Строка1СОшибкой.Добавить(1); + Строка1СОшибкой.Добавить(999); // Ошибка! + Строка1СОшибкой.Добавить(3); + + Строка2Копия = Новый Массив; + Строка2Копия.Добавить(4); + Строка2Копия.Добавить(5); + Строка2Копия.Добавить(6); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить(Строка1СОшибкой); + ФактическоеЗначение.Добавить(Строка2Копия); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьСоответствийСМассивамиКлючей() Экспорт + // Arrange - соответствия с массивами в качестве ключей и значений + МассивКлюч1 = Новый Массив; + МассивКлюч1.Добавить("ключ"); + МассивКлюч1.Добавить(1); + + МассивЗначение1 = Новый Массив; + МассивЗначение1.Добавить("значение"); + МассивЗначение1.Добавить(2); + + ОжидаемоеЗначение = Новый Соответствие; + ОжидаемоеЗначение.Вставить("ПростойКлюч", МассивЗначение1); + ОжидаемоеЗначение.Вставить("ДругойКлюч", "Простое значение"); + + // Создаем идентичную копию + МассивЗначение1Копия = Новый Массив; + МассивЗначение1Копия.Добавить("значение"); + МассивЗначение1Копия.Добавить(2); + + ФактическоеЗначение = Новый Соответствие; + ФактическоеЗначение.Вставить("ПростойКлюч", МассивЗначение1Копия); + ФактическоеЗначение.Вставить("ДругойКлюч", "Простое значение"); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьКомбинированныхКоллекций() Экспорт + // Arrange - структура, содержащая массив соответствий + Соответствие1 = Новый Соответствие; + Соответствие1.Вставить("ID", 1); + Соответствие1.Вставить("Название", "Первый элемент"); + + Соответствие2 = Новый Соответствие; + Соответствие2.Вставить("ID", 2); + Соответствие2.Вставить("Название", "Второй элемент"); + + МассивСоответствий = Новый Массив; + МассивСоответствий.Добавить(Соответствие1); + МассивСоответствий.Добавить(Соответствие2); + + ВложеннаяСтруктура = Новый Структура; + ВложеннаяСтруктура.Вставить("Элементы", МассивСоответствий); + ВложеннаяСтруктура.Вставить("Счетчик", МассивСоответствий.Количество()); + + ОжидаемоеЗначение = Новый Соответствие; + ОжидаемоеЗначение.Вставить("Данные", ВложеннаяСтруктура); + ОжидаемоеЗначение.Вставить("Статус", "Готов"); + + // Создаем идентичную копию + Соответствие1Копия = Новый Соответствие; + Соответствие1Копия.Вставить("ID", 1); + Соответствие1Копия.Вставить("Название", "Первый элемент"); + + Соответствие2Копия = Новый Соответствие; + Соответствие2Копия.Вставить("ID", 2); + Соответствие2Копия.Вставить("Название", "Второй элемент"); + + МассивСоответствийКопия = Новый Массив; + МассивСоответствийКопия.Добавить(Соответствие1Копия); + МассивСоответствийКопия.Добавить(Соответствие2Копия); + + ВложеннаяСтруктураКопия = Новый Структура; + ВложеннаяСтруктураКопия.Вставить("Элементы", МассивСоответствийКопия); + ВложеннаяСтруктураКопия.Вставить("Счетчик", МассивСоответствийКопия.Количество()); + + ФактическоеЗначение = Новый Соответствие; + ФактическоеЗначение.Вставить("Данные", ВложеннаяСтруктураКопия); + ФактическоеЗначение.Вставить("Статус", "Готов"); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ПустыхВложенныхКоллекций() Экспорт + // Arrange - структуры с пустыми вложенными коллекциями + ПустойМассив = Новый Массив; + ПустаяСтруктура = Новый Структура; + ПустоеСоответствие = Новый Соответствие; + + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("ПустойМассив", ПустойМассив); + ОжидаемоеЗначение.Вставить("ПустаяСтруктура", ПустаяСтруктура); + ОжидаемоеЗначение.Вставить("ПустоеСоответствие", ПустоеСоответствие); + + // Создаем копии пустых коллекций + ПустойМассивКопия = Новый Массив; + ПустаяСтруктураКопия = Новый Структура; + ПустоеСоответствиеКопия = Новый Соответствие; + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("ПустойМассив", ПустойМассивКопия); + ФактическоеЗначение.Вставить("ПустаяСтруктура", ПустаяСтруктураКопия); + ФактическоеЗначение.Вставить("ПустоеСоответствие", ПустоеСоответствиеКопия); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьПустойИНепустойКоллекции() Экспорт + // Arrange - сравниваем пустую и непустую коллекции + ПустойМассив = Новый Массив; + НепустойМассив = Новый Массив; + НепустойМассив.Добавить("элемент"); + + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("Массив", ПустойМассив); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("Массив", НепустойМассив); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьСпециальныхДат() Экспорт + // Arrange - тестируем различные форматы дат + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("ПустаяДата", '00010101000000'); + ОжидаемоеЗначение.Вставить("НовыйГод", '20250101000000'); + ОжидаемоеЗначение.Вставить("СВременем", '20250109142530'); + ОжидаемоеЗначение.Вставить("ПолночьТочно", '20250109000000'); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("ПустаяДата", '00010101000000'); + ФактическоеЗначение.Вставить("НовыйГод", '20250101000000'); + ФактическоеЗначение.Вставить("СВременем", '20250109142530'); + ФактическоеЗначение.Вставить("ПолночьТочно", '20250109000000'); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьДатСРазницейВСекунду() Экспорт + // Arrange - даты, отличающиеся на секунду + ОжидаемоеЗначение = '20250109142530'; // 14:25:30 + ФактическоеЗначение = '20250109142531'; // 14:25:31 + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьБулевыхВМассивах() Экспорт + // Arrange - массивы с различными булевыми значениями + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить(Истина); + ОжидаемоеЗначение.Добавить(Ложь); + ОжидаемоеЗначение.Добавить(Истина); + ОжидаемоеЗначение.Добавить(Ложь); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить(Истина); + ФактическоеЗначение.Добавить(Ложь); + ФактическоеЗначение.Добавить(Истина); + ФактическоеЗначение.Добавить(Ложь); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьБулевыхВМассивах() Экспорт + // Arrange - массивы с отличающимися булевыми значениями + ОжидаемоеЗначение = Новый Массив; + ОжидаемоеЗначение.Добавить(Истина); + ОжидаемоеЗначение.Добавить(Ложь); + ОжидаемоеЗначение.Добавить(Истина); + + ФактическоеЗначение = Новый Массив; + ФактическоеЗначение.Добавить(Истина); + ФактическоеЗначение.Добавить(Истина); // Отличается! + ФактическоеЗначение.Добавить(Истина); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_ИдентичностьСтрокСПробелами() Экспорт + // Arrange - строки с различными пробельными символами + ОжидаемоеЗначение = Новый Структура; + ОжидаемоеЗначение.Вставить("СПробелами", " Строка с пробелами "); + ОжидаемоеЗначение.Вставить("БезПробелов", "СтрокаБезПробелов"); + ОжидаемоеЗначение.Вставить("ТолькоПробелы", " "); + ОжидаемоеЗначение.Вставить("ПустаяСтрока", ""); + + ФактическоеЗначение = Новый Структура; + ФактическоеЗначение.Вставить("СПробелами", " Строка с пробелами "); + ФактическоеЗначение.Вставить("БезПробелов", "СтрокаБезПробелов"); + ФактическоеЗначение.Вставить("ТолькоПробелы", " "); + ФактическоеЗначение.Вставить("ПустаяСтрока", ""); + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Идентично(ОжидаемоеЗначение); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_Проверить_НеИдентичностьСтрокСРазнымиПробелами() Экспорт + // Arrange - строки с разным количеством пробелов + ОжидаемоеЗначение = " два пробела "; + ФактическоеЗначение = " один пробел "; + + // Act & Assert + Ожидаем.Что(ФактическоеЗначение).Не_().Идентично(ОжидаемоеЗначение); +КонецПроцедуры diff --git a/tests/bdd-assertions-tests.os b/tests/bdd-assertions-tests.os index fc56113..a608f72 100644 --- a/tests/bdd-assertions-tests.os +++ b/tests/bdd-assertions-tests.os @@ -269,8 +269,8 @@ &Тест Процедура ТестДолжен_Проверить_ЧтоВыбрасываетсяИсключение() Экспорт Контекст = Новый Структура; - // Не понятно что хотел сказать автор... - // Ожидаем.Что(Контекст).Метод("Вставить").ВыбрасываетИсключение("Недостаточно фактических параметров"); + + Ожидаем.Что(Контекст).Метод("Вставить").ВыбрасываетИсключение("Недостаточно фактических параметров"); Массив = Новый Массив; Массив.Добавить("Ключ"); diff --git a/tests/test-detailed-errors.os b/tests/test-detailed-errors.os new file mode 100644 index 0000000..b146ad4 --- /dev/null +++ b/tests/test-detailed-errors.os @@ -0,0 +1,194 @@ +&Тест +Процедура ТестДетализацииОшибокВМассивах() Экспорт + + // Тест различия типов + Попытка + Ожидаем.Что("строка").РавноМассиву(Новый Массив); + ВызватьИсключение "Исключение должно было возникнуть"; + Исключение + СообщениеОбОшибке = ОписаниеОшибки(); + Ожидаем.Что(СообщениеОбОшибке).Содержит("ожидался массив, но получен"); + КонецПопытки; + + // Тест различия количества элементов + Массив1 = Новый Массив; + Массив1.Добавить(1); + Массив1.Добавить(2); + + Массив2 = Новый Массив; + Массив2.Добавить(1); + + Попытка + Ожидаем.Что(Массив1).РавноМассиву(Массив2); + ВызватьИсключение "Исключение должно было возникнуть"; + Исключение + СообщениеОбОшибке = ОписаниеОшибки(); + Ожидаем.Что(СообщениеОбОшибке).Содержит("разное количество элементов"); + Ожидаем.Что(СообщениеОбОшибке).Содержит("ожидалось 1, получено 2"); + КонецПопытки; + + // Тест различия в конкретном элементе массива + Массив1 = Новый Массив; + Массив1.Добавить(1); + Массив1.Добавить(999); // Различие здесь + Массив1.Добавить(3); + + Массив2 = Новый Массив; + Массив2.Добавить(1); + Массив2.Добавить(2); // Ожидается 2 + Массив2.Добавить(3); + + Попытка + Ожидаем.Что(Массив1).РавноМассиву(Массив2); + ВызватьИсключение "Исключение должно было возникнуть"; + Исключение + СообщениеОбОшибке = ОписаниеОшибки(); + Ожидаем.Что(СообщениеОбОшибке).Содержит("[1]"); // Индекс элемента + Ожидаем.Что(СообщениеОбОшибке).Содержит("ожидалось 2, получено 999"); + КонецПопытки; + +КонецПроцедуры + +&Тест +Процедура ТестДетализацииОшибокВСтруктурах() Экспорт + + // Тест различия типов + Попытка + Ожидаем.Что("строка").РавноСтруктуреИлиСоответствию(Новый Структура); + ВызватьИсключение "Исключение должно было возникнуть"; + Исключение + СообщениеОбОшибке = ОписаниеОшибки(); + Ожидаем.Что(СообщениеОбОшибке).Содержит("ожидался").Содержит("получен"); + КонецПопытки; + + // Тест отсутствующего ключа + Структура1 = Новый Структура("Ключ1, Ключ2", 1, 2); + Структура2 = Новый Структура("Ключ1, Ключ3", 1, 3); // Ключ2 отсутствует, есть Ключ3 + + Попытка + Ожидаем.Что(Структура1).РавноСтруктуреИлиСоответствию(Структура2); + ВызватьИсключение "Исключение должно было возникнуть"; + Исключение + СообщениеОбОшибке = ОписаниеОшибки(); + // Может быть либо отсутствие Ключ3, либо лишний Ключ2 + Условие = Найти(СообщениеОбОшибке, ".Ключ3") > 0 Или Найти(СообщениеОбОшибке, ".Ключ2") > 0; + Ожидаем.Что(Условие).Равно(Истина); + КонецПопытки; + + // Тест различия в значении ключа + Структура1 = Новый Структура("Поле1, Поле2", "значение1", 999); // Различие в Поле2 + Структура2 = Новый Структура("Поле1, Поле2", "значение1", 555); // Ожидается 555 + + Попытка + Ожидаем.Что(Структура1).РавноСтруктуреИлиСоответствию(Структура2); + ВызватьИсключение "Исключение должно было возникнуть"; + Исключение + СообщениеОбОшибке = ОписаниеОшибки(); + Ожидаем.Что(СообщениеОбОшибке).Содержит(".Поле2"); // Ключ элемента + Ожидаем.Что(СообщениеОбОшибке).Содержит("ожидалось 555, получено 999"); + КонецПопытки; + +КонецПроцедуры + +&Тест +Процедура ТестДетализацииОшибокВложенныхСтруктур() Экспорт + + // Тест вложенных структур + ВнутренняяСтруктура1 = Новый Структура("ВнутреннийКлюч", 999); // Различие здесь + ВнутренняяСтруктура2 = Новый Структура("ВнутреннийКлюч", 123); // Ожидается 123 + + ВнешняяСтруктура1 = Новый Структура("ВнешнийКлюч", ВнутренняяСтруктура1); + ВнешняяСтруктура2 = Новый Структура("ВнешнийКлюч", ВнутренняяСтруктура2); + + Попытка + Ожидаем.Что(ВнешняяСтруктура1).РавноСтруктуреИлиСоответствию(ВнешняяСтруктура2); + ВызватьИсключение "Исключение должно было возникнуть"; + Исключение + СообщениеОбОшибке = ОписаниеОшибки(); + Ожидаем.Что(СообщениеОбОшибке).Содержит(".ВнешнийКлюч.ВнутреннийКлюч"); // Полный путь + Ожидаем.Что(СообщениеОбОшибке).Содержит("ожидалось 123, получено 999"); + КонецПопытки; + +КонецПроцедуры + +&Тест +Процедура ТестДетализацииОшибокВложенныхМассивов() Экспорт + + // Тест массива массивов + ВнутреннийМассив1 = Новый Массив; + ВнутреннийМассив1.Добавить(1); + ВнутреннийМассив1.Добавить(999); // Различие здесь + + ВнутреннийМассив2 = Новый Массив; + ВнутреннийМассив2.Добавить(1); + ВнутреннийМассив2.Добавить(2); // Ожидается 2 + + ВнешнийМассив1 = Новый Массив; + ВнешнийМассив1.Добавить("строка"); + ВнешнийМассив1.Добавить(ВнутреннийМассив1); + + ВнешнийМассив2 = Новый Массив; + ВнешнийМассив2.Добавить("строка"); + ВнешнийМассив2.Добавить(ВнутреннийМассив2); + + Попытка + Ожидаем.Что(ВнешнийМассив1).РавноМассиву(ВнешнийМассив2); + ВызватьИсключение "Исключение должно было возникнуть"; + Исключение + СообщениеОбОшибке = ОписаниеОшибки(); + Ожидаем.Что(СообщениеОбОшибке).Содержит("[1][1]"); // Полный путь с индексами + Ожидаем.Что(СообщениеОбОшибке).Содержит("ожидалось 2, получено 999"); + КонецПопытки; + +КонецПроцедуры + +&Тест +Процедура ТестДетализацииОшибокСмешанныхТипов() Экспорт + + // Тест структуры с массивом + МассивВСтруктуре1 = Новый Массив; + МассивВСтруктуре1.Добавить("элемент1"); + МассивВСтруктуре1.Добавить(999); // Различие здесь + + МассивВСтруктуре2 = Новый Массив; + МассивВСтруктуре2.Добавить("элемент1"); + МассивВСтруктуре2.Добавить(555); // Ожидается 555 + + Структура1 = Новый Структура("Массив", МассивВСтруктуре1); + Структура2 = Новый Структура("Массив", МассивВСтруктуре2); + + Попытка + Ожидаем.Что(Структура1).РавноСтруктуреИлиСоответствию(Структура2); + ВызватьИсключение "Исключение должно было возникнуть"; + Исключение + СообщениеОбОшибке = ОписаниеОшибки(); + Ожидаем.Что(СообщениеОбОшибке).Содержит(".Массив[1]"); // Путь структура -> массив -> индекс + Ожидаем.Что(СообщениеОбОшибке).Содержит("ожидалось 555, получено 999"); + КонецПопытки; + +КонецПроцедуры + +&Тест +Процедура ТестДетализацииОшибокВСоответствиях() Экспорт + + // Тест различия в значении ключа соответствия + Соответствие1 = Новый Соответствие; + Соответствие1.Вставить("Ключ1", "значение1"); + Соответствие1.Вставить("Ключ2", 999); // Различие здесь + + Соответствие2 = Новый Соответствие; + Соответствие2.Вставить("Ключ1", "значение1"); + Соответствие2.Вставить("Ключ2", 777); // Ожидается 777 + + Попытка + Ожидаем.Что(Соответствие1).РавноСтруктуреИлиСоответствию(Соответствие2); + ВызватьИсключение "Исключение должно было возникнуть"; + Исключение + СообщениеОбОшибке = ОписаниеОшибки(); + Ожидаем.Что(СообщениеОбОшибке).Содержит(".Ключ2"); // Ключ элемента + Ожидаем.Что(СообщениеОбОшибке).Содержит("ожидалось 777, получено 999"); + КонецПопытки; + +КонецПроцедуры + +