Skip to content

Commit 6cddc57

Browse files
Merge pull request #364 from igostv/feature/plugin-priority-sorting
МенеджерПодписок: детерминированный порядок вызова плагинов по убыванию Приоритет()
2 parents 3f4af40 + 0ef2d2e commit 6cddc57

4 files changed

Lines changed: 187 additions & 3 deletions

File tree

src/core/Классы/internal/Классы/МенеджерПодписок.os

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -774,16 +774,31 @@
774774

775775
Процедура ВыполнитьПодпискуНаСобытие(Знач ИмяПроцедурыВыполнения, ПараметрыПроцедуры)
776776

777-
Для Каждого ЭлементИндекса Из ИндексПодписчиков Цикл
777+
Для Каждого Подписчик Из ПодписчикиПоПриоритету() Цикл
778778

779-
Подписчик = ЭлементИндекса.Значение;
780-
781779
Подписчик.ВыполнитьПодписку(ИмяПроцедурыВыполнения, ПараметрыПроцедуры);
782780

783781
КонецЦикла;
784782

785783
КонецПроцедуры
786784

785+
Функция ПодписчикиПоПриоритету()
786+
Таблица = Новый ТаблицаЗначений;
787+
Таблица.Колонки.Добавить("Приоритет", Новый ОписаниеТипов("Число"));
788+
Таблица.Колонки.Добавить("Подписчик");
789+
Для Каждого ЭлементИндекса Из ИндексПодписчиков Цикл
790+
Стр = Таблица.Добавить();
791+
Стр.Приоритет = ЭлементИндекса.Значение.Приоритет();
792+
Стр.Подписчик = ЭлементИндекса.Значение;
793+
КонецЦикла;
794+
Таблица.Сортировать("Приоритет Убыв");
795+
Результат = Новый Массив;
796+
Для Каждого Стр Из Таблица Цикл
797+
Результат.Добавить(Стр.Подписчик);
798+
КонецЦикла;
799+
Возврат Результат;
800+
КонецФункции
801+
787802
Процедура ПрисвоитьЗначенияПараметраПроцедуры(НовыеЗначения, // BSLLS:NumberOfParams-off
788803
Перем0 = Неопределено,
789804
Перем1 = Неопределено,

tests/fixtures/lib.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<package-def>
3+
<class name="СтабПодписчик" file="СтабПодписчик.os"/>
4+
</package-def>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Минимальный стаб подписчика для тестирования МенеджерПодписок.
2+
// Реализует интерфейс ИндексПодписчиков: Приоритет() и ВыполнитьПодписку().
3+
// ЖурналВызовов — массив, переданный по ссылке из теста; стаб пишет в него свою метку при каждом вызове.
4+
5+
Перем _Приоритет;
6+
Перем _Метка;
7+
Перем _ЖурналВызовов;
8+
9+
Процедура Инициализировать(Знач Приоритет, Знач Метка, Знач ЖурналВызовов) Экспорт
10+
_Приоритет = Приоритет;
11+
_Метка = Метка;
12+
_ЖурналВызовов = ЖурналВызовов;
13+
КонецПроцедуры
14+
15+
Функция Приоритет() Экспорт
16+
Возврат _Приоритет;
17+
КонецФункции
18+
19+
Процедура ВыполнитьПодписку(ИмяПроцедуры, Параметры) Экспорт
20+
_ЖурналВызовов.Добавить(_Метка);
21+
КонецПроцедуры
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// Запуск (из корня репозитория):
2+
// oscript -encoding=utf-8 "%ONESCRIPT_LIB%\1testrunner\src\main.os" tests\МенеджерПодписок_сортировка_test.os
3+
4+
#использовать "../src/core/"
5+
#Использовать "./fixtures"
6+
#Использовать asserts
7+
#Использовать logos
8+
9+
Перем Лог;
10+
11+
Функция ПолучитьСписокТестов(Знач Тестирование) Экспорт
12+
13+
ИменаТестов = Новый Массив;
14+
ИменаТестов.Добавить("ТестДолжен_ВызыватьПодписчиковВПорядкеУбыванияПриоритета");
15+
ИменаТестов.Добавить("ТестДолжен_ВызыватьВсехПодписчиков");
16+
ИменаТестов.Добавить("ТестДолжен_ВызыватьТрёхПодписчиковВПравильномПорядке");
17+
ИменаТестов.Добавить("ТестДолжен_КорректноОбрабатыватьОдногоПодписчика");
18+
ИменаТестов.Добавить("ТестДолжен_НеВызыватьЕслиПустойИндекс");
19+
20+
Возврат ИменаТестов;
21+
22+
КонецФункции
23+
24+
Процедура ПередЗапускомТестов() Экспорт
25+
Лог = Логирование.ПолучитьЛог("test.менеджер-подписок");
26+
КонецПроцедуры
27+
28+
Процедура ПослеЗапускаТестов() Экспорт
29+
КонецПроцедуры
30+
31+
// ===========================================================================
32+
33+
// А(приоритет=100) должна быть вызвана раньше Б(приоритет=0)
34+
Процедура ТестДолжен_ВызыватьПодписчиковВПорядкеУбыванияПриоритета() Экспорт
35+
36+
Журнал = Новый Массив;
37+
38+
А = Новый СтабПодписчик;
39+
А.Инициализировать(100, "А", Журнал);
40+
41+
Б = Новый СтабПодписчик;
42+
Б.Инициализировать(0, "Б", Журнал);
43+
44+
МенеджерПодписок = Новый МенеджерПодписок;
45+
МенеджерПодписок.УстановитьПодписчиков(СоздатьИндекс("А", А, "Б", Б));
46+
МенеджерПодписок.ПослеКоммита("", "");
47+
48+
Ожидаем.Что(Журнал[0], "Первой вызвана А (приоритет 100)").Равно("А");
49+
Ожидаем.Что(Журнал[1], "Второй вызвана Б (приоритет 0)").Равно("Б");
50+
51+
КонецПроцедуры
52+
53+
// Все подписчики должны быть вызваны, не только первый
54+
Процедура ТестДолжен_ВызыватьВсехПодписчиков() Экспорт
55+
56+
Журнал = Новый Массив;
57+
58+
А = Новый СтабПодписчик;
59+
А.Инициализировать(100, "А", Журнал);
60+
61+
Б = Новый СтабПодписчик;
62+
Б.Инициализировать(0, "Б", Журнал);
63+
64+
МенеджерПодписок = Новый МенеджерПодписок;
65+
МенеджерПодписок.УстановитьПодписчиков(СоздатьИндекс("А", А, "Б", Б));
66+
МенеджерПодписок.ПослеКоммита("", "");
67+
68+
Ожидаем.Что(Журнал.Количество(), "Вызваны оба подписчика").Равно(2);
69+
70+
КонецПроцедуры
71+
72+
// Три подписчика с перепутанными приоритетами — порядок по убыванию: В(50), А(10), Б(1)
73+
Процедура ТестДолжен_ВызыватьТрёхПодписчиковВПравильномПорядке() Экспорт
74+
75+
Журнал = Новый Массив;
76+
77+
А = Новый СтабПодписчик;
78+
А.Инициализировать(10, "А", Журнал);
79+
80+
Б = Новый СтабПодписчик;
81+
Б.Инициализировать(1, "Б", Журнал);
82+
83+
В = Новый СтабПодписчик;
84+
В.Инициализировать(50, "В", Журнал);
85+
86+
Индекс = Новый Соответствие;
87+
Индекс.Вставить("А", А);
88+
Индекс.Вставить("Б", Б);
89+
Индекс.Вставить("В", В);
90+
91+
МенеджерПодписок = Новый МенеджерПодписок;
92+
МенеджерПодписок.УстановитьПодписчиков(Индекс);
93+
МенеджерПодписок.ПослеКоммита("", "");
94+
95+
Ожидаем.Что(Журнал.Количество(), "Вызваны все три подписчика").Равно(3);
96+
Ожидаем.Что(Журнал[0], "Первой вызвана В (приоритет 50)").Равно("В");
97+
Ожидаем.Что(Журнал[1], "Второй вызвана А (приоритет 10)").Равно("А");
98+
Ожидаем.Что(Журнал[2], "Третьей вызвана Б (приоритет 1)").Равно("Б");
99+
100+
КонецПроцедуры
101+
102+
// Один подписчик — должен быть вызван без ошибок
103+
Процедура ТестДолжен_КорректноОбрабатыватьОдногоПодписчика() Экспорт
104+
105+
Журнал = Новый Массив;
106+
107+
А = Новый СтабПодписчик;
108+
А.Инициализировать(42, "А", Журнал);
109+
110+
МенеджерПодписок = Новый МенеджерПодписок;
111+
МенеджерПодписок.УстановитьПодписчиков(СоздатьИндекс("А", А));
112+
МенеджерПодписок.ПослеКоммита("", "");
113+
114+
Ожидаем.Что(Журнал.Количество(), "Единственный подписчик вызван").Равно(1);
115+
Ожидаем.Что(Журнал[0]).Равно("А");
116+
117+
КонецПроцедуры
118+
119+
// Пустой индекс — никаких вызовов, никаких исключений
120+
Процедура ТестДолжен_НеВызыватьЕслиПустойИндекс() Экспорт
121+
122+
Журнал = Новый Массив;
123+
124+
МенеджерПодписок = Новый МенеджерПодписок;
125+
МенеджерПодписок.УстановитьПодписчиков(Новый Соответствие);
126+
МенеджерПодписок.ПослеКоммита("", "");
127+
128+
Ожидаем.Что(Журнал.Количество(), "Подписчики не вызывались").Равно(0);
129+
130+
КонецПроцедуры
131+
132+
// ===========================================================================
133+
// Вспомогательные
134+
// ===========================================================================
135+
136+
Функция СоздатьИндекс(Знач К1 = "", Знач В1 = Неопределено,
137+
Знач К2 = "", Знач В2 = Неопределено)
138+
Индекс = Новый Соответствие;
139+
Если Не ПустаяСтрока1) Тогда Индекс.Вставить(К1, В1); КонецЕсли;
140+
Если Не ПустаяСтрока2) Тогда Индекс.Вставить(К2, В2); КонецЕсли;
141+
Возврат Индекс;
142+
КонецФункции
143+
144+
Лог = Логирование.ПолучитьЛог("test.менеджер-подписок");

0 commit comments

Comments
 (0)