Исправлена ошибка при чтении строк, содержащих дату в формате ISO 8601, при использовании объекта ЧтениеJSON и глобальной функции ПрочитатьJSON: строки с датой больше не преобразуются в Дату автоматически#1682
Conversation
Исправлено поведение объекта ЧтениеJSON и глобальной функции ПрочитатьJSON, строки с датами не конвертируются автоматически в дату
📝 WalkthroughWalkthroughJSONReader now disables Newtonsoft automatic date parsing (DateParseHandling.None) in OpenFile, OpenStream, and SetString. Five tests and a JSON fixture were added to verify ISO-8601 datetime values are read and preserved as strings from string, stream, and file inputs. ChangesISO-8601 Datetime String Handling
Sequence DiagramsequenceDiagram
participant JSONInput as JSON Input
participant JSONReader
participant JsonReaderInternal as JsonReaderInternal
participant TestConsumer as Test/Consumer
JSONInput->>JSONReader: provide JSON with ISO-8601 string
JSONReader->>JsonReaderInternal: initialize with DateParseHandling = None
JsonReaderInternal->>TestConsumer: emit token as String (not Date)
TestConsumer->>TestConsumer: assert value and type are original string
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/json/test-json_reader.os (1)
265-333: ⚡ Quick winAdd ISO-string regression tests for
ОткрытьФайлandОткрытьПоток.These new tests cover
УстановитьСтроку, but this PR also changes initialization in file/stream entrypoints. Adding one focused case per path will lock the behavior across all three constructors.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/json/test-json_reader.os` around lines 265 - 333, The tests only exercise УстановитьСтроку but the PR changed initialization paths for file/stream entrypoints (ОткрытьФайл, ОткрытьПоток), so add parallel regression tests that mirror Тест_Должен_ОпределятьСтрокуСДатойВФорматеISOКакСтроку, Тест_Должен_ЧитатьСтрокуСДатойВФорматеISOКакСтроку and Тест_Должен_ЧитатьДатуВФорматеISOКакСтрокуПриИспользованииПрочитатьJSON but using ЧтениеJSON created via ОткрытьФайл(...) and ОткрытьПоток(...) (and their corresponding close semantics) to assert the same sequence of ТипТекущегоЗначения and that ТекущееЗначение/ПрочитатьJSON preserve ISO timestamps as strings.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tests/json/test-json_reader.os`:
- Around line 265-333: The tests only exercise УстановитьСтроку but the PR
changed initialization paths for file/stream entrypoints (ОткрытьФайл,
ОткрытьПоток), so add parallel regression tests that mirror
Тест_Должен_ОпределятьСтрокуСДатойВФорматеISOКакСтроку,
Тест_Должен_ЧитатьСтрокуСДатойВФорматеISOКакСтроку and
Тест_Должен_ЧитатьДатуВФорматеISOКакСтрокуПриИспользованииПрочитатьJSON but
using ЧтениеJSON created via ОткрытьФайл(...) and ОткрытьПоток(...) (and their
corresponding close semantics) to assert the same sequence of
ТипТекущегоЗначения and that ТекущееЗначение/ПрочитатьJSON preserve ISO
timestamps as strings.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: cbb85473-a4a9-40d4-bb39-90c64570a5c5
📒 Files selected for processing (2)
src/OneScript.StandardLibrary/Json/JSONReader.cstests/json/test-json_reader.os
… ОткрытьФайл() - по замечаниям coderabbit
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/json/test-json_reader.os`:
- Around line 359-375: В тестовой процедуре
Тест_Должен_ОткрытьФайлЧитаетСтрокуСДатойВФорматеISOКакСтроку() используется
переменная Чтение для создания экземпляра JSON-ридера, но далее вызываются
методы у неинициализированной переменной ЧтениеJSON; исправьте это, заменив все
вызовы ЧтениеJSON.Прочитать(), ЧтениеJSON.ТекущееЗначение,
ЧтениеJSON.ТипТекущегоЗначения и ЧтениеJSON.Закрыть() на эквивалентные вызовы
через Чтение (т.е. Чтение.Прочитать(), Чтение.ТекущееЗначение,
Чтение.ТипТекущегоЗначения, Чтение.Закрыть()) либо инициализируйте ЧтениеJSON =
Новый ЧтениеJSON перед использованием, если вы намеренно хотите использовать
переменную ЧтениеJSON.
- Around line 267-292: Тест
Тест_Должен_ОпределятьСтрокуСДатойВФорматеISOКакСтроку собирает ожидаемые и
фактические последовательности в ЭталонЗначения и ФактЗначения, но не проверяет
их длину, поэтому лишние токены пройдут незамеченными; добавьте в процедуру до
цикла сравнения явную проверку размера массивов (например через Колво() или
ВГраница+1) с использованием юТест.ПроверитьРавенство, чтобы убедиться, что
ФактЗначения и ЭталонЗначения имеют одинаковую длину перед посекторным
сравнением, затем оставить существующий цикл сравнения по индексам.
- Around line 333-357: The test currently opens a stream on the reader instance
named Чтение but then performs reads and assertions on a different reader
ЧтениеJSON, so ОткрытьПоток is never actually verified; fix by using the same
reader instance (Чтение) for
Прочитать/ТекущееЗначение/ТипТекущегоЗначения/Закрыть or remove the unused
ЧтениеJSON setup and instead call УстановитьСтроку only on Чтение if needed;
ensure the assertions reference Чтение and its ТипТекущегоЗначения so the
ОткрытьПоток call is actually exercised (look for symbols:
Тест_Должен_ОткрытьПотокЧитаетСтрокуСДатойВФорматеISOКакСтроку, Чтение,
ЧтениеJSON, ОткрытьПоток, УстановитьСтроку, Прочитать).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 04826260-11e9-47e7-9062-eacb1d66c62e
📒 Files selected for processing (2)
tests/json/json-mock_isodate.jsontests/json/test-json_reader.os
✅ Files skipped from review due to trivial changes (1)
- tests/json/json-mock_isodate.json
| Процедура Тест_Должен_ОпределятьСтрокуСДатойВФорматеISOКакСтроку() Экспорт | ||
|
|
||
| // проверяемая строка json | ||
| СтрокаJSON = "{ ""lastSignInTime"": ""2026-05-13T22:51:46Z"" }"; | ||
|
|
||
| // какие типы должны быть при последовательном чтении | ||
| ЭталонЗначения = Новый Массив; | ||
| ЭталонЗначения.Добавить( ТипЗначенияJSON.НачалоОбъекта ); | ||
| ЭталонЗначения.Добавить( ТипЗначенияJSON.ИмяСвойства ); | ||
| ЭталонЗначения.Добавить( ТипЗначенияJSON.Строка ); | ||
| ЭталонЗначения.Добавить( ТипЗначенияJSON.КонецОбъекта ); | ||
|
|
||
| // читаем последовательно строку json и собираем типы значений по порядку | ||
| ЧтениеJSON = Новый ЧтениеJSON; | ||
| ЧтениеJSON.УстановитьСтроку(СтрокаJSON); | ||
| ФактЗначения = Новый Массив; | ||
| Пока ЧтениеJSON.Прочитать() Цикл | ||
| ФактЗначения.Добавить( ЧтениеJSON.ТипТекущегоЗначения ); | ||
| КонецЦикла; | ||
| ЧтениеJSON.Закрыть(); | ||
|
|
||
| Для Сч = 0 По ЭталонЗначения.ВГраница() Цикл | ||
| юТест.ПроверитьРавенство(ЭталонЗначения[Сч], ФактЗначения[Сч]); | ||
| КонецЦикла; | ||
|
|
||
| КонецПроцедуры |
There was a problem hiding this comment.
Добавьте проверку длины последовательности токенов.
Сейчас на Line 288-290 сверяются только ожидаемые индексы; лишние токены в ФактЗначения не будут обнаружены. Небольшая проверка размера сделает тест строже.
Proposed fix
Для Сч = 0 По ЭталонЗначения.ВГраница() Цикл
юТест.ПроверитьРавенство(ЭталонЗначения[Сч], ФактЗначения[Сч]);
КонецЦикла;
+ юТест.ПроверитьРавенство(ЭталонЗначения.Количество(), ФактЗначения.Количество());🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/json/test-json_reader.os` around lines 267 - 292, Тест
Тест_Должен_ОпределятьСтрокуСДатойВФорматеISOКакСтроку собирает ожидаемые и
фактические последовательности в ЭталонЗначения и ФактЗначения, но не проверяет
их длину, поэтому лишние токены пройдут незамеченными; добавьте в процедуру до
цикла сравнения явную проверку размера массивов (например через Колво() или
ВГраница+1) с использованием юТест.ПроверитьРавенство, чтобы убедиться, что
ФактЗначения и ЭталонЗначения имеют одинаковую длину перед посекторным
сравнением, затем оставить существующий цикл сравнения по индексам.
| Процедура Тест_Должен_ОткрытьПотокЧитаетСтрокуСДатойВФорматеISOКакСтроку() Экспорт | ||
|
|
||
| // проверяемая строка json | ||
| СтрокаJSON = "{ ""lastSignInTime"": ""2026-05-13T22:51:46Z"" }"; | ||
|
|
||
| БДД = ПолучитьБуферДвоичныхДанныхИзСтроки(СтрокаJSON); | ||
| Поток = Новый ПотокВПамяти(БДД); | ||
| Чтение = Новый ЧтениеJSON; | ||
| Чтение.ОткрытьПоток(Поток); | ||
|
|
||
| ЧтениеJSON = Новый ЧтениеJSON; | ||
| ЧтениеJSON.УстановитьСтроку(СтрокаJSON); | ||
| ЧтениеJSON.Прочитать(); | ||
| ЧтениеJSON.Прочитать(); | ||
| ЧтениеJSON.Прочитать(); | ||
|
|
||
| ТекущееЗначение = ЧтениеJSON.ТекущееЗначение; | ||
| ТипТекущегоЗначения = ЧтениеJSON.ТипТекущегоЗначения; | ||
|
|
||
| ЧтениеJSON.Закрыть(); | ||
|
|
||
| юТест.ПроверитьРавенство(ТекущееЗначение, "2026-05-13T22:51:46Z"); | ||
| юТест.ПроверитьРавенство(ТипТекущегоЗначения, ТипЗначенияJSON.Строка); | ||
|
|
||
| КонецПроцедуры |
There was a problem hiding this comment.
Тест потока не проверяет ОткрытьПоток фактически.
На Line 341 поток открывается в Чтение, но далее на Line 343-352 проверка идет через другой reader (ЧтениеJSON) из строки. В итоге этот тест пройдет даже при поломке ОткрытьПоток.
Proposed fix
Процедура Тест_Должен_ОткрытьПотокЧитаетСтрокуСДатойВФорматеISOКакСтроку() Экспорт
@@
БДД = ПолучитьБуферДвоичныхДанныхИзСтроки(СтрокаJSON);
Поток = Новый ПотокВПамяти(БДД);
Чтение = Новый ЧтениеJSON;
Чтение.ОткрытьПоток(Поток);
-
- ЧтениеJSON = Новый ЧтениеJSON;
- ЧтениеJSON.УстановитьСтроку(СтрокаJSON);
- ЧтениеJSON.Прочитать();
- ЧтениеJSON.Прочитать();
- ЧтениеJSON.Прочитать();
+ Чтение.Прочитать();
+ Чтение.Прочитать();
+ Чтение.Прочитать();
- ТекущееЗначение = ЧтениеJSON.ТекущееЗначение;
- ТипТекущегоЗначения = ЧтениеJSON.ТипТекущегоЗначения;
+ ТекущееЗначение = Чтение.ТекущееЗначение;
+ ТипТекущегоЗначения = Чтение.ТипТекущегоЗначения;
- ЧтениеJSON.Закрыть();
+ Чтение.Закрыть();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Процедура Тест_Должен_ОткрытьПотокЧитаетСтрокуСДатойВФорматеISOКакСтроку() Экспорт | |
| // проверяемая строка json | |
| СтрокаJSON = "{ ""lastSignInTime"": ""2026-05-13T22:51:46Z"" }"; | |
| БДД = ПолучитьБуферДвоичныхДанныхИзСтроки(СтрокаJSON); | |
| Поток = Новый ПотокВПамяти(БДД); | |
| Чтение = Новый ЧтениеJSON; | |
| Чтение.ОткрытьПоток(Поток); | |
| ЧтениеJSON = Новый ЧтениеJSON; | |
| ЧтениеJSON.УстановитьСтроку(СтрокаJSON); | |
| ЧтениеJSON.Прочитать(); | |
| ЧтениеJSON.Прочитать(); | |
| ЧтениеJSON.Прочитать(); | |
| ТекущееЗначение = ЧтениеJSON.ТекущееЗначение; | |
| ТипТекущегоЗначения = ЧтениеJSON.ТипТекущегоЗначения; | |
| ЧтениеJSON.Закрыть(); | |
| юТест.ПроверитьРавенство(ТекущееЗначение, "2026-05-13T22:51:46Z"); | |
| юТест.ПроверитьРавенство(ТипТекущегоЗначения, ТипЗначенияJSON.Строка); | |
| КонецПроцедуры | |
| Процедура Тест_Должен_ОткрытьПотокЧитаетСтрокуСДатойВФорматеISOКакСтроку() Экспорт | |
| // проверяемая строка json | |
| СтрокаJSON = "{ ""lastSignInTime"": ""2026-05-13T22:51:46Z"" }"; | |
| БДД = ПолучитьБуферДвоичныхДанныхИзСтроки(СтрокаJSON); | |
| Поток = Новый ПотокВПамяти(БДД); | |
| Чтение = Новый ЧтениеJSON; | |
| Чтение.ОткрытьПоток(Поток); | |
| Чтение.Прочитать(); | |
| Чтение.Прочитать(); | |
| Чтение.Прочитать(); | |
| ТекущееЗначение = Чтение.ТекущееЗначение; | |
| ТипТекущегоЗначения = Чтение.ТипТекущегоЗначения; | |
| Чтение.Закрыть(); | |
| юТест.ПроверитьРавенство(ТекущееЗначение, "2026-05-13T22:51:46Z"); | |
| юТест.ПроверитьРавенство(ТипТекущегоЗначения, ТипЗначенияJSON.Строка); | |
| КонецПроцедуры |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/json/test-json_reader.os` around lines 333 - 357, The test currently
opens a stream on the reader instance named Чтение but then performs reads and
assertions on a different reader ЧтениеJSON, so ОткрытьПоток is never actually
verified; fix by using the same reader instance (Чтение) for
Прочитать/ТекущееЗначение/ТипТекущегоЗначения/Закрыть or remove the unused
ЧтениеJSON setup and instead call УстановитьСтроку only on Чтение if needed;
ensure the assertions reference Чтение and its ТипТекущегоЗначения so the
ОткрытьПоток call is actually exercised (look for symbols:
Тест_Должен_ОткрытьПотокЧитаетСтрокуСДатойВФорматеISOКакСтроку, Чтение,
ЧтениеJSON, ОткрытьПоток, УстановитьСтроку, Прочитать).
| Процедура Тест_Должен_ОткрытьФайлЧитаетСтрокуСДатойВФорматеISOКакСтроку() Экспорт | ||
|
|
||
| Чтение = Новый ЧтениеJSON; | ||
| Чтение.ОткрытьФайл("json/json-mock_isodate.json"); | ||
| ЧтениеJSON.Прочитать(); | ||
| ЧтениеJSON.Прочитать(); | ||
| ЧтениеJSON.Прочитать(); | ||
|
|
||
| ТекущееЗначение = ЧтениеJSON.ТекущееЗначение; | ||
| ТипТекущегоЗначения = ЧтениеJSON.ТипТекущегоЗначения; | ||
|
|
||
| ЧтениеJSON.Закрыть(); | ||
|
|
||
| юТест.ПроверитьРавенство(ТекущееЗначение, "2026-05-13T22:51:46Z"); | ||
| юТест.ПроверитьРавенство(ТипТекущегоЗначения, ТипЗначенияJSON.Строка); | ||
|
|
||
| КонецПроцедуры |
There was a problem hiding this comment.
Используется неверная переменная reader, тест падает/невалиден.
На Line 361-362 файл открывается через Чтение, но на Line 363-370 вызывается ЧтениеJSON, который в этой процедуре не инициализирован. Это прямой дефект теста.
Proposed fix
Процедура Тест_Должен_ОткрытьФайлЧитаетСтрокуСДатойВФорматеISOКакСтроку() Экспорт
@@
Чтение = Новый ЧтениеJSON;
Чтение.ОткрытьФайл("json/json-mock_isodate.json");
- ЧтениеJSON.Прочитать();
- ЧтениеJSON.Прочитать();
- ЧтениеJSON.Прочитать();
+ Чтение.Прочитать();
+ Чтение.Прочитать();
+ Чтение.Прочитать();
- ТекущееЗначение = ЧтениеJSON.ТекущееЗначение;
- ТипТекущегоЗначения = ЧтениеJSON.ТипТекущегоЗначения;
+ ТекущееЗначение = Чтение.ТекущееЗначение;
+ ТипТекущегоЗначения = Чтение.ТипТекущегоЗначения;
- ЧтениеJSON.Закрыть();
+ Чтение.Закрыть();📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Процедура Тест_Должен_ОткрытьФайлЧитаетСтрокуСДатойВФорматеISOКакСтроку() Экспорт | |
| Чтение = Новый ЧтениеJSON; | |
| Чтение.ОткрытьФайл("json/json-mock_isodate.json"); | |
| ЧтениеJSON.Прочитать(); | |
| ЧтениеJSON.Прочитать(); | |
| ЧтениеJSON.Прочитать(); | |
| ТекущееЗначение = ЧтениеJSON.ТекущееЗначение; | |
| ТипТекущегоЗначения = ЧтениеJSON.ТипТекущегоЗначения; | |
| ЧтениеJSON.Закрыть(); | |
| юТест.ПроверитьРавенство(ТекущееЗначение, "2026-05-13T22:51:46Z"); | |
| юТест.ПроверитьРавенство(ТипТекущегоЗначения, ТипЗначенияJSON.Строка); | |
| КонецПроцедуры | |
| Процедура Тест_Должен_ОткрытьФайлЧитаетСтрокуСДатойВФорматеISOКакСтроку() Экспорт | |
| Чтение = Новый ЧтениеJSON; | |
| Чтение.ОткрытьФайл("json/json-mock_isodate.json"); | |
| Чтение.Прочитать(); | |
| Чтение.Прочитать(); | |
| Чтение.Прочитать(); | |
| ТекущееЗначение = Чтение.ТекущееЗначение; | |
| ТипТекущегоЗначения = Чтение.ТипТекущегоЗначения; | |
| Чтение.Закрыть(); | |
| юТест.ПроверитьРавенство(ТекущееЗначение, "2026-05-13T22:51:46Z"); | |
| юТест.ПроверитьРавенство(ТипТекущегоЗначения, ТипЗначенияJSON.Строка); | |
| КонецПроцедуры |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/json/test-json_reader.os` around lines 359 - 375, В тестовой процедуре
Тест_Должен_ОткрытьФайлЧитаетСтрокуСДатойВФорматеISOКакСтроку() используется
переменная Чтение для создания экземпляра JSON-ридера, но далее вызываются
методы у неинициализированной переменной ЧтениеJSON; исправьте это, заменив все
вызовы ЧтениеJSON.Прочитать(), ЧтениеJSON.ТекущееЗначение,
ЧтениеJSON.ТипТекущегоЗначения и ЧтениеJSON.Закрыть() на эквивалентные вызовы
через Чтение (т.е. Чтение.Прочитать(), Чтение.ТекущееЗначение,
Чтение.ТипТекущегоЗначения, Чтение.Закрыть()) либо инициализируйте ЧтениеJSON =
Новый ЧтениеJSON перед использованием, если вы намеренно хотите использовать
переменную ЧтениеJSON.
| SupportMultipleContent = true | ||
| ,DateParseHandling = DateParseHandling.None |
There was a problem hiding this comment.
Обе эти инициализации во всех трех местах стоит перенести в конструктор JsonReaderInternal
Внутренняя реализация чтения json использовала популярную библиотеку работы с json от newtonsoft.
Эта библиотека по-умолчанию преобразует в тип Дата строки, содержащие дату в формате ISO - "2026-05-13T22:51:46.230Z". Из-за этого поведение объекта ЧтениеJSON и функии ПрочитатьJSON() отличалось от платформы 1С:
Возврат поведения к идиоматическому платформенному позволит обрабатывать json свободно, писать свои алгоритмы преобразования дат при использовании последовательного чтения с помощью ЧтениеJSON и пр. Сейчас это невозможно, точное значение даты может теряться при автоматической конвертации рантаймом.
Важно! Это может быть breaking change если какой-то код заложился на этот баг - когда строка с датой автоматически преобразуется в тип Дата функцией ПрочитатьJSON(). Но имхо "типовое" поведение важнее иметь
Summary by CodeRabbit
Bug Fixes
Tests