Skip to content

Commit 6ff0f91

Browse files
authored
Merge pull request Segate-ekb#4 from Segate-ekb/feature/test_suits
Разделение по тегам и генерация
2 parents 961e52f + 1bde7a7 commit 6ff0f91

File tree

10 files changed

+5445
-307
lines changed

10 files changed

+5445
-307
lines changed

src/internal/Модули/Десериализатор.os

Lines changed: 1095 additions & 142 deletions
Large diffs are not rendered by default.

src/internal/Модули/Сериализатор.os

Lines changed: 147 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,51 @@
1212
Функция Сериализовать(Знач Значение, УровеньОтступа = 0) Экспорт
1313

1414
ТипЗначения = ТипЗнч(Значение);
15+
Результат = "";
16+
17+
// Если это корневой уровень, добавляем разделитель документа
18+
Если УровеньОтступа = 0 Тогда
19+
Результат = "---" + Символы.ПС;
20+
КонецЕсли;
1521

1622
Если ТипЗначения = Тип("Строка") Тогда
17-
Возврат СериализоватьСтроку(Значение);
23+
Результат = Результат + СериализоватьСтроку(Значение);
1824
ИначеЕсли ТипЗначения = Тип("Число") Тогда
19-
Возврат СериализоватьЧисло(Значение);
25+
Результат = Результат + СериализоватьЧисло(Значение);
2026
ИначеЕсли ТипЗначения = Тип("Булево") Тогда
21-
Возврат СериализоватьБулево(Значение);
27+
Результат = Результат + СериализоватьБулево(Значение);
2228
ИначеЕсли ТипЗначения = Тип("Массив") Тогда
23-
Возврат СериализоватьМассив(Значение, УровеньОтступа);
29+
Результат = Результат + СериализоватьМассив(Значение, УровеньОтступа);
2430
ИначеЕсли ТипЗначения = Тип("Структура") Или ТипЗначения = Тип("Соответствие") Тогда
25-
Возврат СериализоватьОбъект(Значение, УровеньОтступа);
31+
Результат = Результат + СериализоватьОбъект(Значение, УровеньОтступа);
2632
ИначеЕсли Значение = Неопределено Тогда
27-
Возврат "null";
33+
Результат = Результат + "null";
2834
ИначеЕсли ТипЗначения = Тип("Дата") Тогда
2935
// Используем JSON писателя для корректной сериализации дат
3036
ЗаписьJSON = Новый ЗаписьJSON;
3137
ЗаписьJSON.УстановитьСтроку();
3238
ЗаписатьJSON(ЗаписьJSON, Значение);
33-
Возврат ЗаписьJSON.Закрыть();
39+
Результат = Результат + ЗаписьJSON.Закрыть();
3440
Иначе
3541
// Для неизвестных типов пытаемся использовать JSON сериализацию
3642
Попытка
3743
ЗаписьJSON = Новый ЗаписьJSON;
3844
ЗаписьJSON.УстановитьСтроку();
3945
ЗаписатьJSON(ЗаписьJSON, Значение);
40-
Возврат ЗаписьJSON.Закрыть();
46+
Результат = Результат + ЗаписьJSON.Закрыть();
4147
Исключение
4248
// Если JSON не справился, используем строковое представление
43-
Возврат СериализоватьСтроку(Строка(Значение));
49+
Результат = Результат + СериализоватьСтроку(Строка(Значение));
4450
КонецПопытки;
4551
КонецЕсли;
4652

53+
// Если это корневой уровень, добавляем разделитель конца документа
54+
Если УровеньОтступа = 0 Тогда
55+
Результат = Результат + Символы.ПС + "...";
56+
КонецЕсли;
57+
58+
Возврат Результат;
59+
4760
КонецФункции
4861

4962
// Сериализация строки
@@ -61,6 +74,11 @@
6174
Возврат """""";
6275
КонецЕсли;
6376

77+
// Если строка содержит переносы строк, используем блочный стиль
78+
Если СтрНайти(Значение, Символы.ПС) > 0 ИЛИ СтрНайти(Значение, Символы.ВК) > 0 Тогда
79+
Возврат СериализоватьМногострочнуюСтроку(Значение);
80+
КонецЕсли;
81+
6482
// Проверяем, нужно ли заключать в кавычки
6583
Если ТребуетсяЗаключениеВКавычки(Значение) Тогда
6684
// Используем JSON писателя для корректного экранирования строки
@@ -74,6 +92,36 @@
7492

7593
КонецФункции
7694

95+
// Сериализация многострочной строки
96+
//
97+
// Параметры:
98+
// Значение - Строка - многострочная строка для сериализации
99+
//
100+
// Возвращаемое значение:
101+
// Строка - YAML представление многострочной строки
102+
//
103+
Функция СериализоватьМногострочнуюСтроку(Значение)
104+
105+
// Нормализуем переносы строк
106+
НормализованноеЗначение = СтрЗаменить(Значение, Символы.ВК, Символы.ПС);
107+
108+
// Разделяем на строки
109+
Строки = СтрРазделить(НормализованноеЗначение, Символы.ПС, Ложь);
110+
111+
// Используем блочный литеральный стиль |
112+
Результат = "|" + Символы.ПС;
113+
114+
Для Каждого Строка Из Строки Цикл
115+
Результат = Результат + " " + Строка + Символы.ПС;
116+
КонецЦикла;
117+
118+
// Убираем последний перенос строки
119+
Результат = Лев(Результат, СтрДлина(Результат) - 1);
120+
121+
Возврат Результат;
122+
123+
КонецФункции
124+
77125
// Сериализация числа
78126
//
79127
// Параметры:
@@ -123,27 +171,85 @@
123171

124172
Результат = "";
125173
Отступ = ПолучитьОтступ(УровеньОтступа);
174+
ПервыйЭлемент = Истина;
126175

127176
Для Каждого Элемент Из Массив Цикл
128-
Результат = Результат + Символы.ПС;
177+
Если НЕ ПервыйЭлемент Тогда
178+
Результат = Результат + Символы.ПС;
179+
КонецЕсли;
180+
ПервыйЭлемент = Ложь;
181+
182+
ТипЭлемента = ТипЗнч(Элемент);
129183

130-
СериализованныйЭлемент = Сериализовать(Элемент, УровеньОтступа + 1);
131-
МассивСтрок = СтрРазделить(СериализованныйЭлемент, Символы.ПС, Ложь);
132-
СериализованныйЭлемент = "";
133-
ОтступВложения = ПолучитьОтступ(УровеньОтступа + 1);
134-
Для каждого Строка Из МассивСтрок Цикл
135-
СериализованныйЭлемент = СериализованныйЭлемент + ?(ЗначениеЗаполнено(СериализованныйЭлемент), Символы.ПС + ОтступВложения, Отступ + "- ") + СокрЛП(Строка);
136-
КонецЦикла;
137-
// Убираем последний отступ
138-
СериализованныйЭлемент = СокрП(СериализованныйЭлемент);
139-
Результат = Результат + СериализованныйЭлемент;
184+
// Для объектов и массивов используем специальную обработку
185+
Если ТипЭлемента = Тип("Структура") ИЛИ ТипЭлемента = Тип("Соответствие") ИЛИ ТипЭлемента = Тип("Массив") Тогда
186+
СериализованныйЭлемент = Сериализовать(Элемент, УровеньОтступа + 1);
187+
Результат = Результат + ОбработатьМногострочныйЭлементМассива(СериализованныйЭлемент, Отступ, УровеньОтступа);
188+
Иначе
189+
// Простые значения (строки, числа, булево)
190+
СериализованныйЭлемент = Сериализовать(Элемент, УровеньОтступа + 1);
191+
Результат = Результат + Отступ + "- " + СериализованныйЭлемент;
192+
КонецЕсли;
140193

141194
КонецЦикла;
142195

143196
Возврат Результат;
144197

145198
КонецФункции
146199

200+
// Обработка многострочного элемента в массиве
201+
//
202+
// Параметры:
203+
// СериализованныйЭлемент - Строка - сериализованный элемент с переносами строк
204+
// Отступ - Строка - базовый отступ для массива
205+
// УровеньОтступа - Число - уровень отступа
206+
//
207+
// Возвращаемое значение:
208+
// Строка - отформатированный элемент массива
209+
//
210+
Функция ОбработатьМногострочныйЭлементМассива(СериализованныйЭлемент, Отступ, УровеньОтступа)
211+
212+
МассивСтрок = СтрРазделить(СериализованныйЭлемент, Символы.ПС, Ложь);
213+
ОжидаемыйОтступ = ПолучитьОтступ(УровеньОтступа + 1);
214+
215+
Результат = "";
216+
Для Инд = 0 По МассивСтрок.Количество() - 1 Цикл
217+
СтрокаЭлемента = МассивСтрок[Инд];
218+
219+
Если Инд = 0 Тогда
220+
// Первая строка - убираем ожидаемый отступ и добавляем "- "
221+
СтрокаБезОтступа = УбратьОжидаемыйОтступ(СтрокаЭлемента, ОжидаемыйОтступ);
222+
Результат = Результат + Отступ + "- " + СтрокаБезОтступа;
223+
Иначе
224+
// Остальные строки - заменяем ожидаемый отступ на отступ массива + 2 пробела
225+
ОстатокСтроки = УбратьОжидаемыйОтступ(СтрокаЭлемента, ОжидаемыйОтступ);
226+
Результат = Результат + Символы.ПС + Отступ + " " + ОстатокСтроки;
227+
КонецЕсли;
228+
КонецЦикла;
229+
230+
Возврат Результат;
231+
232+
КонецФункции
233+
234+
// Убрать ожидаемый отступ из строки
235+
//
236+
// Параметры:
237+
// СтрокаЭлемента - Строка - исходная строка
238+
// ОжидаемыйОтступ - Строка - ожидаемый отступ для удаления
239+
//
240+
// Возвращаемое значение:
241+
// Строка - строка без ожидаемого отступа
242+
//
243+
Функция УбратьОжидаемыйОтступ(СтрокаЭлемента, ОжидаемыйОтступ)
244+
245+
Если СтрНачинаетсяС(СтрокаЭлемента, ОжидаемыйОтступ) Тогда
246+
Возврат Сред(СтрокаЭлемента, СтрДлина(ОжидаемыйОтступ) + 1);
247+
Иначе
248+
Возврат СокрЛП(СтрокаЭлемента);
249+
КонецЕсли;
250+
251+
КонецФункции
252+
147253
// Сериализация объекта
148254
//
149255
// Параметры:
@@ -161,18 +267,35 @@
161267

162268
Результат = "";
163269
Отступ = ПолучитьОтступ(УровеньОтступа);
270+
ПервыйЭлемент = Истина;
164271

165272
Для Каждого КлючЗначение Из Объект Цикл
166-
Результат = Результат + Символы.ПС;
273+
Если НЕ ПервыйЭлемент Тогда
274+
Результат = Результат + Символы.ПС;
275+
КонецЕсли;
276+
ПервыйЭлемент = Ложь;
167277

168278
Ключ = КлючЗначение.Ключ;
169279
Значение = КлючЗначение.Значение;
170280

171281
СериализованныйКлюч = СериализоватьКлюч(Ключ);
172282
СериализованноеЗначение = Сериализовать(Значение, УровеньОтступа + 1);
173283

174-
284+
// Если значение содержит переносы строк (массив или сложный объект),
285+
// то нужно размещать его на новой строке с правильными отступами
286+
Если СтрНайти(СериализованноеЗначение, Символы.ПС) > 0 Тогда
287+
// Сложное значение - размещаем на новой строке
288+
// Но для многострочных строк с | добавляем пробел
289+
Если СтрНачинаетсяС(СериализованноеЗначение, "|") Тогда
290+
Результат = Результат + Отступ + СериализованныйКлюч + ": " + СериализованноеЗначение;
291+
Иначе
292+
// Для массивов и объектов - значение начинается с новой строки
293+
Результат = Результат + Отступ + СериализованныйКлюч + ":" + Символы.ПС + СериализованноеЗначение;
294+
КонецЕсли;
295+
Иначе
296+
// Простое значение - размещаем на той же строке
175297
Результат = Результат + Отступ + СериализованныйКлюч + ": " + СериализованноеЗначение;
298+
КонецЕсли;
176299
КонецЦикла;
177300

178301
Возврат Результат;
@@ -299,6 +422,7 @@
299422
КонецЕсли;
300423

301424
// Строки, которые могут интерпретироваться как специальные значения YAML
425+
// НО только если они точно совпадают
302426
СпециальныеЗначения = Новый Массив;
303427
СпециальныеЗначения.Добавить("true");
304428
СпециальныеЗначения.Добавить("false");
@@ -309,7 +433,7 @@
309433
СпециальныеЗначения.Добавить("on");
310434
СпециальныеЗначения.Добавить("off");
311435

312-
НижнийРегистр = НРег(Значение);
436+
НижнийРегистр = НРег(СокрЛП(Значение));
313437
Для Каждого СпециальноеЗначение Из СпециальныеЗначения Цикл
314438
Если НижнийРегистр = СпециальноеЗначение Тогда
315439
Возврат Истина;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
nested sequences:
3-
- - - []
4-
- - - {}
3+
- - - []
4+
- - - {}
55
key1: []
66
key2: {}

tests/fixtures/yaml-test-suite/A6F9/in.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ strip: |-
33
clip: |
44
text
55
keep: |+
6-
text
6+
text
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
CUP7
2-
HMQ5
3-
SU5Z - Вроде валидный json, парсер не ругается.
4-
5-
######################### Преобразования json ###################
6-
C2SP - Подумать, как в таких нодах определять основной значащий символ...
7-
Q4CL - Не понимаю, почему ЧтениеJSON пропускает "quoted2" trailing content надо разобраться
1+
CUP7
2+
HMQ5
3+
SU5Z - Вроде валидный json, парсер не ругается.
4+
5+
######################### whitespaces ###################
6+
4Q9F - Я не понял, почему тут в json 2 перевода строки между ef и gh. Судя по доке - вроде один должен быть...
7+
A2M4 - Функционал A question mark and space (“? ”) indicate a complex mapping key

0 commit comments

Comments
 (0)