diff --git "a/docs/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.md" "b/docs/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.md" index dd16e32b..2398e1d0 100644 --- "a/docs/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.md" +++ "b/docs/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.md" @@ -25,6 +25,10 @@ ```bsl // Регистрирует переданный тип класса-сценария в модели данных. // +// Повторная регистрация типа модель не меняет: остается прежний объект модели, с которым уже +// работают хранилища. Регистрировать классы можно и после передачи менеджера другим потокам, но +// таблицы создает Инициализировать, поэтому обычно классы регистрируют до него. +// // Параметры: // ТипСущности - Тип - Тип для добавления в модель // diff --git "a/docs/\320\234\320\276\320\264\320\265\320\273\321\214\320\224\320\260\320\275\320\275\321\213\321\205.md" "b/docs/\320\234\320\276\320\264\320\265\320\273\321\214\320\224\320\260\320\275\320\275\321\213\321\205.md" index 0d428dd5..08463e69 100644 --- "a/docs/\320\234\320\276\320\264\320\265\320\273\321\214\320\224\320\260\320\275\320\275\321\213\321\205.md" +++ "b/docs/\320\234\320\276\320\264\320\265\320\273\321\214\320\224\320\260\320\275\320\275\321\213\321\205.md" @@ -1,5 +1,8 @@ ## МодельДанных +Модель общая у всех потоков, работающих с менеджером: операции читают ее на каждом шаге, а классы +можно регистрировать и после передачи менеджера другим потокам. + ### ПриСозданииОбъекта ```bsl @@ -10,21 +13,44 @@ ### Получить ```bsl - +// Возвращает объект модели типа сущности. +// +// Параметры: +// ТипСущности - Тип - Тип сущности. +// +// Возвращаемое значение: +// ОбъектМодели - Объект модели типа. +// Неопределено - Тип не зарегистрирован в модели. +// Функция Получить(ТипСущности) Экспорт ``` ### ПолучитьОбъектыМодели ```bsl - +// Возвращает объекты модели всех зарегистрированных типов. +// +// Возвращаемое значение: +// Массив из ОбъектМодели - Копия на момент вызова: типы, зарегистрированные позже, в нее не +// попадут. +// Функция ПолучитьОбъектыМодели() Экспорт ``` ### СоздатьОбъектМодели ```bsl - +// Регистрирует тип сущности в модели. +// +// Если тип уже зарегистрирован, возвращается существующий объект модели: с ним уже могут работать +// хранилища и операции других потоков, поэтому он не подменяется. +// +// Параметры: +// ТипСущности - Тип - Тип сущности. +// +// Возвращаемое значение: +// ОбъектМодели - Объект модели типа. +// Функция СоздатьОбъектМодели(ТипСущности) Экспорт ``` diff --git "a/docs/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.md" "b/docs/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.md" index 3c3d21b7..186ae3d7 100644 --- "a/docs/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.md" +++ "b/docs/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.md" @@ -3,8 +3,16 @@ ### ПриСозданииОбъекта ```bsl - -Процедура ПриСозданииОбъекта(ПТипСущности, ПМодельДанных) +// Создает объект модели по аннотациям класса сущности. +// +// Параметры: +// ПТипСущности - Тип - Тип класса сущности. +// ПМодельДанных - МодельДанных - Модель, к которой относится объект. +// ПИмяТаблицы - Строка - Имя таблицы вместо имени из аннотации класса. Так создаются объекты +// модели подчиненных таблиц: класс элемента у них один, а таблицы разные. +// - Неопределено - Имя таблицы берется из аннотации класса. +// +Процедура ПриСозданииОбъекта(ПТипСущности, ПМодельДанных, ПИмяТаблицы = Неопределено) ``` ### ИмяТаблицы @@ -32,13 +40,6 @@ Функция ПодчиненныеТаблицы() Экспорт ``` -### Служебный_ИмяТаблицы - -```bsl -// @internal -Процедура Служебный_ИмяТаблицы(ПИмяТаблицы) Экспорт -``` - ### Идентификатор ```bsl diff --git "a/docs/\320\242\320\270\320\277\321\213\320\232\320\276\320\273\320\276\320\275\320\276\320\272.md" "b/docs/\320\242\320\270\320\277\321\213\320\232\320\276\320\273\320\276\320\275\320\276\320\272.md" index 22568002..21d52667 100644 --- "a/docs/\320\242\320\270\320\277\321\213\320\232\320\276\320\273\320\276\320\275\320\276\320\272.md" +++ "b/docs/\320\242\320\270\320\277\321\213\320\232\320\276\320\273\320\276\320\275\320\276\320\272.md" @@ -10,11 +10,16 @@ * Время * ДатаВремя * Ссылка +* ДвоичныеДанные ### Типы ```bsl - +// Возвращает все типы колонок модели. +// +// Возвращаемое значение: +// ФиксированныйМассив из Строка - Имена типов колонок. +// Функция Типы() Экспорт ``` diff --git "a/docs/\320\242\320\270\320\277\321\213\320\237\320\276\320\264\321\207\320\270\320\275\320\265\320\275\320\275\321\213\321\205\320\242\320\260\320\261\320\273\320\270\321\206.md" "b/docs/\320\242\320\270\320\277\321\213\320\237\320\276\320\264\321\207\320\270\320\275\320\265\320\275\320\275\321\213\321\205\320\242\320\260\320\261\320\273\320\270\321\206.md" index dcc4b5a3..6b06169c 100644 --- "a/docs/\320\242\320\270\320\277\321\213\320\237\320\276\320\264\321\207\320\270\320\275\320\265\320\275\320\275\321\213\321\205\320\242\320\260\320\261\320\273\320\270\321\206.md" +++ "b/docs/\320\242\320\270\320\277\321\213\320\237\320\276\320\264\321\207\320\270\320\275\320\265\320\275\320\275\321\213\321\205\320\242\320\260\320\261\320\273\320\270\321\206.md" @@ -8,7 +8,11 @@ ### Типы ```bsl - +// Возвращает все типы подчиненных таблиц. +// +// Возвращаемое значение: +// ФиксированныйМассив из Строка - Имена типов подчиненных таблиц. +// Функция Типы() Экспорт ``` diff --git a/packagedef b/packagedef index 94e964fb..1c77805b 100644 --- a/packagedef +++ b/packagedef @@ -18,7 +18,7 @@ .ЗависитОт("annotations", "1.6.0") .ЗависитОт("asserts", "1.6.2") .ЗависитОт("atomic", "0.1.1") - .ЗависитОт("collectionos", "0.8.4") + .ЗависитОт("collectionos", "0.9.0") .ЗависитОт("fluent", "0.6.1") .ЗависитОт("fs", "1.2.0") .ЗависитОт("lambdas", "0.3.5") diff --git "a/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\320\271.os" "b/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\320\271.os" index e2af1cf6..c0482e1f 100644 --- "a/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\320\271.os" +++ "b/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\236\320\261\321\200\320\260\320\261\320\276\321\202\320\272\320\260\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\320\271.os" @@ -89,10 +89,10 @@ ОбъектМоделиЭлементКоллекции = Новый ОбъектМодели( Тип("СлужебнаяСущность_ЭлементКоллекцииКлючЗначение"), - РодительскийОбъектМодели.МодельДанных() + РодительскийОбъектМодели.МодельДанных(), + ПодчиненнаяТаблица.ИмяТаблицы ); - ОбъектМоделиЭлементКоллекции.Служебный_ИмяТаблицы(ПодчиненнаяТаблица.ИмяТаблицы); // Колонки модели только для чтения, но этот объект модели только что создан и еще никому не отдан. КолонкиОбъектаМодели = ОбъектМоделиЭлементКоллекции.Колонки(); diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" index 8d5fe2f3..eb0c9c91 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\265\320\275\320\265\320\264\320\266\320\265\321\200\320\241\321\203\321\211\320\275\320\276\321\201\321\202\320\265\320\271.os" @@ -67,6 +67,10 @@ // Регистрирует переданный тип класса-сценария в модели данных. // +// Повторная регистрация типа модель не меняет: остается прежний объект модели, с которым уже +// работают хранилища. Регистрировать классы можно и после передачи менеджера другим потокам, но +// таблицы создает Инициализировать, поэтому обычно классы регистрируют до него. +// // Параметры: // ТипСущности - Тип - Тип для добавления в модель // diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\276\320\264\320\265\320\273\321\214\320\224\320\260\320\275\320\275\321\213\321\205.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\276\320\264\320\265\320\273\321\214\320\224\320\260\320\275\320\275\321\213\321\205.os" index 538f3bbc..0bbe6c3e 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\276\320\264\320\265\320\273\321\214\320\224\320\260\320\275\320\275\321\213\321\205.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\234\320\276\320\264\320\265\320\273\321\214\320\224\320\260\320\275\320\275\321\213\321\205.os" @@ -1,25 +1,55 @@ +#Использовать collectionos + +// КартаКопированиеПриЗаписи - Тип сущности: ее объект модели. Модель общая у всех потоков, работающих +// с менеджером: операции читают ее на каждом шаге, а меняется она только при регистрации класса. Перем ХранилищеМодели; Процедура ПриСозданииОбъекта() - ХранилищеМодели = Новый Соответствие; + ХранилищеМодели = Новый КартаКопированиеПриЗаписи(); КонецПроцедуры +// Возвращает объект модели типа сущности. +// +// Параметры: +// ТипСущности - Тип - Тип сущности. +// +// Возвращаемое значение: +// ОбъектМодели - Объект модели типа. +// Неопределено - Тип не зарегистрирован в модели. +// Функция Получить(ТипСущности) Экспорт - Возврат ХранилищеМодели.Получить(ТипСущности); + Возврат ХранилищеМодели.ПолучитьИлиУмолчание(ТипСущности, Неопределено); КонецФункции +// Возвращает объекты модели всех зарегистрированных типов. +// +// Возвращаемое значение: +// Массив из ОбъектМодели - Копия на момент вызова: типы, зарегистрированные позже, в нее не +// попадут. +// Функция ПолучитьОбъектыМодели() Экспорт - ВсеОбъектыМодели = Новый Массив; - Для Каждого КлючИЗначение Из ХранилищеМодели Цикл - ВсеОбъектыМодели.Добавить(КлючИЗначение.Значение); - КонецЦикла; - - Возврат ВсеОбъектыМодели; + + Возврат ХранилищеМодели.Значения().ВМассив(); + КонецФункции +// Регистрирует тип сущности в модели. +// +// Если тип уже зарегистрирован, возвращается существующий объект модели: с ним уже могут работать +// хранилища и операции других потоков, поэтому он не подменяется. +// +// Параметры: +// ТипСущности - Тип - Тип сущности. +// +// Возвращаемое значение: +// ОбъектМодели - Объект модели типа. +// Функция СоздатьОбъектМодели(ТипСущности) Экспорт + + // Объект строится вне карты: конструктор разбирает аннотации класса, и держать на это время + // блокировку изменения карты незачем. ОбъектМодели = Новый ОбъектМодели(ТипСущности, ЭтотОбъект); - ХранилищеМодели.Вставить(ТипСущности, ОбъектМодели); - Возврат ОбъектМодели; + Возврат ХранилищеМодели.ВставитьЕслиОтсутствует(ТипСущности, ОбъектМодели).Иначе_(ОбъектМодели); + КонецФункции diff --git "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.os" "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.os" index c5704879..7992bf60 100644 --- "a/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.os" +++ "b/src/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.os" @@ -18,7 +18,16 @@ Перем Рефлектор; -Процедура ПриСозданииОбъекта(ПТипСущности, ПМодельДанных) +// Создает объект модели по аннотациям класса сущности. +// +// Параметры: +// ПТипСущности - Тип - Тип класса сущности. +// ПМодельДанных - МодельДанных - Модель, к которой относится объект. +// ПИмяТаблицы - Строка - Имя таблицы вместо имени из аннотации класса. Так создаются объекты +// модели подчиненных таблиц: класс элемента у них один, а таблицы разные. +// - Неопределено - Имя таблицы берется из аннотации класса. +// +Процедура ПриСозданииОбъекта(ПТипСущности, ПМодельДанных, ПИмяТаблицы = Неопределено) МодельДанных = ПМодельДанных; ТипСущности = ПТипСущности; @@ -27,6 +36,10 @@ ЗаполнитьПодчиненныеТаблицы(); Рефлектор = Новый Рефлектор; + Если ПИмяТаблицы <> Неопределено Тогда + ИмяТаблицы = ПИмяТаблицы; + КонецЕсли; + КонецПроцедуры Функция ИмяТаблицы() Экспорт @@ -50,11 +63,6 @@ Возврат ПодчиненныеТаблицы.Скопировать(); КонецФункции -// @internal -Процедура Служебный_ИмяТаблицы(ПИмяТаблицы) Экспорт - ИмяТаблицы = ПИмяТаблицы; -КонецПроцедуры - Функция Идентификатор() Экспорт Возврат Идентификатор; КонецФункции diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\232\320\276\320\273\320\276\320\275\320\276\320\272.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\232\320\276\320\273\320\276\320\275\320\276\320\272.os" index a31fe188..67ffe183 100644 --- "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\232\320\276\320\273\320\276\320\275\320\276\320\272.os" +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\232\320\276\320\273\320\276\320\275\320\276\320\272.os" @@ -8,9 +8,16 @@ Перем Ссылка Экспорт; Перем ДвоичныеДанные Экспорт; +// ФиксированныйМассив из Строка - Все типы колонок. Перем Типы; +// ФиксированныйМассив из Строка - Примитивные типы колонок. Перем ПримитивныеТипы; +// Возвращает все типы колонок модели. +// +// Возвращаемое значение: +// ФиксированныйМассив из Строка - Имена типов колонок. +// Функция Типы() Экспорт Возврат Типы; КонецФункции @@ -68,23 +75,25 @@ Ссылка = "Ссылка"; ДвоичныеДанные = "ДвоичныеДанные"; -Типы = Новый Массив; -Типы.Добавить(Целое); -Типы.Добавить(Дробное); -Типы.Добавить(Булево); -Типы.Добавить(Строка); -Типы.Добавить(Дата); -Типы.Добавить(Время); -Типы.Добавить(ДатаВремя); -Типы.Добавить(Ссылка); -Типы.Добавить(ДвоичныеДанные); +ВсеТипы = Новый Массив; +ВсеТипы.Добавить(Целое); +ВсеТипы.Добавить(Дробное); +ВсеТипы.Добавить(Булево); +ВсеТипы.Добавить(Строка); +ВсеТипы.Добавить(Дата); +ВсеТипы.Добавить(Время); +ВсеТипы.Добавить(ДатаВремя); +ВсеТипы.Добавить(Ссылка); +ВсеТипы.Добавить(ДвоичныеДанные); +Типы = Новый ФиксированныйМассив(ВсеТипы); -ПримитивныеТипы = Новый Массив; -ПримитивныеТипы.Добавить(Целое); -ПримитивныеТипы.Добавить(Дробное); -ПримитивныеТипы.Добавить(Булево); -ПримитивныеТипы.Добавить(Строка); -ПримитивныеТипы.Добавить(Дата); -ПримитивныеТипы.Добавить(Время); -ПримитивныеТипы.Добавить(ДатаВремя); -ПримитивныеТипы.Добавить(ДвоичныеДанные); \ No newline at end of file +Примитивные = Новый Массив; +Примитивные.Добавить(Целое); +Примитивные.Добавить(Дробное); +Примитивные.Добавить(Булево); +Примитивные.Добавить(Строка); +Примитивные.Добавить(Дата); +Примитивные.Добавить(Время); +Примитивные.Добавить(ДатаВремя); +Примитивные.Добавить(ДвоичныеДанные); +ПримитивныеТипы = Новый ФиксированныйМассив(Примитивные); \ No newline at end of file diff --git "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\237\320\276\320\264\321\207\320\270\320\275\320\265\320\275\320\275\321\213\321\205\320\242\320\260\320\261\320\273\320\270\321\206.os" "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\237\320\276\320\264\321\207\320\270\320\275\320\265\320\275\320\275\321\213\321\205\320\242\320\260\320\261\320\273\320\270\321\206.os" index a8d1edd3..53857598 100644 --- "a/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\237\320\276\320\264\321\207\320\270\320\275\320\265\320\275\320\275\321\213\321\205\320\242\320\260\320\261\320\273\320\270\321\206.os" +++ "b/src/\320\234\320\276\320\264\321\203\320\273\320\270/\320\242\320\270\320\277\321\213\320\237\320\276\320\264\321\207\320\270\320\275\320\265\320\275\320\275\321\213\321\205\320\242\320\260\320\261\320\273\320\270\321\206.os" @@ -1,8 +1,14 @@ Перем Массив Экспорт; Перем Структура Экспорт; +// ФиксированныйМассив из Строка - Все типы подчиненных таблиц. Перем Типы; +// Возвращает все типы подчиненных таблиц. +// +// Возвращаемое значение: +// ФиксированныйМассив из Строка - Имена типов подчиненных таблиц. +// Функция Типы() Экспорт Возврат Типы; КонецФункции @@ -10,6 +16,7 @@ Массив = "Массив"; Структура = "Структура"; -Типы = Новый Массив; -Типы.Добавить(Массив); -Типы.Добавить(Структура); +ВсеТипы = Новый Массив; +ВсеТипы.Добавить(Массив); +ВсеТипы.Добавить(Структура); +Типы = Новый ФиксированныйМассив(ВсеТипы); diff --git "a/tests/\320\234\320\276\320\264\320\265\320\273\321\214\320\224\320\260\320\275\320\275\321\213\321\205.os" "b/tests/\320\234\320\276\320\264\320\265\320\273\321\214\320\224\320\260\320\275\320\275\321\213\321\205.os" new file mode 100644 index 00000000..5df345ab --- /dev/null +++ "b/tests/\320\234\320\276\320\264\320\265\320\273\321\214\320\224\320\260\320\275\320\275\321\213\321\205.os" @@ -0,0 +1,214 @@ +// Модель данных менеджера: регистрация классов и чтение объектов модели. +// +// Модель общая у всех потоков, работающих с менеджером: операции читают ее на каждом шаге, а +// классы можно регистрировать и после передачи менеджера другим потокам. Тесты проверяют, что +// поздняя регистрация не ломает идущие операции, а повторная не подменяет объект модели, с которым +// уже работают хранилища. +// +// BSLLS:MagicNumber-off +// BSLLS:LatinAndCyrillicSymbolInWord-off +// BSLLS:DuplicateStringLiteral-off + +#Использовать ".." +#Использовать "utils" + +// ИсточникДанных - Источник тестовой базы; закрывается после каждого теста. +Перем Источник; +// МенеджерСущностей - Менеджер, который тесты создают заново перед каждым тестом. +Перем МенеджерСущностей; +// Строка - Каталог классов, сгенерированных тестом; Неопределено, если тест их не создавал. +Перем КаталогКлассов; + +&ПередКаждым +Процедура ПередЗапускомТеста() Экспорт + + ХранилищеВПамяти.Очистить("МодельДанных"); + ТестовыеУтилиты.ПодключитьКлассыСущностей(); + ПодключитьСценарий(ОбъединитьПути(ТекущийКаталог(), "tests", "fixtures", "СигналСобытия.os"), "СигналСобытия"); + + Источник = Новый ИсточникДанных("Тесты", Тип("КоннекторInMemory"), "МодельДанных"); + // oneunit исполняет подготовку и тест в разных потоках: источник живет до ПослеКаждого. + Источник.УстановитьАвтоЗакрытие(Ложь); + МенеджерСущностей = Новый МенеджерСущностей(Источник); + + // Автор ссылается на СущностьБезГенерируемогоИдентификатора, поэтому в модели нужны обе. + МенеджерСущностей.ДобавитьКлассВМодель(Тип("СущностьБезГенерируемогоИдентификатора")); + МенеджерСущностей.ДобавитьКлассВМодель(Тип("Автор")); + + КаталогКлассов = Неопределено; + +КонецПроцедуры + +&ПослеКаждого +Процедура ПослеЗапускаТеста() Экспорт + + МенеджерСущностей.Закрыть(); + МенеджерСущностей = Неопределено; + Источник.Закрыть(); + + Если КаталогКлассов <> Неопределено Тогда + УдалитьФайлы(КаталогКлассов); + КаталогКлассов = Неопределено; + КонецЕсли; + +КонецПроцедуры + +// Класс регистрируют повторно, когда с ним уже работают. Модель должна вернуть тот же объект +// модели: иначе хранилище, созданное раньше, и новые операции работали бы с разными объектами +// одного типа. +// +&Тест +Процедура ПовторнаяРегистрацияНеПодменяетОбъектМодели() Экспорт + + Модель = МенеджерСущностей.ПолучитьМодельДанных(); + Прежний = Модель.Получить(Тип("Автор")); + Хранилище = МенеджерСущностей.ПолучитьХранилищеСущностей(Тип("Автор")); + + МенеджерСущностей.ДобавитьКлассВМодель(Тип("Автор")); + + Ожидаем.Что(Модель.Получить(Тип("Автор")) = Прежний, "Модель отдает прежний объект модели").ЭтоИстина(); + Ожидаем.Что( + Хранилище.ПолучитьОбъектМодели() = Модель.Получить(Тип("Автор")), + "Хранилище и модель работают с одним объектом модели" + ).ЭтоИстина(); + Ожидаем.Что( + Модель.СоздатьОбъектМодели(Тип("Автор")) = Прежний, + "Создание объекта модели для известного типа возвращает существующий" + ).ЭтоИстина(); + +КонецПроцедуры + +// Задание обходит модель так же, как Инициализировать, и ищет в ней каждый найденный тип, а тест в +// это время регистрирует 50 новых классов. Обход не должен падать на изменяемой модели, и все +// классы должны стать видны. +// +&Тест +Процедура РегистрацияКлассовПараллельноОбходуМоделиНеЛомаетОбход() Экспорт + + Типы = ПодключитьКлассыРегистрации(50); + Модель = МенеджерСущностей.ПолучитьМодельДанных(); + ОжидаемоеКоличество = Модель.ПолучитьОбъектыМодели().Количество() + Типы.Количество(); + НачалОбход = Новый СигналСобытия; + Стоп = Новый СигналСобытия; + + Параметры = Новый Массив; + Параметры.Добавить(Модель); + Параметры.Добавить(ОжидаемоеКоличество); + Параметры.Добавить(НачалОбход); + Параметры.Добавить(Стоп); + Задания = Новый Массив; + Задания.Добавить(ФоновыеЗадания.Выполнить(ЭтотОбъект, "ОбходитьМодельВФоне", Параметры, Истина)); + + Попытка + Ожидаем.Что(НачалОбход.Дождаться(), "Задание начало обход модели").ЭтоИстина(); + Для Каждого ТипСущности Из Типы Цикл + МенеджерСущностей.ДобавитьКлассВМодель(ТипСущности); + КонецЦикла; + Исключение + Ошибка = ИнформацияОбОшибке(); + Стоп.Отметить(); + ТестовыеУтилиты.СообщитьОЗаданиях(ТестовыеУтилиты.ДождатьсяЗаданий(Задания, СрокЗадания())); + ВызватьИсключение; + КонецПопытки; + + ТестовыеУтилиты.ПроверитьЗадания(Задания, СрокЗадания()); + + Для Каждого ТипСущности Из Типы Цикл + ОбъектМодели = Модель.Получить(ТипСущности); + Ожидаем.Что(ОбъектМодели <> Неопределено, СтрШаблон("Класс %1 есть в модели", ТипСущности)).ЭтоИстина(); + Ожидаем.Что(ОбъектМодели.ТипСущности(), "Объект модели описывает свой класс").Равно(ТипСущности); + КонецЦикла; + +КонецПроцедуры + +// Обходит модель в цикле, пока в ней не окажутся все ожидаемые классы. Каждый найденный при обходе +// объект модели ищется в модели по типу и должен найтись тем же. Запускается в фоновом задании. +// +// Параметры: +// Модель - МодельДанных - Модель менеджера теста. +// ОжидаемоеКоличество - Число - Сколько объектов модели будет после регистрации всех классов. +// НачалОбход - СигналСобытия - Отмечается после первого обхода. +// Стоп - СигналСобытия - Отмечается тестом, если регистрация упала. +// +Процедура ОбходитьМодельВФоне(Модель, ОжидаемоеКоличество, НачалОбход, Стоп) Экспорт + + КрайнийСрок = ТекущаяУниверсальнаяДатаВМиллисекундах() + 20000; + + Пока НЕ Стоп.Отмечен() Цикл + + ОбъектыМодели = Модель.ПолучитьОбъектыМодели(); + Для Каждого ОбъектМодели Из ОбъектыМодели Цикл + Если Модель.Получить(ОбъектМодели.ТипСущности()) <> ОбъектМодели Тогда + ВызватьИсключение СтрШаблон("Модель отдала по типу %1 другой объект", ОбъектМодели.ТипСущности()); + КонецЕсли; + КонецЦикла; + + НачалОбход.Отметить(); + + Если ОбъектыМодели.Количество() >= ОжидаемоеКоличество Тогда + Возврат; + КонецЕсли; + + Если ТекущаяУниверсальнаяДатаВМиллисекундах() >= КрайнийСрок Тогда + ВызватьИсключение СтрШаблон( + "За 20 с в модели не появились все классы: %1 из %2", + ОбъектыМодели.Количество(), + ОжидаемоеКоличество + ); + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +// Создает и подключает классы сущностей с уникальными в процессе именами. +// +// Подключение идет в потоке теста до запуска заданий: на движке 2.2 параллельное подключение +// сценариев само не потокобезопасно, а проверяется здесь модель, а не движок. +// +// Параметры: +// Количество - Число - Сколько классов создать. +// +// Возвращаемое значение: +// Массив из Тип - Типы подключенных классов. +// +Функция ПодключитьКлассыРегистрации(Знач Количество) + + КаталогКлассов = ОбъединитьПути(КаталогВременныхФайлов(), "entity-model-" + Новый УникальныйИдентификатор); + СоздатьКаталог(КаталогКлассов); + + Типы = Новый Массив; + Номер = 1; + Пока Номер <= Количество Цикл + + ИмяКласса = "КлассРегистрацииВМодели" + Формат(Номер, "ЧГ="); + ИмяФайла = ОбъединитьПути(КаталогКлассов, ИмяКласса + ".os"); + + ЗаписьТекста = Новый ЗаписьТекста(ИмяФайла, "UTF-8"); + ЗаписьТекста.ЗаписатьСтроку("&Идентификатор"); + ЗаписьТекста.ЗаписатьСтроку("Перем Идентификатор Экспорт;"); + ЗаписьТекста.ЗаписатьСтроку("Перем Поле Экспорт;"); + ЗаписьТекста.ЗаписатьСтроку(СтрШаблон("&Сущность(ИмяТаблицы = ""%1"")", ИмяКласса)); + ЗаписьТекста.ЗаписатьСтроку("Процедура ПриСозданииОбъекта()"); + ЗаписьТекста.ЗаписатьСтроку("КонецПроцедуры"); + ЗаписьТекста.Закрыть(); + + ПодключитьСценарий(ИмяФайла, ИмяКласса); + Типы.Добавить(Тип(ИмяКласса)); + + Номер = Номер + 1; + + КонецЦикла; + + Возврат Типы; + +КонецФункции + +// Срок ожидания задания теста. +// +// Возвращаемое значение: +// Число - Срок в миллисекундах. +// +Функция СрокЗадания() + Возврат 30000; +КонецФункции diff --git "a/tests/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.os" "b/tests/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.os" index 619d6764..a8d12b2f 100644 --- "a/tests/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.os" +++ "b/tests/\320\236\320\261\321\212\320\265\320\272\321\202\320\234\320\276\320\264\320\265\320\273\320\270.os" @@ -158,6 +158,19 @@ КонецПроцедуры +// Имя таблицы, переданное при создании, заменяет имя из аннотации класса. Так создаются объекты +// модели подчиненных таблиц: класс элемента у них один, а таблицы разные. +&Тест +Процедура ИмяТаблицыЗадаетсяПриСоздании() Экспорт + + НовыйОбъектМоделиАвтора(); + + ОбъектМодели = Новый ОбъектМодели(Тип("Автор"), Неопределено, "Авторы_Подчиненная"); + + Ожидаем.Что(ОбъектМодели.ИмяТаблицы(), "Имя таблицы взято из параметра").Равно("Авторы_Подчиненная"); + +КонецПроцедуры + // Идентификатор отдается неизменяемым: правка результата невозможна и модель не меняет. &Тест Процедура ИдентификаторНеизменяем() Экспорт diff --git "a/tests/\320\242\320\270\320\277\321\213\320\232\320\276\320\273\320\276\320\275\320\276\320\272.os" "b/tests/\320\242\320\270\320\277\321\213\320\232\320\276\320\273\320\276\320\275\320\276\320\272.os" new file mode 100644 index 00000000..293efc12 --- /dev/null +++ "b/tests/\320\242\320\270\320\277\321\213\320\232\320\276\320\273\320\276\320\275\320\276\320\272.os" @@ -0,0 +1,21 @@ +// Перечни типов из глобальных модулей библиотеки отдаются неизменяемыми. + +#Использовать ".." + +&Тест +Процедура ТипыКолонокНеизменяемы() Экспорт + + Ожидаем.Что(ТипЗнч(ТипыКолонок.Типы()), "Типы колонок - фиксированный массив") + .Равно(Тип("ФиксированныйМассив")); + Ожидаем.Что(ТипыКолонок.Типы(), "Перечень содержит все типы колонок").ИмеетДлину(9); + +КонецПроцедуры + +&Тест +Процедура ТипыПодчиненныхТаблицНеизменяемы() Экспорт + + Ожидаем.Что(ТипЗнч(ТипыПодчиненныхТаблиц.Типы()), "Типы подчиненных таблиц - фиксированный массив") + .Равно(Тип("ФиксированныйМассив")); + Ожидаем.Что(ТипыПодчиненныхТаблиц.Типы(), "Перечень содержит все типы подчиненных таблиц").ИмеетДлину(2); + +КонецПроцедуры