/
dev-npgsql
/
npgsql
Обзор
Документация
Войти
/
dev-npgsql
/
npgsql
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
test-logs
test/Npgsql.Tests/Types/JsonTests.cs
250 строк
9 KB
Copilot
Fix JsonNode[] missing from basic JSON types (#6549)
21 апр 2026, 18:52
Не верифицирован
21 апр 2026, 18:52
2d91c29
Код
Авторство
О чём код?
using System; using System.Data; using System.IO; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; using System.Threading.Tasks; using NUnit.Framework; namespace Npgsql.Tests.Types; [TestFixture("json")] [TestFixture("jsonb")] public class JsonTests : TestBase { [Test] public async Task As_string() => await AssertType("""{"K": "V"}""", """{"K": "V"}""", PostgresType, dataTypeInference: DataTypeInference.Mismatch, dbType: new(DbType.Object, DbType.String)); [Test] public async Task As_string_long() { await using var conn = CreateConnection(); var value = new StringBuilder() .Append(@"{""K"": """) .Append('x', conn.Settings.WriteBufferSize) .Append(@"""}") .ToString(); await AssertType(value, value, PostgresType, dataTypeInference: DataTypeInference.Mismatch, dbType: new(DbType.Object, DbType.String)); } [Test] public async Task As_string_with_GetTextReader() { await using var conn = await OpenConnectionAsync(); await using var cmd = new NpgsqlCommand($$"""SELECT '{"K": "V"}'::{{PostgresType}}""", conn); await using var reader = await cmd.ExecuteReaderAsync(); reader.Read(); using var textReader = await reader.GetTextReaderAsync(0); Assert.That(await textReader.ReadToEndAsync(), Is.EqualTo(@"{""K"": ""V""}")); } [Test] public async Task As_char_array() => await AssertType("""{"K": "V"}""".ToCharArray(), """{"K": "V"}""", PostgresType, dataTypeInference: DataTypeInference.Mismatch, dbType: new(DbType.Object, DbType.String), valueTypeEqualsFieldType: false); [Test] public async Task As_bytes() => await AssertType("""{"K": "V"}"""u8.ToArray(), """{"K": "V"}""", PostgresType, dataTypeInference: DataTypeInference.Mismatch, dbType: new(DbType.Object, DbType.Binary), valueTypeEqualsFieldType: false); [Test] public async Task Write_as_ReadOnlyMemory_of_byte() => await AssertTypeWrite(new ReadOnlyMemory<byte>("""{"K": "V"}"""u8.ToArray()), """{"K": "V"}""", PostgresType, dataTypeInference: DataTypeInference.Mismatch, dbType: new(DbType.Object, DbType.Binary)); [Test] public async Task Write_as_ArraySegment_of_char() => await AssertTypeWrite(new ArraySegment<char>("""{"K": "V"}""".ToCharArray()), """{"K": "V"}""", PostgresType, dataTypeInference: DataTypeInference.Mismatch, dbType: new(DbType.Object, DbType.String)); [Test] public Task As_MemoryStream() => AssertTypeWrite(() => new MemoryStream("""{"K": "V"}"""u8.ToArray()), """{"K": "V"}""", PostgresType, dataTypeInference: DataTypeInference.Mismatch, dbType: new(DbType.Object, DbType.Binary)); [Test] public async Task As_JsonDocument() => await AssertType( JsonDocument.Parse("""{"K": "V"}"""), IsJsonb ? """{"K": "V"}""" : """{"K":"V"}""", PostgresType, dataTypeInference: DataTypeInference.Mismatch, comparer: (x, y) => x.RootElement.GetProperty("K").GetString() == y.RootElement.GetProperty("K").GetString(), valueTypeEqualsFieldType: false); [Test, IssueLink("https://github.com/npgsql/npgsql/issues/5540")] public async Task As_JsonDocument_with_null_root() => await AssertType( JsonDocument.Parse("null"), "null", PostgresType, dataTypeInference: DataTypeInference.Mismatch, comparer: (x, y) => x.RootElement.ValueKind == y.RootElement.ValueKind, valueTypeEqualsFieldType: false, skipArrayCheck: true); [Test] public async Task As_JsonElement_with_null_root() => await AssertType( JsonDocument.Parse("null").RootElement, "null", PostgresType, dataTypeInference: DataTypeInference.Mismatch, comparer: (x, y) => x.ValueKind == y.ValueKind, valueTypeEqualsFieldType: false, skipArrayCheck: true); [Test] public async Task As_JsonDocument_supported_only_with_SystemTextJson() { await using var slimDataSource = new NpgsqlSlimDataSourceBuilder(ConnectionString).Build(); await AssertTypeUnsupported( JsonDocument.Parse("""{"K": "V"}"""), """{"K": "V"}""", PostgresType, slimDataSource); } [Test] public Task Roundtrip_string() => AssertType( @"{""p"": 1}", @"{""p"": 1}", PostgresType, dataTypeInference: DataTypeInference.Mismatch, dbType: new(DbType.Object, DbType.String), valueTypeEqualsFieldType: true); [Test] public Task Roundtrip_char_array() => AssertType( @"{""p"": 1}".ToCharArray(), @"{""p"": 1}", PostgresType, dataTypeInference: DataTypeInference.Mismatch, dbType: new(DbType.Object, DbType.String), valueTypeEqualsFieldType: false); [Test] public Task Roundtrip_byte_array() => AssertType( @"{""p"": 1}"u8.ToArray(), @"{""p"": 1}", PostgresType, dataTypeInference: DataTypeInference.Mismatch, dbType: new(DbType.Object, DbType.Binary), valueTypeEqualsFieldType: false); [Test] [IssueLink("https://github.com/npgsql/npgsql/issues/2811")] [IssueLink("https://github.com/npgsql/efcore.pg/issues/1177")] [IssueLink("https://github.com/npgsql/efcore.pg/issues/1082")] public async Task Can_read_two_json_documents() { await using var conn = await OpenConnectionAsync(); JsonDocument car; await using (var cmd = new NpgsqlCommand("""SELECT '{"key" : "foo"}'::jsonb""", conn)) await using (var reader = await cmd.ExecuteReaderAsync()) { reader.Read(); car = reader.GetFieldValue<JsonDocument>(0); } await using (var cmd = new NpgsqlCommand("""SELECT '{"key" : "bar"}'::jsonb""", conn)) await using (var reader = await cmd.ExecuteReaderAsync()) { reader.Read(); reader.GetFieldValue<JsonDocument>(0); } Assert.That(car.RootElement.GetProperty("key").GetString(), Is.EqualTo("foo")); } [Test] public Task Roundtrip_JsonObject() => AssertType( new JsonObject { ["Bar"] = 8 }, IsJsonb ? """{"Bar": 8}""" : """{"Bar":8}""", PostgresType, // By default we map JsonObject to jsonb dataTypeInference: IsJsonb ? DataTypeInference.Match : DataTypeInference.Mismatch, valueTypeEqualsFieldType: false, comparer: (x, y) => x.ToString() == y.ToString()); [Test] public Task Roundtrip_JsonArray() => AssertType( new JsonArray { 1, 2, 3 }, IsJsonb ? "[1, 2, 3]" : "[1,2,3]", PostgresType, // By default we map JsonArray to jsonb dataTypeInference: IsJsonb ? DataTypeInference.Match : DataTypeInference.Mismatch, valueTypeEqualsFieldType: false, comparer: (x, y) => x.ToString() == y.ToString()); [Test] [IssueLink("https://github.com/npgsql/npgsql/issues/4537")] public async Task Write_jsonobject_array_without_npgsqldbtype() { // By default we map JsonObject to jsonb if (!IsJsonb) return; await using var conn = await OpenConnectionAsync(); var tableName = await TestUtil.CreateTempTable(conn, "key SERIAL PRIMARY KEY, ingredients json[]"); await using var cmd = new NpgsqlCommand { Connection = conn }; var jsonObject1 = new JsonObject { { "name", "value1" }, { "amount", 1 }, { "unit", "ml" } }; var jsonObject2 = new JsonObject { { "name", "value2" }, { "amount", 2 }, { "unit", "g" } }; cmd.CommandText = $"INSERT INTO {tableName} (ingredients) VALUES (@p)"; cmd.Parameters.Add(new("p", new[] { jsonObject1, jsonObject2 })); await cmd.ExecuteNonQueryAsync(); } [Test] [IssueLink("https://github.com/npgsql/npgsql/issues/6517")] public Task Roundtrip_JsonNode() => AssertType( (JsonNode)new JsonObject { ["Bar"] = 8 }, IsJsonb ? """{"Bar": 8}""" : """{"Bar":8}""", PostgresType, // By default we map JsonNode to jsonb dataTypeInference: IsJsonb ? DataTypeInference.Match : DataTypeInference.Mismatch, valueTypeEqualsFieldType: false, comparer: (x, y) => x.ToString() == y.ToString()); public JsonTests(string dataTypeName) { if (dataTypeName == "jsonb") using (var conn = OpenConnection()) TestUtil.MinimumPgVersion(conn, "9.4.0", "JSONB data type not yet introduced"); PostgresType = dataTypeName; } bool IsJsonb => PostgresType == "jsonb"; string PostgresType { get; } }