1
0
mirror of https://github.com/bia-technologies/yaxunit.git synced 2025-01-05 12:50:36 +02:00

Merge pull request #278 from bia-technologies/feature/271

271 / Конструктор объектов для XDTO
This commit is contained in:
Koryakin Aleksey 2024-03-11 17:17:24 +03:00 committed by GitHub
commit c2a50b9f66
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 544 additions and 0 deletions

View File

@ -672,6 +672,26 @@
КонецФункции
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Тогда
// Возвращает конструктор создания объекта XDTO
//
// Параметры:
// ИмяТипа - Строка - Имя типа объекта
// ПространствоИмен - Строка - Пространство имен типа
// Фабрика - ФабрикаXDTO - Используемая фабрика XDTO
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТКонструкторОбъектаXDTO - Конструктор объекта XDTO
Функция КонструкторОбъектаXDTO(ИмяТипа, ПространствоИмен, Фабрика = Неопределено) Экспорт
Обработка = Обработки.ЮТКонструкторОбъектаXDTO.Создать();
Обработка.Инициализировать(ИмяТипа, ПространствоИмен);
Возврат Обработка;
КонецФункции
#КонецЕсли
// Удаляет переданные объекта
//
// Параметры:

View File

@ -122,6 +122,7 @@
<dataProcessors>DataProcessor.ЮТHTTPServiceRequest</dataProcessors>
<dataProcessors>DataProcessor.ЮТHTTPСервисЗапрос</dataProcessors>
<dataProcessors>DataProcessor.ЮТRecordSet</dataProcessors>
<dataProcessors>DataProcessor.ЮТКонструкторОбъектаXDTO</dataProcessors>
<dataProcessors>DataProcessor.ЮТКонструкторТестовыхДанных</dataProcessors>
<dataProcessors>DataProcessor.ЮТЮнитТесты</dataProcessors>
</mdclass:Configuration>

View File

@ -0,0 +1,347 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Тогда
#Область ОписаниеПеременных
Перем ТекущийОбъект;
Перем ТекущийТип;
Перем СтекОбъектов;
Перем Фабрика;
#КонецОбласти
#Область ПрограммныйИнтерфейс
// Устанавливает значение реквизита объекта.
//
// Параметры:
// ИмяРеквизита - Строка - Имя реквизита объекта
// Значение - Произвольный - Значение реквизита объекта
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТКонструкторОбъектаXDTO - Конструктор
Функция Установить(ИмяРеквизита, Значение) Экспорт
ТекущийОбъект[ИмяРеквизита] = Значение;
Возврат ЭтотОбъект;
КонецФункции
// Устанавливает фиктивное значение реквизита объекта.
//
// На основании типа реквизита генерируется фиктивное значение.
//
// * Для примитивных значение генерируется случайное значение
// * Для объектных типов создается новый объект
// * Для коллекций - генерируется случайно количество случайных элементов (на основании типа)
//
// Параметры:
// ИмяРеквизита - Строка - Имя реквизита объекта
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТКонструкторОбъектаXDTO - Конструктор
Функция Фикция(ИмяРеквизита) Экспорт
Свойство = ТекущийТип.Свойства.Получить(ИмяРеквизита);
Значение = СлучайноеЗначениеСвойства(Свойство, 0);
Установить(ИмяРеквизита, Значение);
Возврат ЭтотОбъект;
КонецФункции
// Заполняет обязательные реквизиты объекта фиктивными значениями
//
// На основании типа объекта определяются обязательные поля.
// Для них генерируются и устанавливаются фиктивные значение.
//
// * Для примитивных значение генерируется случайное значение
// * Для объектных типов создается новый объект
// * Для коллекций - генерируется случайно количество случайных элементов (на основании типа)
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТКонструкторОбъектаXDTO - Конструктор
Функция ФикцияОбязательныхПолей() Экспорт
Для Каждого Свойство Из ТекущийТип.Свойства Цикл
Если НЕ Свойство.ВозможноПустое И НеЗаполнено(Свойство, ТекущийОбъект[Свойство.Имя]) Тогда
УстановитьСлучайноеЗначениеСвойства(ТекущийОбъект, Свойство, 0);
КонецЕсли;
КонецЦикла;
Возврат ЭтотОбъект;
КонецФункции
// Заполняет неустановленные реквизиты объекта фиктивными значениями
//
// На основании типа объекта определяются обязательные поля.
// Для них генерируются и устанавливаются фиктивные значение.
//
// * Для примитивных значение генерируется случайное значение
// * Для объектных типов создается новый объект
// * Для коллекций - генерируется случайно количество случайных элементов (на основании типа)
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТКонструкторОбъектаXDTO - Конструктор
Функция ФикцияНезаполненных() Экспорт
Для Каждого Свойство Из ТекущийТип.Свойства Цикл
Если НеЗаполнено(Свойство, ТекущийОбъект[Свойство.Имя]) Тогда
УстановитьСлучайноеЗначениеСвойства(ТекущийОбъект, Свойство, 0);
КонецЕсли;
КонецЦикла;
Возврат ЭтотОбъект;
КонецФункции
// Возвращает основной объект XDTO
//
// Возвращаемое значение:
// ОбъектXDTO
Функция ДанныеОбъекта() Экспорт
Возврат СтекОбъектов[0];
КонецФункции
// Добавляет новый объект в реквизит-коллекцию
//
// Параметры:
// ИмяРеквизита - Строка - Имя реквизиты коллекции
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТКонструкторОбъектаXDTO - Добавить новый
Функция ДобавитьНовый(ИмяРеквизита) Экспорт
Свойство = ТекущийТип.Свойства.Получить(ИмяРеквизита);
Если НЕ ЭтоТипОбъектаXDTO(Свойство.Тип) Тогда
ВызватьИсключение СтрШаблон("Метод применяется только для свойств-объектов. Реквизит: %1 имеет тип %2", ИмяРеквизита, Свойство.Тип);
КонецЕсли;
Коллекция = ТекущийОбъект[Свойство.Имя];
ДобавитьНовыйОбъектВСтек(Свойство.Тип);
Коллекция.Добавить(ТекущийОбъект);
Возврат ЭтотОбъект;
КонецФункции
// Переходит на уровень выше по стеку.
//
// Возвращаемое значение:
// ОбработкаОбъект.ЮТКонструкторОбъектаXDTO - Перейти к владельцу
Функция ПерейтиКВладельцу() Экспорт
УдалитьПоследнийИзСтека();
Возврат ЭтотОбъект;
КонецФункции
#КонецОбласти
#Область СлужебныйПрограммныйИнтерфейс
Процедура Инициализировать(ИмяТипаОбъекта, ПространствоИмен, ФабрикаОбъектов = Неопределено) Экспорт
Если ФабрикаОбъектов = Неопределено Тогда
Фабрика = ФабрикаXDTO;
Иначе
Фабрика = ФабрикаОбъектов;
КонецЕсли;
СтекОбъектов = Новый Массив();
ТипОбъекта = Фабрика.Тип(ПространствоИмен, ИмяТипаОбъекта);
ДобавитьНовыйОбъектВСтек(ТипОбъекта);
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Процедура ДобавитьНовыйОбъектВСтек(Тип)
Объект = НовыйОбъект(Тип);
СтекОбъектов.Добавить(Объект);
ТекущийОбъект = Объект;
ТекущийТип = Тип;
КонецПроцедуры
Процедура УдалитьПоследнийИзСтека()
ИндексПоследнего = СтекОбъектов.ВГраница();
ТекущийОбъект = СтекОбъектов[ИндексПоследнего - 1];
ТекущийТип = ТекущийОбъект.Тип();
СтекОбъектов.Удалить(ИндексПоследнего);
КонецПроцедуры
Функция СлучайноеЗначениеСвойства(Свойство, Уровень = 0)
ТипСвойства = Свойство.Тип;
Если ТипЗнч(ТипСвойства) = Тип("ТипЗначенияXDTO") Тогда
Возврат СлучайноеЗначениеПримитипа(Свойство);
ИначеЕсли Уровень < 3 Тогда
Возврат СлучайноеЗначениеОбъекта(Свойство, Уровень + 1);
КонецЕсли;
КонецФункции
Функция СлучайноеЗначениеПримитипа(Свойство)
Тип = Свойство.Тип;
Если Тип.Имя = "string" И СтрНайти(НРег(Свойство.Имя), "uid") Тогда
Возврат ЮТест.Данные().УникальнаяСтрока();
ИначеЕсли Тип.Имя = "string" Тогда
Возврат ЮТест.Данные().СлучайнаяСтрока();
ИначеЕсли Тип.Имя = "boolean" Тогда
Возврат ЮТест.Данные().СлучайноеБулево();
ИначеЕсли Тип.Имя = "integer" Тогда
Возврат ЮТест.Данные().СлучайноеЧисло();
ИначеЕсли Тип.Имя = "decimal" Тогда
Возврат ЮТест.Данные().СлучайноеЧисло(, , 3);
ИначеЕсли Тип.Имя = "time" Тогда
Возврат ЮТест.Данные().СлучайноеВремя();
ИначеЕсли Тип.Имя = "date" Тогда
Возврат НачалоДня(ЮТест.Данные().СлучайнаяДата());
ИначеЕсли Тип.Имя = "dateTime" Тогда
Возврат ЮТест.Данные().СлучайнаяДата();
ИначеЕсли Тип.БазовыйТип.Имя = "AnyRef" Тогда
Возврат ЮТест.Данные().УникальнаяСтрока();
ИначеЕсли ЗначениеЗаполнено(Тип.Фасеты) И Тип.Фасеты[0].Вид = ВидФасетаXDTO.Перечисление Тогда
Возврат СлучайноеЗначениеПеречисления(Тип);
Иначе
ВызватьИсключение "Неподдерживаемый тип примитива XDTO: " + Тип;
КонецЕсли;
КонецФункции
Функция СлучайноеЗначениеОбъекта(Свойство, Уровень)
Пакет = НовыйОбъект(Свойство.Тип);
ЗаполнитьПакетСлучайнымиЗначениями(Пакет, Уровень);
Возврат Пакет;
КонецФункции
Процедура ЗаполнитьПакетСлучайнымиЗначениями(Пакет, Уровень = 0)
Тип = Пакет.Тип();
Для Каждого Свойство Из Тип.Свойства Цикл
Если НеЗаполнено(Свойство, Пакет[Свойство.Имя]) Тогда
Продолжить;
КонецЕсли;
УстановитьСлучайноеЗначениеСвойства(Пакет, Свойство, Уровень);
КонецЦикла;
КонецПроцедуры
Процедура УстановитьСлучайноеЗначениеСвойства(Пакет, Свойство, Уровень)
ЭтоСписок = ЭтоСписок(Свойство);
Если ЭтоСписок Тогда
СписокСлучайныхЗначений(Пакет[Свойство.Имя], Свойство, Уровень);
Иначе
Пакет[Свойство.Имя] = СлучайноеЗначениеСвойства(Свойство, Уровень);
КонецЕсли;
КонецПроцедуры
Функция НеЗаполнено(Свойство, Значение)
ЭтоСписок = ЭтоСписок(Свойство);
Если ЭтоСписок И Значение.Количество() Тогда
Возврат Значение.Количество() = 0;
Иначе
Возврат НЕ ЗначениеЗаполнено(Значение);
КонецЕсли;
КонецФункции
Функция ЭтоСписок(Свойство)
Возврат Свойство.ВерхняяГраница = -1 ИЛИ Свойство.ВерхняяГраница > 1;
КонецФункции
Процедура СписокСлучайныхЗначений(Список, Свойство, Уровень)
Если Свойство.ВерхняяГраница = -1 Тогда
Количество = ЮТест.Данные().СлучайноеЧисло(Свойство.НижняяГраница, 10);
Иначе
Количество = ЮТест.Данные().СлучайноеЧисло(Свойство.НижняяГраница, Свойство.ВерхняяГраница);
КонецЕсли;
Для Инд = 0 По Количество Цикл
Значение = СлучайноеЗначениеСвойства(Свойство, Уровень);
Список.Добавить(Значение);
КонецЦикла;
КонецПроцедуры
Функция НовыйОбъект(Тип)
Возврат Фабрика.Создать(Тип);
КонецФункции
Функция ЭтоТипОбъектаXDTO(ТипСвойства)
Возврат ТипЗнч(ТипСвойства) = Тип("ТипОбъектаXDTO");
КонецФункции
Функция СлучайноеЗначениеПеречисления(Тип)
Значения = Новый Массив();
Для Каждого Фасет Из Тип.Фасеты Цикл
Если Фасет.Вид = ВидФасетаXDTO.Перечисление Тогда
Значения.Добавить(Фасет.Значение);
КонецЕсли;
КонецЦикла;
Возврат ЮТест.Данные().СлучайноеЗначениеИзСписка(Значения);
КонецФункции
#КонецОбласти
#КонецЕсли

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:DataProcessor xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="8ea1fd8e-8352-4973-a357-c64ccb1b9b5c">
<producedTypes>
<objectType typeId="4d0c09ec-ea56-4aef-852c-42a99d491406" valueTypeId="ac59e2e1-acef-483b-b47d-b9aa6bcde7cd"/>
<managerType typeId="f43e3751-6657-41b5-a060-07b0bcd9b2c0" valueTypeId="66b97e8e-5ab2-4e0b-8e10-a14a755c4e0b"/>
</producedTypes>
<name>ЮТКонструкторОбъектаXDTO</name>
<synonym>
<key>ru</key>
<value>Конструктор объекта XDTO</value>
</synonym>
<useStandardCommands>true</useStandardCommands>
</mdclass:DataProcessor>

View File

@ -0,0 +1,157 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
#Область СлужебныйПрограммныйИнтерфейс
Процедура ИсполняемыеСценарии() Экспорт
ЮТТесты
.ДобавитьТест("Установить")
.ДобавитьТест("Фикция")
.ДобавитьТест("ФикцияОбязательныхПолей")
.ДобавитьТест("ФикцияНезаполненных")
.ДобавитьТест("ДобавитьНовый")
.ДобавитьТест("ПерейтиКВладельцу")
;
КонецПроцедуры
Процедура Установить() Экспорт
Номер = ЮТест.Данные().СлучайнаяСтрока(9);
Сумма = ЮТест.Данные().СлучайноеЧисло();
Покупатель = ЮТест.Данные().СоздатьЭлемент(Справочники.Контрагенты);
Объект = НовыйКонструктор()
.Установить("Number", Номер)
.Установить("Сумма", Сумма)
.Установить("Покупатель", Покупатель)
.ДанныеОбъекта();
ЮТест.ОжидаетЧто(Объект)
.ИмеетТип(Тип("ОбъектXDTO"))
.Свойство("Number").Равно(Номер)
.Свойство("Сумма").Равно(Сумма)
.Свойство("Покупатель").Равно(Покупатель)
;
КонецПроцедуры
Процедура Фикция() Экспорт
Объект = НовыйКонструктор()
.Фикция("Number")
.Фикция("Сумма")
.Фикция("Покупатель")
.ДанныеОбъекта();
ЮТест.ОжидаетЧто(Объект)
.ИмеетТип(Тип("ОбъектXDTO"))
.Свойство("Number").Заполнено()
.Свойство("Сумма").Заполнено()
.Свойство("Покупатель").Заполнено()
;
КонецПроцедуры
Процедура ФикцияОбязательныхПолей() Экспорт
Дата = ЮТест.Данные().СлучайнаяДата();
Объект = НовыйКонструктор()
.Установить("Date", Дата)
.ФикцияОбязательныхПолей()
.ДанныеОбъекта();
ЮТест.ОжидаетЧто(Объект)
.ИмеетТип(Тип("ОбъектXDTO"))
.Свойство("Number").Заполнено()
.Свойство("Date").Равно(Дата)
.Свойство("Сумма").Заполнено()
.Свойство("Покупатель").Заполнено()
.Свойство("Товары").Заполнено()
;
КонецПроцедуры
Процедура ФикцияНезаполненных() Экспорт
Дата = ЮТест.Данные().СлучайнаяДата();
Объект = НовыйКонструктор()
.Установить("Date", Дата)
.ФикцияНезаполненных()
.ДанныеОбъекта();
ЮТест.ОжидаетЧто(Объект)
.ИмеетТип(Тип("ОбъектXDTO"))
.Свойство("Number").Заполнено()
.Свойство("Date").Равно(Дата)
.Свойство("Сумма").Заполнено()
.Свойство("Покупатель").Заполнено()
.Свойство("Товары").Заполнено()
;
КонецПроцедуры
Процедура ДобавитьНовый() Экспорт
Объект = НовыйКонструктор()
.ДобавитьНовый("Товары")
.Фикция("Цена")
.Фикция("Количество")
.ДанныеОбъекта();
ЮТест.ОжидаетЧто(Объект)
.ИмеетТип(Тип("ОбъектXDTO"))
.Свойство("Товары").ИмеетДлину(1)
.Свойство("Товары[0].Цена").Заполнено()
.Свойство("Товары[0].Сумма").НеЗаполнено();
КонецПроцедуры
Процедура ПерейтиКВладельцу() Экспорт
Объект = НовыйКонструктор()
.ДобавитьНовый("Товары")
.ПерейтиКВладельцу()
.Фикция("Сумма")
.ДанныеОбъекта();
ЮТест.ОжидаетЧто(Объект)
.ИмеетТип(Тип("ОбъектXDTO"))
.Свойство("Товары").ИмеетДлину(1)
.Свойство("Товары[0].Сумма").НеЗаполнено()
.Свойство("Сумма").Заполнено()
;
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция НовыйКонструктор()
Тип = СериализаторXDTO.XMLТип(Тип("ДокументОбъект.Заказ"));
Возврат ЮТест.Данные().КонструкторОбъектаXDTO(Тип.ИмяТипа, Тип.URIПространстваИмен);
КонецФункции
#КонецОбласти

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="39244668-382e-4400-b046-25a401cf4f61">
<name>Обр_ЮТКонструкторОбъектаXDTO_МО</name>
<server>true</server>
</mdclass:CommonModule>

View File

@ -27,6 +27,7 @@
<commonModules>CommonModule.Интеграция</commonModules>
<commonModules>CommonModule.Обр_ЮТHTTPСервисЗапрос</commonModules>
<commonModules>CommonModule.Обр_ЮТRecordSet_МО</commonModules>
<commonModules>CommonModule.Обр_ЮТКонструкторОбъектаXDTO_МО</commonModules>
<commonModules>CommonModule.ОМ_Мокито</commonModules>
<commonModules>CommonModule.ОМ_МокитоОбучение</commonModules>
<commonModules>CommonModule.ОМ_МокитоСлужебный</commonModules>