1
0
mirror of https://github.com/bia-technologies/yaxunit.git synced 2024-12-03 08:45:31 +02:00

Merge branch 'feature/ORAIS-676' into 'develop'

ORAIS-676 / Отчет о тестировании в режиме предприятия

See merge request orais/ci_cd/yaxunit!10
This commit is contained in:
Максимов Валерий Валерьевич (000044217) 2022-11-07 20:33:02 +03:00
commit 0222b98ea1
30 changed files with 3374 additions and 40 deletions

View File

@ -1,3 +1,3 @@
Manifest-Version: 1.0
Runtime-Version: 8.3.10
Base-Project: BSP
Base-Project: configuration

View File

@ -66,7 +66,9 @@
ЮТОтчет.СформироватьОтчет(РезультатыТестирования, Параметры);
Если Параметры.CloseAfterTests Тогда
Если Параметры.showReport Тогда
ПоказатьОтчет(РезультатыТестирования, Параметры);
ИначеЕсли Параметры.CloseAfterTests Тогда
ПрекратитьРаботуСистемы(Ложь);
КонецЕсли;
@ -120,7 +122,7 @@
ЮТСобытия.ПослеВсехТестовМодуля(ТестовыйМодуль);
Если ЕстьОшибки(ТестовыйМодуль) Тогда
СкопироватьОшибкиВ(Наборы, ТестовыйМодуль);
СкопироватьОшибкиВ(Наборы, ТестовыйМодуль.Ошибки);
КонецЕсли;
Возврат Наборы;
@ -324,4 +326,15 @@
КонецФункции
#Если Клиент Тогда
Процедура ПоказатьОтчет(РезультатыТестирования, Параметры)
Данные = Новый Структура("РезультатыТестирования, ПараметрыЗапуска", РезультатыТестирования, Параметры);
АдресДанных = ПоместитьВоВременноеХранилище(Данные);
ОткрытьФорму("Обработка.ЮнитТесты.Форма.Основная", Новый Структура("АдресХранилища", АдресДанных));
КонецПроцедуры
#КонецЕсли
#КонецОбласти

View File

@ -105,6 +105,49 @@
#КонецОбласти
#Область Числа
// Инкрементирует значение
//
// Параметры:
// Значение - Число
// Шаг - Число
Процедура Инкремент(Значение, Знач Шаг = 1) Экспорт
Значение = Значение + Шаг;
КонецПроцедуры
Функция ЧислоВСтроку(Значение) Экспорт
Возврат Формат(Значение, "ЧН = 0; ЧГ=");
КонецФункции
#КонецОбласти
#Область ДатаВремя
// Человекочитаемое представление продолжительности
//
// Параметры:
// Продолжительность - Число - Продолжительность в миллисекундах
//
// Возвращаемое значение:
// Строка - Представление продолжительности
Функция ПредставлениеПродолжительности(Знач Продолжительность) Экспорт
Представление = ЧислоВСтроку(Цел(Продолжительность / 1000));
Представление = ДобавитьСтроку(Представление, Продолжительность % 1000, ".");
Инкремент(Представление, " сек");
Возврат Представление;
КонецФункции
#КонецОбласти
#Область Коллекции
// ЗначениеСтруктуры
@ -776,6 +819,22 @@
КонецФункции
Функция МестноеВремяПоВременнойМетке(Метка) Экспорт
Если ЗначениеЗаполнено(Метка) Тогда
Возврат МестноеВремя('00010101' + Метка / 1000);
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Функция ПродолжительностьВСекундах(Продолжительность) Экспорт
Возврат Продолжительность / 1000;
КонецФункции
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////////

View File

@ -100,7 +100,7 @@
ЗаписьXML.ЗаписатьНачалоЭлемента("testcase");
ЗаписьXML.ЗаписатьАтрибут("name", РезультатТеста.Имя);
ЗаписьXML.ЗаписатьАтрибут("classname", РезультатТеста.ПолноеИмяМетода);
ЗаписьXML.ЗаписатьАтрибут("time", XMLСтрока(ПродолжительностьВСекундах(РезультатТеста.Длительность)));
ЗаписьXML.ЗаписатьАтрибут("time", XMLСтрока(ЮТОбщий.ПродолжительностьВСекундах(РезультатТеста.Длительность)));
ЗаписьXML.ЗаписатьАтрибут("context", РезультатТеста.Режим);
Для Каждого ОписаниеОшибки Из РезультатТеста.Ошибки Цикл
@ -221,8 +221,8 @@
ЗаписьXML.ЗаписатьАтрибут("errors", XMLСтрока(КоличествоСломанных));
ЗаписьXML.ЗаписатьАтрибут("skipped", XMLСтрока(КоличествоПропущенных));
ЗаписьXML.ЗаписатьАтрибут("failures", XMLСтрока(КоличествоУпавших));
ЗаписьXML.ЗаписатьАтрибут("timestamp", XMLСтрока(МестноеВремяПоВременнойМетке(Набор.ДатаСтарта)));
ЗаписьXML.ЗаписатьАтрибут("time", XMLСтрока(ПродолжительностьВСекундах(Набор.Длительность)));
ЗаписьXML.ЗаписатьАтрибут("timestamp", XMLСтрока(ЮТОбщий.МестноеВремяПоВременнойМетке(Набор.ДатаСтарта)));
ЗаписьXML.ЗаписатьАтрибут("time", XMLСтрока(ЮТОбщий.ПродолжительностьВСекундах(Набор.Длительность)));
ЗаписьXML.ЗаписатьАтрибут("package", Набор.МетаданныеМодуля.Расширение);
ЗаписьXML.ЗаписатьАтрибут("context", Набор.Режим);
@ -325,22 +325,6 @@
КонецФункции
Функция МестноеВремяПоВременнойМетке(Метка)
Если ЗначениеЗаполнено(Метка) Тогда
Возврат МестноеВремя('00010101' + Метка / 1000);
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Функция ПродолжительностьВСекундах(Продолжительность)
Возврат Продолжительность / 1000;
КонецФункции
Процедура ЗаписатьСвойства(ЗаписьXML, Свойства)
ЗаписьXML.ЗаписатьНачалоЭлемента("properties");

View File

@ -46,6 +46,12 @@
КонецФункции
Функция КлючЗапуска() Экспорт
Возврат "RunUnitTests";
КонецФункции
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////////
@ -116,7 +122,7 @@
КонецЦикла;
ЗначениеКлючаЗапуска = ЮТОбщий.ЗначениеСтруктуры(ПараметрыЗапуска, "RunUnitTests", Ложь);
ЗначениеКлючаЗапуска = ЮТОбщий.ЗначениеСтруктуры(ПараметрыЗапуска, КлючЗапуска(), Ложь);
Если ТипЗнч(ЗначениеКлючаЗапуска) = Тип("Булево") Тогда
@ -147,7 +153,7 @@
#Если НЕ ВебКлиент Тогда
Если ЮТОбщий.УстановленБезопасныйРежим() Тогда
ВызватьИсключение "Раширение подключено в безопасном режиме. Чтение конфигурационного файла недоступно";
ВызватьИсключение "Расширение подключено в безопасном режиме. Чтение конфигурационного файла недоступно";
КонецЕсли;
Файл = Новый Файл(ПутьКФайлу);

View File

@ -94,7 +94,7 @@
#КонецОбласти
// Вызввает ошибку выполнения теста, на основании перехваченной ошибки
// Вызывает ошибку выполнения теста, на основании перехваченной ошибки
//
// Параметры:
// ИнформацияОбОшибке - ИнформацияОбОшибке
@ -107,7 +107,7 @@
КонецПроцедуры
// Вызввает ошибку сравнения значений
// Вызывает ошибку сравнения значений
// При этом сохраняет в контекст состояние, для дальнейшей обработки
//
// Параметры:
@ -123,7 +123,7 @@
КонецПроцедуры
// Вызввает ошибку проверки утверждений
// Вызывает ошибку проверки утверждений
// При этом сохраняет в контекст состояние, для дальнейшей обработки
//
// Параметры:
@ -165,7 +165,7 @@
/////////////////////////////////////////////////////////////////////////////////
#Область СлужебныйПрограммныйИнтерфейс
// Вызввает ошибку выполнения теста
// Вызывает ошибку выполнения теста
// Служебный метод, предварительно нужно самостоятельно настроить контекст (см. ЮТКонтекст.КонтекстОшибки)
// Параметры:
// ТекстСообщения - Строка
@ -247,7 +247,7 @@
КонецФункции
Функция СтатусВыполненияТеста(Тест) Экспорт
Функция СтатусВыполненияТеста(Тест) Экспорт
СтатусыИсполненияТеста = ЮТФабрика.СтатусыИсполненияТеста();

View File

@ -313,15 +313,7 @@
Функция ОписаниеИсполняемогоТеста(Тест, Режим, ТестовыйМодуль) Экспорт
ПолноеИмяМетода = СтрШаблон("%1.%2", ТестовыйМодуль.МетаданныеМодуля.Имя, Тест.Имя);
Если ЗначениеЗаполнено(Тест.Представление) Тогда
Представление = Тест.Представление;
ИначеЕсли ЗначениеЗаполнено(Тест.Параметры) Тогда
ПредставлениеПараметров = СтрСоединить(Тест.Параметры, ", ");
Представление = СтрШаблон("%1(%2)", Тест.Имя, ПредставлениеПараметров);
Иначе
Представление = Тест.Имя;
КонецЕсли;
Представление = ПредставлениеТеста(Тест);
ОписаниеТеста = Новый Структура;
ОписаниеТеста.Вставить("Имя", Представление);
@ -364,13 +356,14 @@
Параметры.Вставить("filter", ПараметрыФильтрации());
Параметры.Вставить("settings", НастройкиВыполнения());
Параметры.Вставить("reportFormat", "jUnit");
Параметры.Вставить("showReport", Ложь);
Возврат Параметры;
КонецФункции
// ОписаниеКонтекстаОшибки
// Возвращает описание детелей/расшифровки ошибки
// Возвращает описание деталей/расшифровки ошибки
// Возвращаемое значение:
// Структура - Детали ошибки:
// * ОшибкаУтверждения - Булево - Признак, это ошибка проверки утверждения
@ -580,6 +573,28 @@
КонецФункции
// Формирует представление теста
//
// Параметры:
// Тест - см. ОписаниеТеста
//
// Возвращаемое значение:
// Строка - Представление теста
Функция ПредставлениеТеста(Тест) Экспорт
Если ЗначениеЗаполнено(Тест.Представление) Тогда
Представление = Тест.Представление;
ИначеЕсли ЗначениеЗаполнено(Тест.Параметры) Тогда
ПредставлениеПараметров = СтрСоединить(Тест.Параметры, ", ");
Представление = СтрШаблон("%1(%2)", Тест.Имя, ПредставлениеПараметров);
Иначе
Представление = Тест.Имя;
КонецЕсли;
Возврат Представление;
КонецФункции
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="20px"
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<rect x="4" y="4" rx="10" ry="10" width="42" height="42" style="fill:none;stroke:#9400d3;stroke-width:4"/>
<g transform="scale(0.8) translate(6, 4)">
<line style="fill:none;stroke:#9400d3;stroke-width:8;stroke-linecap:round;stroke-miterlimit:10;" x1="25" y1="41" x2="25" y2="43"/>
<path style="fill:none;stroke:#9400d3;stroke-width:8;stroke-linecap:round;stroke-miterlimit:10;" d="M18,16
c0-3.899,3.188-7.054,7.1-6.999c3.717,0.052,6.848,3.182,6.9,6.9c0.035,2.511-1.252,4.723-3.21,5.986
C26.355,23.457,25,26.261,25,29.158V32"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 924 B

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonPicture xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="2fa60d62-90ab-4c69-92b0-a2424b08692e">
<name>ЮТНеизвестный</name>
<synonym>
<key>ru</key>
<value>Неизвестный</value>
</synonym>
</mdclass:CommonPicture>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="20px"
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<rect x="4" y="4" rx="10" ry="10" width="42" height="42" style="fill:none;stroke:#D75A4A;stroke-width:4"/>
<polyline style="fill:none;stroke:#D75A4A;stroke-width:8;stroke-linecap:round;stroke-miterlimit:10;" points="14,36 25,25 36,14 "/>
<polyline style="fill:none;stroke:#D75A4A;stroke-width:8;stroke-linecap:round;stroke-miterlimit:10;" points="14,14 25,25 36,36 "/>
</svg>

After

Width:  |  Height:  |  Size: 755 B

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonPicture xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="64f99c40-dd74-493b-99f2-4cde101037ab">
<name>ЮТОшибка</name>
<synonym>
<key>ru</key>
<value>Ошибка</value>
</synonym>
</mdclass:CommonPicture>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="20px"
viewBox="0 0 50 50" style="enable-background:new 0 0 54 54;" xml:space="preserve">
<rect x="4" y="4" rx="10" ry="10" width="42" height="42" style="fill:none;stroke:#999999;stroke-width:4"/>
<g transform="translate(-2,-2)">
<path style="fill:none;stroke:#999999;stroke-width:4;stroke-linecap:round;stroke-miterlimit:10;" d="M27.707,14.293c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414L37.586,27L26.293,38.293
c-0.391,0.391-0.391,1.023,0,1.414C26.488,39.902,26.744,40,27,40s0.512-0.098,0.707-0.293l11.498-11.498
c0.667-0.667,0.667-1.751,0-2.418L27.707,14.293z"/>
<path style="fill:none;stroke:#999999;stroke-width:4;stroke-linecap:round;stroke-miterlimit:10;" d="M29.205,25.791L17.707,14.293c-0.391-0.391-1.023-0.391-1.414,0s-0.391,1.023,0,1.414L27.586,27L16.293,38.293
c-0.391,0.391-0.391,1.023,0,1.414C16.488,39.902,16.744,40,17,40s0.512-0.098,0.707-0.293l11.498-11.498
C29.872,27.542,29.872,26.458,29.205,25.791z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonPicture xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="52d4711c-930f-453c-a761-c1a0a1428860">
<name>ЮТПропущен</name>
<synonym>
<key>ru</key>
<value>Пропущен</value>
</synonym>
</mdclass:CommonPicture>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="20px"
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<rect x="4" y="4" rx="10" ry="10" width="42" height="42" style="fill:none;stroke:#EFCE4A;stroke-width:4"/>
<line style="fill:none;stroke:#EFCE4A;stroke-width:8;stroke-linecap:round;stroke-miterlimit:10;" x1="25" y1="14" x2="25" y2="28"/>
<line style="fill:none;stroke:#EFCE4A;stroke-width:8;stroke-linecap:round;stroke-miterlimit:10;" x1="25" y1="37" x2="25" y2="37"/>
</svg>

After

Width:  |  Height:  |  Size: 754 B

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonPicture xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="a631ba97-5787-4937-aa95-db6ccde8467f">
<name>ЮТУпал</name>
<synonym>
<key>ru</key>
<value>Упал</value>
</synonym>
</mdclass:CommonPicture>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="20px"
viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
<rect x="4" y="4" rx="10" ry="10" width="42" height="42" style="fill:none;stroke:#25AE88;stroke-width:4"/>
<polyline style="fill:none;stroke:#25AE88;stroke-width:8;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;" points="37,15 21,36 12,26 "/>
</svg>

After

Width:  |  Height:  |  Size: 645 B

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonPicture xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="bf60188c-c7ce-48d4-9a1c-a70087ee2821">
<name>ЮТУспешно</name>
<synonym>
<key>ru</key>
<value>Успешно</value>
</synonym>
</mdclass:CommonPicture>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="80px" height="20px"
viewBox="0 0 2000 500" xml:space="preserve">
<g transform="translate(-20, -20) scale(15)" style="fill:#ff713b">
<path d="M29.81,16H29V8.83a2,2,0,0,0-2-2H21A5.14,5.14,0,0,0,16.51,2,5,5,0,0,0,11,6.83H4a2,2,0,0,0-2,2V17H4.81A3.13,3.13,0,0,1,8,19.69,3,3,0,0,1,7.22,22,3,3,0,0,1,5,23H2v8.83a2,2,0,0,0,2,2H27a2,2,0,0,0,2-2V26h1a5,5,0,0,0,5-5.51A5.15,5.15,0,0,0,29.81,16Zm2.41,7A3,3,0,0,1,30,24H27v7.83H4V25H5a5,5,0,0,0,5-5.51A5.15,5.15,0,0,0,4.81,15H4V8.83h9V7a3,3,0,0,1,1-2.22A3,3,0,0,1,16.31,4,3.13,3.13,0,0,1,19,7.19V8.83h8V18h2.81A3.13,3.13,0,0,1,33,20.69,3,3,0,0,1,32.22,23Z"></path>
</g>
<g transform="translate(500, 0) scale(34)" style="fill:#3980ed">
<path d="M3 2.5C3 2.22386 3.22386 2 3.5 2H9.08579C9.21839 2 9.34557 2.05268 9.43934 2.14645L11.8536 4.56066C11.9473 4.65443 12 4.78161
12 4.91421V12.5C12 12.7761 11.7761 13 11.5 13H3.5C3.22386 13 3 12.7761 3 12.5V2.5ZM3.5 1C2.67157 1 2 1.67157 2 2.5V12.5C2 13.3284
2.67157 14 3.5 14H11.5C12.3284 14 13 13.3284 13 12.5V4.91421C13 4.51639 12.842 4.13486 12.5607 3.85355L10.1464 1.43934C9.86514 1.15804
9.48361 1 9.08579 1H3.5ZM4.5 4C4.22386 4 4 4.22386 4 4.5C4 4.77614 4.22386 5 4.5 5H7.5C7.77614 5 8 4.77614 8 4.5C8 4.22386 7.77614 4
7.5 4H4.5ZM4.5 7C4.22386 7 4 7.22386 4 7.5C4 7.77614 4.22386 8 4.5 8H10.5C10.7761 8 11 7.77614 11 7.5C11 7.22386 10.7761 7 10.5 7H4.5ZM4.5
10C4.22386 10 4 10.2239 4 10.5C4 10.7761 4.22386 11 4.5 11H10.5C10.7761 11 11 10.7761 11 10.5C11 10.2239 10.7761 10 10.5 10H4.5Z"/>
</g>
<g transform="translate(1000, 0)" style="fill:#16a706">
<path d="M192.5,0H20.8C9.4,0,0,9.4,0,20.8v171.7c0,11.4,9.4,20.8,20.8,20.8h171.7c11.4,0,20.8-9.4,20.8-20.8V20.8
C213.3,9.4,203.9,0,192.5,0z M171.7,172.7H40.6V40.6h131.1L171.7,172.7L171.7,172.7z"/>
<path d="M192.5,275.7H20.8C9.4,275.7,0,285.1,0,296.5v171.7C0,479.6,9.4,489,20.8,489h171.7c11.4,0,20.8-9.4,20.8-19.8V296.5
C213.3,285.1,203.9,275.7,192.5,275.7z M171.7,448.4H40.6V316.3h131.1L171.7,448.4L171.7,448.4z"/>
<path d="M262.2,126.9h206c11.4,0,20.8-9.4,20.8-20.8s-9.4-20.8-20.8-20.8h-206c-11.4,0-20.8,9.4-20.8,20.8
C241.4,117.6,250.7,126.9,262.2,126.9z"/>
<path d="M468.2,361h-206c-11.4,0-20.8,9.4-20.8,20.8s9.4,20.8,20.8,20.8h206c11.4,0,20.8-9.4,20.8-20.8S479.6,361,468.2,361z"/>
</g>
<g transform="translate(1500, 130)" style="fill:#67db5a">
<path d="M192.5,0H20.8C9.4,0,0,9.4,0,20.8v171.7c0,11.4,9.4,20.8,20.8,20.8h171.7c11.4,0,20.8-9.4,20.8-20.8V20.8
C213.3,9.4,203.9,0,192.5,0z M171.7,172.7H40.6V40.6h131.1L171.7,172.7L171.7,172.7z"/>
<path d="M262.2,126.9h206c11.4,0,20.8-9.4,20.8-20.8s-9.4-20.8-20.8-20.8h-206c-11.4,0-20.8,9.4-20.8,20.8
C241.4,117.6,250.7,126.9,262.2,126.9z"/>
</g></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonPicture xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="341ee107-1c3b-488b-8890-02d2129fa2a4">
<name>ЮТЭлементыТестов</name>
<synonym>
<key>ru</key>
<value>Элементы тестов</value>
</synonym>
</mdclass:CommonPicture>

View File

@ -31,6 +31,12 @@
</languages>
<subsystems>Subsystem.ЮТДвижок</subsystems>
<subsystems>Subsystem.ЮТФункциональность</subsystems>
<commonPictures>CommonPicture.ЮТНеизвестный</commonPictures>
<commonPictures>CommonPicture.ЮТОшибка</commonPictures>
<commonPictures>CommonPicture.ЮТПропущен</commonPictures>
<commonPictures>CommonPicture.ЮТУпал</commonPictures>
<commonPictures>CommonPicture.ЮТУспешно</commonPictures>
<commonPictures>CommonPicture.ЮТЭлементыТестов</commonPictures>
<commonModules>CommonModule.Мокито</commonModules>
<commonModules>CommonModule.МокитоОбучение</commonModules>
<commonModules>CommonModule.МокитоПроверки</commonModules>
@ -62,4 +68,5 @@
<commonModules>CommonModule.ЮТФильтрация</commonModules>
<commonModules>CommonModule.ЮТЧитатель</commonModules>
<commonModules>CommonModule.ЮТЧитательСервер</commonModules>
<dataProcessors>DataProcessor.ЮТЮнитТесты</dataProcessors>
</mdclass:Configuration>

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8"?>
<ConditionalAppearance xmlns="http://v8.1c.ru/8.1/data-composition-system/settings" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcscor="http://v8.1c.ru/8.1/data-composition-system/core" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows">
<item>
<selection>
<item>
<field>ДеревоТестовПрогресс</field>
</item>
</selection>
<filter>
<item xsi:type="FilterItemComparison">
<left xsi:type="dcscor:Field">ДеревоТестов.Набор</left>
<comparisonType>Equal</comparisonType>
<right xsi:type="xs:boolean">false</right>
</item>
</filter>
<appearance>
<dcscor:item xsi:type="SettingsParameterValue">
<dcscor:parameter>Видимость</dcscor:parameter>
<dcscor:value xsi:type="xs:boolean">false</dcscor:value>
</dcscor:item>
</appearance>
<presentation xsi:type="v8:LocalStringType">
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Скрытие колонок. Тест</v8:content>
</v8:item>
</presentation>
</item>
<item>
<selection>
<item>
<field>ДеревоТестовИконка</field>
</item>
<item>
<field>ДеревоТестовСостояние</field>
</item>
</selection>
<filter>
<item xsi:type="FilterItemComparison">
<left xsi:type="dcscor:Field">ДеревоТестов.Набор</left>
<comparisonType>Equal</comparisonType>
<right xsi:type="xs:boolean">true</right>
</item>
</filter>
<appearance>
<dcscor:item xsi:type="SettingsParameterValue">
<dcscor:parameter>Видимость</dcscor:parameter>
<dcscor:value xsi:type="xs:boolean">false</dcscor:value>
</dcscor:item>
</appearance>
<presentation xsi:type="v8:LocalStringType">
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Скрытие колонок. Набор</v8:content>
</v8:item>
</presentation>
</item>
<item>
<selection>
<item>
<field>ДеревоТестовКонтекст</field>
</item>
</selection>
<filter>
<item xsi:type="FilterItemComparison">
<left xsi:type="dcscor:Field">ДеревоТестов.Контекст</left>
<comparisonType>Equal</comparisonType>
<right xsi:type="xs:string">Сервер</right>
</item>
</filter>
<appearance>
<dcscor:item xsi:type="SettingsParameterValue">
<dcscor:parameter>ЦветТекста</dcscor:parameter>
<dcscor:value xsi:type="v8ui:Color">#B46C00</dcscor:value>
</dcscor:item>
</appearance>
<presentation xsi:type="v8:LocalStringType">
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Контекст. Сервер</v8:content>
</v8:item>
</presentation>
</item>
<item>
<selection>
<item>
<field>ДеревоТестовКонтекст</field>
</item>
</selection>
<filter>
<item xsi:type="FilterItemComparison">
<left xsi:type="dcscor:Field">ДеревоТестов.Контекст</left>
<comparisonType>Equal</comparisonType>
<right xsi:type="xs:string">Клиент</right>
</item>
</filter>
<appearance>
<dcscor:item xsi:type="SettingsParameterValue">
<dcscor:parameter>ЦветТекста</dcscor:parameter>
<dcscor:value xsi:type="v8ui:Color">#058BC0</dcscor:value>
</dcscor:item>
</appearance>
<presentation xsi:type="v8:LocalStringType">
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Контекст. Клиент</v8:content>
</v8:item>
</presentation>
</item>
<item>
<selection>
<item>
<field>ДеревоТестовВремяВыполнения</field>
</item>
</selection>
<filter>
<item xsi:type="FilterItemGroup">
<groupType>OrGroup</groupType>
<item xsi:type="FilterItemGroup">
<groupType>AndGroup</groupType>
<item xsi:type="FilterItemComparison">
<left xsi:type="dcscor:Field">ДеревоТестов.Набор</left>
<comparisonType>Equal</comparisonType>
<right xsi:type="xs:boolean">false</right>
</item>
<item xsi:type="FilterItemComparison">
<left xsi:type="dcscor:Field">ДеревоТестов.ВремяВыполнения</left>
<comparisonType>Greater</comparisonType>
<right xsi:type="xs:decimal">1</right>
</item>
</item>
<item xsi:type="FilterItemGroup">
<groupType>AndGroup</groupType>
<item xsi:type="FilterItemComparison">
<left xsi:type="dcscor:Field">ДеревоТестов.Набор</left>
<comparisonType>Equal</comparisonType>
<right xsi:type="xs:boolean">true</right>
</item>
<item xsi:type="FilterItemComparison">
<left xsi:type="dcscor:Field">ДеревоТестов.ВремяВыполнения</left>
<comparisonType>Greater</comparisonType>
<right xsi:type="xs:decimal">10</right>
</item>
</item>
</item>
</filter>
<appearance>
<dcscor:item xsi:type="SettingsParameterValue">
<dcscor:parameter>ЦветТекста</dcscor:parameter>
<dcscor:value xsi:type="v8ui:Color">#D2000F</dcscor:value>
</dcscor:item>
</appearance>
<presentation xsi:type="v8:LocalStringType">
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Время выполнения &gt; 1 сек</v8:content>
</v8:item>
</presentation>
</item>
</ConditionalAppearance>

View File

@ -0,0 +1,352 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 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.
//
//©///////////////////////////////////////////////////////////////////////////©//
#Область ОбработчикиСобытийФормы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("АдресХранилища") И ЭтоАдресВременногоХранилища(Параметры.АдресХранилища) Тогда
ОтобразитьРезультатыТестирования(Параметры.АдресХранилища);
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийЭлементовШапкиФормы
#КонецОбласти
#Область ОбработчикиСобытийЭлементовТаблицыФормыДеревоТестов
&НаКлиенте
Процедура ДеревоТестовПриАктивизацииСтроки(Элемент)
Данные = Элементы.ДеревоТестов.ТекущиеДанные;
Если Данные = Неопределено Тогда
Возврат;
КонецЕсли;
Если Данные.Ошибки.Количество() Тогда
Элементы.ДеревоТестовОшибки.ТекущаяСтрока = Данные.Ошибки[0].ПолучитьИдентификатор();
КонецЕсли;
ОбновитьДоступностьСравнения();
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийЭлементовТаблицыФормыДеревоТестовОшибки
&НаКлиенте
Процедура ДеревоТестовОшибкиПриАктивизацииСтроки(Элемент)
ОбновитьДоступностьСравнения();
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура Сравнить(Команда)
Данные = Элементы.ДеревоТестовОшибки.ТекущиеДанные;
Если Данные = Неопределено Или ПустаяСтрока(Данные.ОжидаемоеЗначение) И ПустаяСтрока(Данные.ФактическоеЗначение) Тогда
Возврат;
КонецЕсли;
ПараметрыФормы = Новый Структура("ОжидаемоеЗначение, ФактическоеЗначение", Данные.ОжидаемоеЗначение, Данные.ФактическоеЗначение);
ОткрытьФорму("Обработка.ЮТЮнитТесты.Форма.Сравнение", ПараметрыФормы, ЭтотОбъект, , , , , РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
&НаСервере
Процедура ОтобразитьРезультатыТестирования(АдресХранилища)
Данные = ПолучитьИзВременногоХранилища(АдресХранилища);
УдалитьИзВременногоХранилища(АдресХранилища);
РезультатТестирования = Данные.РезультатыТестирования;
Статусы = ЮТФабрика.СтатусыИсполненияТеста();
ОбщаяСтатистика = Статистика();
Для Каждого Набор Из РезультатТестирования Цикл
СтрокаНабора = ДеревоТестов.ПолучитьЭлементы().Добавить();
СтрокаНабора.Набор = Истина;
СтрокаНабора.Представление = Набор.Представление;
СтрокаНабора.Контекст = НормализоватьКонтекст(Набор.Режим);
СтрокаНабора.ПредставлениеВремяВыполнения = ЮТОбщий.ПредставлениеПродолжительности(Набор.Длительность);
СтрокаНабора.ВремяВыполнения = Набор.Длительность / 1000;
СтрокаНабора.ТипОбъекта = 2;
ЗаполнитьОшибки(СтрокаНабора, Набор);
СтатистикаНабора = Статистика();
Для Каждого Тест Из Набор.Тесты Цикл
СтрокаТеста = СтрокаНабора.ПолучитьЭлементы().Добавить();
СтрокаТеста.Представление = Тест.Имя;
СтрокаТеста.Контекст = НормализоватьКонтекст(Набор.Режим);
СтрокаТеста.ПредставлениеВремяВыполнения = ЮТОбщий.ПредставлениеПродолжительности(Тест.Длительность);
СтрокаТеста.ВремяВыполнения = Тест.Длительность / 1000;
СтрокаТеста.Состояние = Тест.Статус;
СтрокаТеста.ТипОбъекта = 3;
СтрокаТеста.Иконка = КартинкаСтатуса(Тест.Статус);
ЗаполнитьОшибки(СтрокаТеста, Тест);
ИнкрементСтатистики(СтатистикаНабора, Тест.Статус, Статусы);
КонецЦикла;
Если СтатистикаНабора.Сломано Тогда
СтрокаНабора.Состояние = Статусы.Сломан;
ИначеЕсли СтатистикаНабора.Упало Тогда
СтрокаНабора.Состояние = Статусы.Ошибка;
ИначеЕсли СтатистикаНабора.Пропущено Тогда
СтрокаНабора.Состояние = Статусы.Пропущен;
ИначеЕсли СтатистикаНабора.Неизвестно Тогда
СтрокаНабора.Состояние = Статусы.Ошибка;
Иначе
СтрокаНабора.Состояние = Статусы.Успешно;
КонецЕсли;
СтрокаНабора.Прогресс = ГрафическоеПредставлениеСтатистики(СтатистикаНабора);
СтрокаНабора.Иконка = КартинкаСтатуса(СтрокаНабора.Состояние);
Для Каждого Элемент Из СтатистикаНабора Цикл
ЮТОбщий.Инкремент(ОбщаяСтатистика[Элемент.Ключ], Элемент.Значение);
КонецЦикла;
КонецЦикла;
Элементы.СтатистикаВыполнения.Заголовок = ПредставлениеСтатистики(ОбщаяСтатистика);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ЗаполнитьОшибки(СтрокаДерева, ОписаниеОбъекта)
Для Каждого Ошибка Из ОписаниеОбъекта.Ошибки Цикл
СтрокаОшибки = СтрокаДерева.Ошибки.Добавить();
СтрокаОшибки.Сообщение = Ошибка.Сообщение;
СтрокаОшибки.Стек = Ошибка.Стек;
СтрокаОшибки.ОжидаемоеЗначение = ЮТОбщий.ЗначениеСтруктуры(Ошибка, "ОжидаемоеЗначение");
СтрокаОшибки.ФактическоеЗначение = ЮТОбщий.ЗначениеСтруктуры(Ошибка, "ПроверяемоеЗначение");
КонецЦикла;
КонецПроцедуры
&НаСервереБезКонтекста
Функция Статистика()
Статистика = Новый Структура();
Статистика.Вставить("Всего", 0);
Статистика.Вставить("Успешно", 0);
Статистика.Вставить("Упало", 0);
Статистика.Вставить("Сломано", 0);
Статистика.Вставить("Пропущено", 0);
Статистика.Вставить("Неизвестно", 0);
Возврат Статистика;
КонецФункции
&НаСервереБезКонтекста
Функция НормализоватьКонтекст(Контекст)
Если СтрНачинаетсяС(Контекст, "Клиент") Тогда
Возврат "Клиент";
Иначе
Возврат Контекст;
КонецЕсли;
КонецФункции
&НаСервереБезКонтекста
Процедура ИнкрементСтатистики(Статистика, Статус, Знач Статусы = Неопределено)
Если Статусы = Неопределено Тогда
Статусы = ЮТФабрика.СтатусыИсполненияТеста();
КонецЕсли;
ЮТОбщий.Инкремент(Статистика.Всего);
Если Статус = Статусы.Успешно Тогда
ЮТОбщий.Инкремент(Статистика.Успешно);
ИначеЕсли Статус = Статусы.Сломан ИЛИ Статус = Статусы.НеРеализован Тогда
ЮТОбщий.Инкремент(Статистика.Сломано);
ИначеЕсли Статус = Статусы.Ошибка Тогда
ЮТОбщий.Инкремент(Статистика.Упало);
ИначеЕсли Статус = Статусы.Пропущен Тогда
ЮТОбщий.Инкремент(Статистика.Пропущено);
Иначе
ЮТОбщий.Инкремент(Статистика.Неизвестно);
КонецЕсли;
КонецПроцедуры
#Область Интерфейсное
&НаСервереБезКонтекста
Функция КартинкаСтатуса(Статус)
Статусы = ЮТФабрика.СтатусыИсполненияТеста();
Если Статус = Статусы.Успешно Тогда
Возврат БиблиотекаКартинок.ЮТУспешно;
ИначеЕсли Статус = Статусы.Сломан ИЛИ Статус = Статусы.НеРеализован Тогда
Возврат БиблиотекаКартинок.ЮТОшибка;
ИначеЕсли Статус = Статусы.Ошибка Тогда
Возврат БиблиотекаКартинок.ЮТУпал;
ИначеЕсли Статус = Статусы.Пропущен Тогда
Возврат БиблиотекаКартинок.ЮТПропущен;
Иначе
Возврат БиблиотекаКартинок.ЮТНеизвестный;
КонецЕсли;
КонецФункции
&НаСервереБезКонтекста
Функция ПредставлениеСтатистики(Статистика)
БлокиСтатистики = Новый Массив();
Разделитель = "; ";
БлокиСтатистики.Добавить(СтрШаблон("Тестов: %1/%2", Статистика.Всего, Статистика.Всего - Статистика.Пропущено));
Если Статистика.Пропущено Тогда
БлокиСтатистики.Добавить(Разделитель);
БлокиСтатистики.Добавить(БиблиотекаКартинок.ЮТПропущен);
БлокиСтатистики.Добавить(" Пропущено: " + Статистика.Пропущено);
КонецЕсли;
БлокиСтатистики.Добавить(Разделитель);
БлокиСтатистики.Добавить(БиблиотекаКартинок.ЮТУспешно);
БлокиСтатистики.Добавить(" Успешно: " + Статистика.Успешно);
БлокиСтатистики.Добавить(Разделитель);
БлокиСтатистики.Добавить(БиблиотекаКартинок.ЮТОшибка);
БлокиСтатистики.Добавить(" Сломано: " + Статистика.Сломано);
БлокиСтатистики.Добавить(Разделитель);
БлокиСтатистики.Добавить(БиблиотекаКартинок.ЮТУпал);
БлокиСтатистики.Добавить(" Упало: " + Статистика.Упало);
Если Статистика.Неизвестно Тогда
БлокиСтатистики.Добавить(Разделитель);
БлокиСтатистики.Добавить(БиблиотекаКартинок.ЮТНеизвестный);
БлокиСтатистики.Добавить(" Неизвестно: " + Статистика.Неизвестно);
КонецЕсли;
Возврат Новый ФорматированнаяСтрока(БлокиСтатистики);
КонецФункции
&НаСервереБезКонтекста
Функция ГрафическоеПредставлениеСтатистики(Статистика)
Текст = БлокиСтатистики(Статистика);
Возврат Новый Картинка(ПолучитьДвоичныеДанныеИзСтроки(Текст));
КонецФункции
&НаСервереБезКонтекста
Функция БлокиСтатистики(Статистика)
Блоки = Новый Массив();
Блоки.Добавить(Новый Структура("Количество, Цвет", Статистика.Успешно, "25AE88"));
Блоки.Добавить(Новый Структура("Количество, Цвет", Статистика.Пропущено, "999999"));
Блоки.Добавить(Новый Структура("Количество, Цвет", Статистика.Упало, "EFCE4A"));
Блоки.Добавить(Новый Структура("Количество, Цвет", Статистика.Сломано, "D75A4A"));
Блоки.Добавить(Новый Структура("Количество, Цвет", Статистика.Неизвестно, "9400d3"));
Сдвиг = 0;
Высота = 20;
Текст = "";
Для Инд = 0 По Блоки.ВГраница() Цикл
Если Блоки[Инд].Количество = 0 Тогда
Продолжить;
КонецЕсли;
Текст = Текст + СтрШаблон(" <rect x=""%1"" y=""2"" width=""%2"" height=""%3"" rx=""4"" ry=""4"" style=""fill:none;stroke:#%4;stroke-width:2""/>
| <text x=""%5"" y=""%6"" dominant-baseline=""middle"" text-anchor=""middle"" style=""fill:#%4;"">%7</text>
|", Сдвиг + 2, Высота * 2 - 4, Высота - 4, Блоки[Инд].Цвет, Сдвиг + Высота, Высота - 4, Блоки[Инд].Количество);
ЮТОбщий.Инкремент(Сдвиг, Высота * 2 + 2);
КонецЦикла;
Возврат СтрШаблон("<svg version=""1.1"" xmlns=""http://www.w3.org/2000/svg"" xmlns:xlink=""http://www.w3.org/1999/xlink"" x=""0px"" y=""0px"" width=""%1px"" height=""%2px""
| viewBox=""0 0 %1 %2"">
| %3
|</svg>", Сдвиг, Высота + 2, Текст);
КонецФункции
#КонецОбласти
&НаКлиенте
Процедура ОбновитьДоступностьСравнения()
Данные = Элементы.ДеревоТестовОшибки.ТекущиеДанные;
Элементы.Сравнить.Доступность = Данные <> Неопределено И (НЕ ПустаяСтрока(Данные.ОжидаемоеЗначение) Или НЕ ПустаяСтрока(Данные.ФактическоеЗначение));
КонецПроцедуры
#КонецОбласти

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<form:Form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:core="http://g5.1c.ru/v8/dt/mcore" xmlns:form="http://g5.1c.ru/v8/dt/form">
<items xsi:type="form:FormField">
<name>Скрипт</name>
<id>4</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<dataPath xsi:type="form:DataPath">
<segments>Скрипт</segments>
</dataPath>
<defaultItem>true</defaultItem>
<titleLocation>None</titleLocation>
<extendedTooltip>
<name>СкриптРасширеннаяПодсказка</name>
<id>3</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<contextMenu>
<name>СкриптКонтекстноеМеню</name>
<id>2</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<autoFill>true</autoFill>
</contextMenu>
<type>HTMLDocumentField</type>
<editMode>Enter</editMode>
<showInHeader>true</showInHeader>
<headerHorizontalAlign>Left</headerHorizontalAlign>
<showInFooter>true</showInFooter>
<extInfo xsi:type="form:HtmlFieldExtInfo">
<width>50</width>
<height>10</height>
<horizontalStretch>true</horizontalStretch>
<verticalStretch>true</verticalStretch>
<borderColor xsi:type="core:ColorRef">
<color>Style.FormBackColor</color>
</borderColor>
</extInfo>
</items>
<commandBarLocation>None</commandBarLocation>
<autoCommandBar>
<name>ФормаКоманднаяПанель</name>
<id>-1</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<horizontalAlign>Left</horizontalAlign>
<autoFill>true</autoFill>
</autoCommandBar>
<handlers>
<event>OnCreateAtServer</event>
<name>ПриСозданииНаСервере</name>
</handlers>
<autoTitle>true</autoTitle>
<autoUrl>true</autoUrl>
<group>Vertical</group>
<autoFillCheck>true</autoFillCheck>
<allowFormCustomize>true</allowFormCustomize>
<enabled>true</enabled>
<showCloseButton>true</showCloseButton>
<attributes>
<name>Скрипт</name>
<title>
<key>ru</key>
<value>Скрипт</value>
</title>
<id>1</id>
<valueType>
<types>String</types>
<stringQualifiers/>
</valueType>
<view>
<common>true</common>
</view>
<edit>
<common>true</common>
</edit>
</attributes>
<commandInterface>
<navigationPanel/>
<commandBar/>
</commandInterface>
</form:Form>

View File

@ -0,0 +1,34 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2022 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.
//
//©///////////////////////////////////////////////////////////////////////////©//
#Область ОбработчикиСобытийФормы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ТекстСтраницы = Обработки.ЮТЮнитТесты.ПолучитьМакет("СравнениеOld").ПолучитьТекст();
ТекстСтраницы = СтрЗаменить(ТекстСтраницы, "ИсходныйТекст", Параметры.ОжидаемоеЗначение);
ТекстСтраницы = СтрЗаменить(ТекстСтраницы, "СравниваемыйТекст", Параметры.ФактическоеЗначение);
АдресСтраницы = ПоместитьВоВременноеХранилище(ПолучитьДвоичныеДанныеИзСтроки(ТекстСтраницы), УникальныйИдентификатор);
Скрипт = СтрШаблон("%1/%2", ПолучитьНавигационнуюСсылкуИнформационнойБазы(), АдресСтраницы);
КонецПроцедуры
#КонецОбласти

View File

@ -0,0 +1,61 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="GENERATOR" content="MSHTML 11.00.9600.19003">
<meta charset="UTF-8" />
<!-- jsdiff -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsdiff/5.1.0/diff.min.js" integrity="sha512-vco9RAxEuv4PQ+iTQyuKElwoUOcsVdp+WgU6Lgo82ASpDfF7vI66LlWz+CZc2lMdn52tjjLOuHvy8BQJFp8a1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- diff2html -->
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" />
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js"></script>
<style>
//.d2h-file-collapse, .d2h-info, .hidden, .d2h-tag { display: none !important; }
html,
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", system-ui, "Ubuntu", "Droid Sans", sans-serif;
font-size: 14px;
line-height: 22px;
}
body {
padding-top: 1em;
}
</style>
<script type="text/javascript">
function renderDiff() {
var renderTo = document.getElementById("container");
var expected = document.getElementById("expected").value;
var actual = document.getElementById("actual").value;
var diff = Diff.createTwoFilesPatch("expected", "actual", expected, actual);
var render =new Diff2HtmlUI(renderTo, diff,
{
inputFormat: 'diff',
synchronisedScroll: true,
matching: 'words',
diffStyle: 'char',
outputFormat: 'side-by-side',
renderNothingWhenEmpty: false,
drawFileList: false,
showFiles: false,
highlight: false,
stickyFileHeaders: false
}
);
render.draw();
}
</script>
</head>
<body onload="renderDiff();">
<div class="hidden">
<textarea id="expected">ИсходныйТекст</textarea>
</div>
<div class="hidden">
<textarea id="actual">СравниваемыйТекст</textarea>
</div>
<div id="container"></div>
</body>
</html>

View File

@ -0,0 +1,936 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta charset="UTF-8" />
<title>Diff test</title>
<script>
var SourceDiff = SourceDiff || {};
SourceDiff.Diff = function(ignoreLeadingWS) {
var trimTrailingWhiteSpace = function(str) {
if (str) {
return str.trim();
}
return str;
};
var checkTrimLeadingWhiteSpace = function(str) {
if (str && ignoreLeadingWS) {
return str.trim();
}
return str;
};
var trimWhiteSpace = function(str) {
if (!str) return str;
if (ignoreLeadingWS) {
return str.trim();
} else {
return str.trim();
}
};
var lineDiff = function(originalLine, editedLine) {
var originalTrimmed = checkTrimLeadingWhiteSpace(originalLine);
var editedTrimmed = checkTrimLeadingWhiteSpace(editedLine);
var originalOffset = originalLine.length - originalTrimmed.length;
var editOffset = editedLine.length - editedTrimmed.length;
originalTrimmed = trimTrailingWhiteSpace(originalTrimmed);
editedTrimmed = trimTrailingWhiteSpace(editedTrimmed);
var matrix = createMatrix(0, originalTrimmed, editedTrimmed);
fillMatrix(0, originalTrimmed, editedTrimmed, matrix);
return createLineDiff(originalTrimmed, editedTrimmed, originalOffset, editOffset, matrix);
};
var createLineDiff = function(originalTrimmed, editedTrimmed, originalOffset, editOffset, matrix) {
var diff = new SourceDiff.LineDiff();
var i = originalTrimmed.length;
var j = editedTrimmed.length;
while (i >= 0 && j >= 0) {
if (originalTrimmed[i - 1] === editedTrimmed[j - 1]) {
if (originalTrimmed[i - 1]) {
diff.addCommon(originalOffset + i - 1, editOffset + j - 1);
}
i--;
j--;
} else if (j >= 0 && (i === 0 || matrix[i][j - 1] >= matrix[i - 1][j])) {
if (editedTrimmed[j - 1].length > 0) {
diff.addInsert(editOffset + j - 1);
}
j--;
} else if (i >= 0 && (j === 0 || matrix[i][j - 1] < matrix[i - 1][j])) {
if (originalTrimmed[i - 1].length > 0) {
diff.addDelete(originalOffset + i - 1);
}
i--;
}
}
return diff;
};
var diff = function(originalText, editedText) {
var originalLines = SourceDiff.split(originalText);
var editedLines = SourceDiff.split(editedText);
SourceDiff.padBlankLines(originalLines);
SourceDiff.padBlankLines(editedLines);
var startPos = trimCommonLines(originalLines, editedLines);
var matrix = createMatrix(startPos, originalLines, editedLines);
fillMatrix(startPos, originalLines, editedLines, matrix);
var results = findAddsAndDeletes(originalLines, editedLines, startPos, matrix);
checkShiftEdits(SourceDiff.split(originalText), results.deleted);
checkShiftEdits(SourceDiff.split(editedText), results.added);
return results;
};
var findAddsAndDeletes = function(originalLines, editedLines, startPos, matrix) {
var i = originalLines.length;
var j = editedLines.length;
var added = new SourceDiff.EditSet();
var deleted = new SourceDiff.EditSet();
var allAddsOrDeletes = checkAllAddsOrDeletes(originalLines, editedLines, added) ||
checkAllAddsOrDeletes(editedLines, originalLines, deleted);
if (!allAddsOrDeletes) {
while (i >= startPos && j >= startPos) {
var m = i - startPos;
var n = j - startPos;
if (m > 0 && n > 0 && linesAreEqual(originalLines[i - 1], editedLines[j - 1])) {
i--;
j--;
} else if (j >= startPos && (i === startPos || matrix[m][n - 1] >= matrix[m - 1][n])) {
if (j - 1 >= startPos && editedLines[j - 1].length > 0) {
added.add(j - 1);
}
j--;
} else if (i >= startPos && (j === startPos || matrix[m][n - 1] < matrix[m - 1][n])) {
if (i - 1 >= startPos && originalLines[i - 1].length > 0) {
deleted.add(i - 1);
}
i--;
}
}
}
return {
added: added,
deleted: deleted
};
};
var checkAllAddsOrDeletes = function(lines, otherLines, editSet) {
if (lines.length === 1 && lines[0] === '') {
for (var i = 0; i < otherLines.length; i++) {
editSet.add(i);
}
return true;
}
return false;
};
var linesAreEqual = function(line1, line2) {
return trimWhiteSpace(line1) === trimWhiteSpace(line2);
};
//Find all continuous runs of inserts or deletes. For each run, see if it can be shifted forward 1 line.
//This is useful for properly pairing opening and closing braces in C-like languages, for example.
var checkShiftEdits = function(textLines, editSet) {
var editArray = editSet.all();
if (editArray.length > 0) {
var startRun = editArray[0];
var current = startRun;
for (var i = 1; i < editArray.length; i++) {
if (i === editArray.length - 1) { //end of the run and the edits
if (editArray[i] === current + 1) {
current++;
}
checkShiftRun(textLines, editSet, startRun, current);
} else if (editArray[i] === current + 1) {
current++;
} else { //end of the run
checkShiftRun(textLines, editSet, startRun, current);
startRun = current = editArray[i];
}
}
}
};
var checkShiftRun = function(textLines, editSet, startRun, endRun) {
if (linesAreEqual(textLines[startRun], textLines[endRun + 1]) && lineIsBlank(textLines[startRun + 1])) {
editSet.remove(startRun);
editSet.add(endRun + 1);
}
};
var lineIsBlank = function(line) {
return /^\s*$/.test(line);
};
var createMatrix = function(startPos, originalLines, editedLines) {
var matrix = [];
for (var i = 0; i <= originalLines.length - startPos; i++) {
matrix[i] = new Array(editedLines.length - startPos + 1);
matrix[i][0] = 0;
}
for (var j = 1; j <= editedLines.length - startPos; j++) {
matrix[0][j] = 0;
}
return matrix;
};
var fillMatrix = function(startPos, originalLines, editedLines, matrix) {
for (var i = 1; i <= originalLines.length - startPos; i++) {
var originalTrimmed = trimWhiteSpace(originalLines[i + startPos - 1]);
for (var j = 1; j <= editedLines.length - startPos; j++) {
var trimmedEdit = trimWhiteSpace(editedLines[j + startPos - 1]);
if (originalTrimmed === trimmedEdit) {
matrix[i][j] = matrix[i - 1][j - 1] + 1;
} else {
matrix[i][j] = Math.max(matrix[i][j - 1], matrix[i - 1][j]);
}
}
}
};
var trimCommonLines = function(originalLines, editedLines) {
var linesRemaining = function(startPos) {
return originalLines.length > startPos && editedLines.length > startPos
};
var startPos = 0;
while (linesRemaining(startPos) && linesAreEqual(originalLines[startPos], editedLines[startPos])) {
startPos++;
}
while (linesRemaining(startPos) && linesAreEqual(originalLines[originalLines.length - 1], editedLines[editedLines.length - 1])) {
originalLines.pop();
editedLines.pop();
}
return startPos;
};
return {
diff: diff,
trimCommonLines: trimCommonLines, //exposed for testing
lineDiff: lineDiff
};
};
SourceDiff.padBlankLines = function(lines) {
if (lines.length === 1 && lines[0] === '') {
return;
}
for (var l = 0; l < lines.length; l++) {
if (lines[l] === '') {
lines[l] = ' ';
}
}
};
SourceDiff.split = function(string) {
return string.split(/\r?\n/);
};
SourceDiff.LineFormatter = function(results, lineDiffs) {
var anchors = new SourceDiff.EditSet();
var added = results.added.all();
var deleted = results.deleted.all();
var lineIsCommon = function(i) {
return !results.added.contains(i) && !results.deleted.contains(i)
};
if (!lineIsCommon(0)) {
anchors.add(0);
}
for (var i = 0; i < Math.max(Math.max.apply(null, added), Math.max.apply(null, deleted)); i++) {
if (lineIsCommon(i) && !lineIsCommon(i + 1)) {
anchors.add(i);
}
}
var formatLeftText = function(text1Lines) {
var deletedText = '';
var startingPos = getStartingPos(results);
var text1EndingPos = getEndingPos(results, text1Lines);
for (var i = startingPos; i < text1EndingPos; i++) {
if (anchors.contains(i)) {
deletedText += '<a name="' + i + '"></a>';
}
if (lineDiffs.contains(i) && results.modifiedLeft.contains(i)) {
var lineDiff = lineDiffs.get(i);
deletedText += appendModifiedLine(text1Lines[i], lineDiff.deleted);
} else {
var className = getClassNameLeft(results, i);
deletedText += appendLine(className, text1Lines[i]);
}
}
return deletedText;
};
var formatRightText = function(text2Lines) {
var addedText = '';
var startingPos = getStartingPos(results);
var text2EndingPos = getEndingPos(results, text2Lines);
for (var i = startingPos; i < text2EndingPos; i++) {
if (lineDiffs.contains(i) && results.modifiedRight.contains(i)) {
var lineDiff = lineDiffs.get(i);
addedText += appendModifiedLine(text2Lines[i], lineDiff.added);
} else {
var className = getClassNameRight(results, i);
addedText += appendLine(className, text2Lines[i]);
}
}
return addedText;
};
var appendModifiedLine = function(textLine, lineEdits) {
var formattedText = '<span class="modified">';
var startIndex = 0;
for (var j = 0; j < lineEdits.length; j++) {
formattedText += escapeHtml(textLine.substring(startIndex, lineEdits[j].position));
startIndex = lineEdits[j].endPosition + 1;
formattedText += '<span class="modified-light">' + escapeHtml(textLine.substring(lineEdits[j].position, startIndex)) +
'</span>';
}
if (startIndex < textLine.length) {
formattedText += escapeHtml(textLine.substring(startIndex, textLine.length));
}
formattedText += '</span><br>';
return formattedText;
};
var getStartingPos = function(results) {
var allDeletes = results.deleted.all();
var firstDelete = allDeletes.length > 0 ?
allDeletes[0] :
-1;
var allAdds = results.added.all();
var firstAdd = allAdds.length > 0 ?
allAdds[0] :
-1;
var firstEdit;
if (firstDelete === -1) {
firstEdit = firstAdd;
} else if (firstAdd === -1) {
firstEdit = firstDelete;
} else {
firstEdit = Math.min(firstDelete, firstAdd)
}
return Math.max(0, firstEdit - 10);
};
var getEndingPos = function(results, lines) {
var allDeletes = results.deleted.all();
var lastDelete = allDeletes.length > 0 ?
allDeletes[allDeletes.length - 1] :
0;
var allAdds = results.added.all();
var lastAdd = allAdds.length > 0 ?
allAdds[allAdds.length - 1] :
0;
var lastEdit = Math.max(lastDelete, lastAdd);
return Math.min(lines.length, lastEdit + 11);
};
var getClassNameLeft = function(results, i) {
var className = '';
if (results.modifiedLeft.contains(i)) {
className = 'modified';
} else if (results.paddingLeft.contains(i)) {
className = 'padding';
} else if (results.deleted.contains(i)) {
className = 'deleted';
}
return className;
};
var getClassNameRight = function(results, i) {
var className = '';
if (results.modifiedRight.contains(i)) {
className = 'modified';
} else if (results.paddingRight.contains(i)) {
className = 'padding';
} else if (results.added.contains(i)) {
className = 'inserted';
}
return className;
};
var appendLine = function(className, line) {
var append = '';
if (className != '') {
append += '<span class="' + className + '">';
}
append += escapeHtml(line);
if (className != '') {
append += '</span>';
}
append += '<br>';
return append;
};
var escapeHtml = function(string) {
var entityMap = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;',
'/': '&#x2F;'
};
var replacedTabs = string.replace(/\t/g, ' ');
return String(replacedTabs).replace(/[&<>"'\/]/g, function(s) {
return entityMap[s];
});
};
var getEditIterator = function() {
return new SourceDiff.AnchorIterator(anchors);
};
return {
formatLeftText: formatLeftText,
formatRightText: formatRightText,
getEditIterator: getEditIterator
};
};
SourceDiff.LineDiff = function() {
var _added = [];
var _deleted = [];
var _common = [];
var addCommon = function(leftPosition, rightPosition) {
_common.unshift({
leftPosition: leftPosition,
leftEndPosition: leftPosition,
rightPosition: rightPosition,
rightEndPosition: rightPosition
});
};
var addDelete = function(position) {
_deleted.unshift({
position: position,
endPosition: position
});
};
var addInsert = function(position) {
_added.unshift({
position: position,
endPosition: position
});
};
var editLength = function(edit) {
if (!edit) {
return 0;
}
return edit.endPosition - edit.position + 1;
};
var cleanUp = function() {
mergeAdjacent(_added);
mergeAdjacent(_deleted);
mergeAdjacentCommon();
do {
var didMerge = false;
for (var i = 0; i < _common.length; i++) {
var equalityLength = _common[i].leftEndPosition - _common[i].leftPosition + 1;
var leftDelete = findEditWithEndingPosition(_deleted, _common[i].leftPosition - 1);
var rightDelete = findEditWithPosition(_deleted, _common[i].leftEndPosition + 1);
var leftAdd = findEditWithEndingPosition(_added, _common[i].rightPosition - 1);
var rightAdd = findEditWithPosition(_added, _common[i].rightEndPosition + 1);
if (equalityLength <= 8 && editLength(leftDelete) + editLength(leftAdd) >= equalityLength &&
editLength(rightDelete) + editLength(rightAdd) >= equalityLength) {
didMerge = true;
if (leftDelete && rightDelete) {
leftDelete.endPosition = rightDelete.endPosition;
removeEdit(_deleted, rightDelete);
} else if (leftDelete) {
leftDelete.endPosition = _common[i].leftEndPosition;
} else if (rightDelete) {
rightDelete.position = _common[i].leftPosition;
} else {
addEdit(_deleted, _common[i].leftPosition, _common[i].leftEndPosition);
}
if (leftAdd && rightAdd) {
leftAdd.endPosition = rightAdd.endPosition;
removeEdit(_added, rightAdd);
} else if (leftAdd) {
leftAdd.endPosition = _common[i].rightEndPosition;
} else if (rightAdd) {
rightAdd.position = _common[i].rightPosition;
} else {
addEdit(_added, _common[i].rightPosition, _common[i].rightEndPosition);
}
_common.splice(i, 1);
}
}
} while (didMerge)
};
var mergeAdjacentCommon = function() {
for (var i = 0; i < _common.length; i++) {
if (i + 1 < _common.length &&
_common[i].leftEndPosition + 1 === _common[i + 1].leftPosition &&
_common[i].rightEndPosition + 1 === _common[i + 1].rightPosition) {
_common[i].leftEndPosition = _common[i + 1].leftEndPosition;
_common[i].rightEndPosition = _common[i + 1].rightEndPosition;
_common.splice(i + 1, 1);
i--;
}
}
};
var addEdit = function(edits, position, endPosition) {
var newEdit = {
position: position,
endPosition: endPosition
};
if (edits.length === 0) {
edits.push(newEdit);
} else if (position < edits[0].position) {
edits.unshift(newEdit);
} else {
for (var i = edits.length - 1; i >= 0; i--) {
if (position > edits[i].position) {
edits.splice(i + 1, 0, newEdit);
break;
}
}
}
};
var removeEdit = function(edits, item) {
for (var i = 0; i < edits.length; i++) {
if (edits[i] === item) {
edits.splice(i, 1);
break;
}
}
};
var findEditWithPosition = function(edits, pos) {
for (var i = 0; i < edits.length; i++) {
if (edits[i].position === pos) {
return edits[i];
}
}
};
var findEditWithEndingPosition = function(edits, endPos) {
for (var i = 0; i < edits.length; i++) {
if (edits[i].endPosition === endPos) {
return edits[i];
}
}
};
var mergeAdjacent = function(edits) {
for (var i = 0; i < edits.length; i++) {
if (i + 1 < edits.length && edits[i].endPosition + 1 === edits[i + 1].position) {
edits[i].endPosition = edits[i + 1].endPosition;
edits.splice(i + 1, 1);
i--;
}
}
};
return {
addDelete: addDelete,
addInsert: addInsert,
addCommon: addCommon,
cleanUp: cleanUp,
added: _added,
deleted: _deleted,
common: _common
};
};
SourceDiff.EditSet = function() {
var _set = {};
var add = function(line) {
_set[line] = true;
};
var addValue = function(line, value) {
_set[line] = value;
};
var remove = function(line) {
_set[line] = undefined;
};
var count = function() {
return all().length;
};
var get = function(line) {
return _set[line];
}
var sortIntegers = function(a, b) {
return a - b;
};
var all = function() {
var arr = [];
for (var prop in _set) {
if (_set[prop]) {
arr.push(parseInt(prop));
}
}
return arr.sort(sortIntegers);
};
var contains = function(lineNumber) {
return _set[lineNumber] !== undefined;
};
var updateNumbers = function(lineNumber) {
var newSet = {};
for (var prop in _set) {
var value = _set[prop];
if (value) {
var parsed = parseInt(prop);
if (parsed >= lineNumber) {
newSet[parsed + 1] = value;
} else {
newSet[parsed] = value;
}
}
}
_set = newSet;
};
return {
add: add,
addValue: addValue,
get: get,
remove: remove,
count: count,
all: all,
updateNumbers: updateNumbers,
contains: contains
};
};
SourceDiff.DiffFormatter = function(diff) {
var formattedDiff = function(originalText, editedText) {
var results = diff.diff(originalText, editedText);
var lines = lineUpText(originalText, editedText, results);
var originalLines = lines[0];
var editedLines = lines[1];
findModifiedLines(originalLines, editedLines, results);
var lineDiffs = diffModifiedLines(originalLines, editedLines, results);
var lineFormatter = SourceDiff.LineFormatter(results, lineDiffs);
var deletedText = lineFormatter.formatLeftText(originalLines);
var addedText = lineFormatter.formatRightText(editedLines);
return [deletedText, addedText, lineFormatter.getEditIterator()];
};
var lineUpText = function(originalText, editedText, results) {
var originalLines = SourceDiff.split(originalText);
var editedLines = SourceDiff.split(editedText);
SourceDiff.padBlankLines(originalLines);
SourceDiff.padBlankLines(editedLines);
results.paddingLeft = new SourceDiff.EditSet();
results.paddingRight = new SourceDiff.EditSet();
for (var i = 0; i < Math.max(originalLines.length, editedLines.length); i++) {
if (!results.deleted.contains(i) && results.added.contains(i)) {
originalLines.splice(i, 0, ' ');
results.deleted.updateNumbers(i);
results.paddingLeft.add(i);
} else if (results.deleted.contains(i) && !results.added.contains(i)) {
editedLines.splice(i, 0, ' ');
results.added.updateNumbers(i);
results.paddingRight.add(i);
}
}
return [originalLines, editedLines];
};
var findModifiedLines = function(originalLines, editedLines, results) {
results.modifiedRight = new SourceDiff.EditSet();
results.modifiedLeft = new SourceDiff.EditSet();
for (var i = 0; i < originalLines.length && i < editedLines.length; i++) {
if (results.added.contains(i) && results.deleted.contains(i)) {
results.modifiedLeft.add(i);
results.modifiedRight.add(i);
} else if (results.added.contains(i) && results.modifiedRight.contains(i - 1)) {
results.modifiedRight.add(i);
} else if (results.deleted.contains(i) && results.modifiedLeft.contains(i - 1)) {
results.modifiedLeft.add(i);
}
}
};
var diffModifiedLines = function(originalLines, editedLines, results) {
var lineDiffs = new SourceDiff.EditSet();
for (var i = 0; i < originalLines.length && i < editedLines.length; i++) {
if (results.modifiedLeft.contains(i) || results.modifiedRight.contains(i)) {
var lineDiff = diff.lineDiff(originalLines[i], editedLines[i]);
lineDiff.cleanUp();
lineDiffs.addValue(i, lineDiff);
}
}
return lineDiffs;
};
return {
lineUpText: lineUpText, //exposed for testing
formattedDiff: formattedDiff
};
};
SourceDiff.AnchorIterator = function(anchors) {
var allAnchors = anchors.all();
var currentIndex = 0;
var getNextEdit = function() {
if (currentIndex + 1 < allAnchors.length) {
currentIndex++;
return allAnchors[currentIndex];
}
return false;
};
var getPrevEdit = function() {
if (currentIndex - 1 >= 0) {
currentIndex--;
return allAnchors[currentIndex];
}
return false;
};
return {
getNextEdit: getNextEdit,
getPrevEdit: getPrevEdit
};
};
</script>
<style>
pre {
background-color: white;
margin: 5px;
white-space: pre;
word-wrap: normal;
border: none;
}
h3 {
margin: 10px;
}
.text {
width: 50%;
}
.wrapper {
width: 98%;
}
.left {
float: left;
width: 49%;
}
.right {
float: right;
width: 49%;
}
.scroll {
overflow-x: scroll;
overflow-y: auto;
height: 98%;
}
.inserted {
background-color: #9E9;
min-width: 100%;
display: inline-block;
}
.deleted {
background-color: #E99;
min-width: 100%;
display: inline-block;
}
.modified {
background-color: #FD8;
min-width: 100%;
display: inline-block;
}
.modified-light {
background-color: #fcffb6;
/*min-width: 100%;*/
/*display: inline-block;*/
}
.padding {
background-color: lightgray;
min-width: 100%;
display: inline-block;
}
.header {
position: fixed;
background: white;
width: 50%;
text-align: center;
}
.spacer {
width: 100%;
height: 50px;
}
textarea {
display: none;
}
html,
body {
margin: 0;
width: 100%;
height: 100%;
overflow-x: hidden;
}
</style>
</head>
<body onload="doDiff()">
<textarea id="original">ИсходныйТекст</textarea>
<textarea id="edited">СравниваемыйТекст</textarea>
<div class="wrapper header">
<div class="right">
<h3>Edit</h3>
</div>
</div>
<div class="left scroll diff-content" id="scrollLeft">
<div class="header">
<h3>Ожидаемое значение</h3>
</div>
<div class="spacer"></div>
<pre id="original_result"></pre>
</div>
<div class="right scroll diff-content" id="scrollRight">
<div class="header">
<h3>Фактическое значение</h3>
</div>
<div class="spacer"></div>
<pre id="edited_result"></pre>
</div>
<script>
var scrollLeft = document.getElementById('scrollLeft');
var scrollRight = document.getElementById('scrollRight');
scrollLeft.addEventListener('scroll', function() {
scrollRight.scrollLeft = scrollLeft.scrollLeft;
scrollRight.scrollTop = scrollLeft.scrollTop;
});
scrollRight.addEventListener('scroll', function() {
scrollLeft.scrollLeft = scrollRight.scrollLeft;
scrollLeft.scrollTop = scrollRight.scrollTop;
});
function doDiff() {
var diff = new SourceDiff.Diff(true); //ignore leading whitespace
var formatter = new SourceDiff.DiffFormatter(diff);
var text1 = document.getElementById('original').value;
var text2 = document.getElementById('edited').value;
var results = formatter.formattedDiff(text1, text2);
document.getElementById('original_result').innerHTML = results[0];
document.getElementById('edited_result').innerHTML = results[1];
}
</script>
</body>
</html>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:DataProcessor xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="c1bdc484-8502-4c5d-bead-0a5861739c3c">
<producedTypes>
<objectType typeId="5b4ab199-21bb-4d2c-9b3f-76400ff90d09" valueTypeId="46e26617-02e4-4719-87a0-982b4820504f"/>
<managerType typeId="cea40759-07dd-409f-8c26-be7e738c7fbe" valueTypeId="e3a7e7ca-1e0d-4fdf-9390-258825a6bba5"/>
</producedTypes>
<name>ЮТЮнитТесты</name>
<synonym>
<key>ru</key>
<value>Юнит тесты</value>
</synonym>
<useStandardCommands>true</useStandardCommands>
<defaultForm>DataProcessor.ЮТЮнитТесты.Form.Основная</defaultForm>
<forms uuid="c3c0fc7f-1c5e-47d9-b103-201517e2c100">
<name>Основная</name>
<synonym>
<key>ru</key>
<value>Основная</value>
</synonym>
<usePurposes>PersonalComputer</usePurposes>
<usePurposes>MobileDevice</usePurposes>
</forms>
<forms uuid="7b2e6e42-7ce3-4e80-b14c-6c492850cc66">
<name>Сравнение</name>
<synonym>
<key>ru</key>
<value>Сравнение</value>
</synonym>
<usePurposes>PersonalComputer</usePurposes>
<usePurposes>MobileDevice</usePurposes>
</forms>
<templates uuid="2b46baf7-b195-4fa1-8014-1130b555872f">
<name>Сравнение</name>
<synonym>
<key>ru</key>
<value>Сравнение</value>
</synonym>
<templateType>TextDocument</templateType>
</templates>
<templates uuid="44459710-21e4-4399-a5ba-253d36a7fbbc">
<name>СравнениеOld</name>
<synonym>
<key>ru</key>
<value>Сравнение old</value>
</synonym>
<templateType>TextDocument</templateType>
</templates>
</mdclass:DataProcessor>

View File

@ -36,4 +36,11 @@
<content>CommonModule.ЮТТестовыеДанныеВызовСервера</content>
<content>CommonModule.ЮТест</content>
<content>CommonModule.ЮТКонтекстТеста</content>
<content>CommonPicture.ЮТНеизвестный</content>
<content>CommonPicture.ЮТОшибка</content>
<content>CommonPicture.ЮТПропущен</content>
<content>CommonPicture.ЮТУпал</content>
<content>CommonPicture.ЮТУспешно</content>
<content>CommonPicture.ЮТЭлементыТестов</content>
<content>DataProcessor.ЮТЮнитТесты</content>
</mdclass:Subsystem>

View File

@ -1,3 +1,3 @@
Manifest-Version: 1.0
Runtime-Version: 8.3.10
Base-Project: BSP
Base-Project: configuration