From f87d862555378bd7649fc570b5dcfd95403787a7 Mon Sep 17 00:00:00 2001 From: Austin Drenski Date: Tue, 15 May 2018 13:37:04 -0400 Subject: [PATCH] Incorporating feedback from range-operators PR (#323). --- .../NpgsqlNetworkAddressTranslator.cs | 50 +----- .../Query/NetworkAddressQueryNpgsqlFixture.cs | 135 -------------- .../Query/NetworkAddressQueryNpgsqlTest.cs | 170 ++++++++++++++++-- 3 files changed, 158 insertions(+), 197 deletions(-) delete mode 100644 test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlFixture.cs diff --git a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkAddressTranslator.cs b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkAddressTranslator.cs index fe556563c2..9fea7fbbb4 100644 --- a/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkAddressTranslator.cs +++ b/src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlNetworkAddressTranslator.cs @@ -23,7 +23,6 @@ #endregion -using System; using System.Linq.Expressions; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Query.ExpressionTranslators; @@ -41,63 +40,20 @@ public class NpgsqlNetworkAddressTranslator : IMethodCallTranslator { /// [CanBeNull] - public Expression Translate(MethodCallExpression methodCallExpression) => - TryTranslateOperator(methodCallExpression); - - /// - /// Attempts to translate the as a PostgreSQL network address operator. - /// - /// The to be translated. - /// - /// The expression if successful; otherwise, null. - /// - [CanBeNull] - static Expression TryTranslateOperator([NotNull] MethodCallExpression expression) + public Expression Translate(MethodCallExpression expression) { switch (expression.Method.Name) { case nameof(NpgsqlNetworkAddressExtensions.Contains): - return MakeBinaryExpression(expression, ">>", typeof(bool)); + return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], ">>", typeof(bool)); case nameof(NpgsqlNetworkAddressExtensions.ContainsOrEquals): - return MakeBinaryExpression(expression, ">>=", typeof(bool)); - -// case nameof(NpgsqlNetworkAddressExtensions.Overlaps): -// return MakeBinaryExpression(expression, "&&", typeof(bool)); -// -// case nameof(NpgsqlNetworkAddressExtensions.IsStrictlyLeftOf): -// return MakeBinaryExpression(expression, "<<", typeof(bool)); -// -// case nameof(NpgsqlNetworkAddressExtensions.IsStrictlyRightOf): -// return MakeBinaryExpression(expression, ">>", typeof(bool)); -// -// case nameof(NpgsqlNetworkAddressExtensions.DoesNotExtendRightOf): -// return MakeBinaryExpression(expression, "&<", typeof(bool)); -// -// case nameof(NpgsqlNetworkAddressExtensions.DoesNotExtendLeftOf): -// return MakeBinaryExpression(expression, "&>", typeof(bool)); -// -// case nameof(NpgsqlNetworkAddressExtensions.IsAdjacentTo): -// return MakeBinaryExpression(expression, "-|-", typeof(bool)); + return new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], ">>=", typeof(bool)); default: return null; } } - - /// - /// Constructs a . - /// - /// The containing two parameters. - /// The symbolic operator for PostgreSQL. - /// The return type of the operator. - /// - /// A . - /// - [NotNull] - static Expression MakeBinaryExpression([NotNull] MethodCallExpression expression, [NotNull] string symbol, [NotNull] Type returnType) => - new CustomBinaryExpression(expression.Arguments[0], expression.Arguments[1], symbol, returnType); - // [NpgsqlBinaryOperator(Symbol = "<", ReturnType = typeof(bool))] LessThan, // [NpgsqlBinaryOperator(Symbol = "<=", ReturnType = typeof(bool))] LessThanOrEqual, // [NpgsqlBinaryOperator(Symbol = "=", ReturnType = typeof(bool))] Equal, diff --git a/test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlFixture.cs b/test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlFixture.cs deleted file mode 100644 index b046d2aa0d..0000000000 --- a/test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlFixture.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Net; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.TestUtilities; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Npgsql.EntityFrameworkCore.PostgreSQL.TestUtilities; -using NpgsqlTypes; - -namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query -{ - /// - /// Represents a fixture suitable for testing network address operators. - /// - public class NetworkAddressQueryNpgsqlFixture : IDisposable - { - /// - /// The used for testing. - /// - private readonly NpgsqlTestStore _testStore; - - /// - /// The used for testing. - /// - private readonly DbContextOptions _options; - - /// - /// The logger factory used for testing. - /// - public TestSqlLoggerFactory TestSqlLoggerFactory { get; } - - /// - /// Initializes a . - /// - // ReSharper disable once UnusedMember.Global - public NetworkAddressQueryNpgsqlFixture() - { - TestSqlLoggerFactory = new TestSqlLoggerFactory(); - - _testStore = NpgsqlTestStore.CreateScratch(); - - _options = - new DbContextOptionsBuilder() - .UseNpgsql(_testStore.ConnectionString, b => b.ApplyConfiguration()) - .UseInternalServiceProvider( - new ServiceCollection() - .AddEntityFrameworkNpgsql() - .AddSingleton(TestSqlLoggerFactory) - .BuildServiceProvider()) - .Options; - - using (NetContext context = CreateContext()) - { - context.Database.EnsureCreated(); - - context.NetTestEntities - .AddRange( - new NetTestEntity { Id = 1, InetMappedToIPAddress = new IPAddress(1), CidrMappedToNpgsqlInet = new IPAddress(1) }, - new NetTestEntity { Id = 2, InetMappedToIPAddress = new IPAddress(2), CidrMappedToNpgsqlInet = new IPAddress(2) }, - new NetTestEntity { Id = 3, InetMappedToIPAddress = new IPAddress(3), CidrMappedToNpgsqlInet = new IPAddress(3) }, - new NetTestEntity { Id = 4, InetMappedToIPAddress = new IPAddress(4), CidrMappedToNpgsqlInet = new IPAddress(4) }, - new NetTestEntity { Id = 5, InetMappedToIPAddress = new IPAddress(5), CidrMappedToNpgsqlInet = new IPAddress(5) }, - new NetTestEntity { Id = 6, InetMappedToIPAddress = new IPAddress(6), CidrMappedToNpgsqlInet = new IPAddress(6) }, - new NetTestEntity { Id = 7, InetMappedToIPAddress = new IPAddress(7), CidrMappedToNpgsqlInet = new IPAddress(7) }, - new NetTestEntity { Id = 8, InetMappedToIPAddress = new IPAddress(8), CidrMappedToNpgsqlInet = new IPAddress(8) }, - new NetTestEntity { Id = 9, InetMappedToIPAddress = new IPAddress(9), CidrMappedToNpgsqlInet = new IPAddress(9) }, - new NetTestEntity { Id = 10, InetMappedToIPAddress = new IPAddress(10), CidrMappedToNpgsqlInet = new IPAddress(10) }); - - context.SaveChanges(); - } - } - - /// - /// Creates a new . - /// - /// - /// A for testing. - /// - public NetContext CreateContext() - { - return new NetContext(_options); - } - - /// - public void Dispose() - { - _testStore.Dispose(); - } - } - - /// - /// Represents an entity suitable for testing network address operators. - /// - public class NetTestEntity - { - /// - /// The primary key. - /// - [Key] - public int Id { get; set; } - - /// - /// The network address. - /// - [Column(TypeName = "inet")] - public IPAddress InetMappedToIPAddress { get; set; } - - /// - /// The network address. - /// - [Column(TypeName = "cidr")] - public NpgsqlInet CidrMappedToNpgsqlInet { get; set; } - } - - /// - /// Represents a database suitable for testing network address operators. - /// - public class NetContext : DbContext - { - /// - /// Represents a set of entities with properties. - /// - public DbSet NetTestEntities { get; set; } - - /// - /// Initializes a . - /// - /// - /// The options to be used for configuration. - /// - public NetContext(DbContextOptions options) : base(options) { } - } -} diff --git a/test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlTest.cs b/test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlTest.cs index d9557be76f..9dd6e6186d 100644 --- a/test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlTest.cs +++ b/test/EFCore.PG.FunctionalTests/Query/NetworkAddressQueryNpgsqlTest.cs @@ -1,5 +1,13 @@ -using System.Linq; +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; using System.Net; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Npgsql.EntityFrameworkCore.PostgreSQL.TestUtilities; using NpgsqlTypes; using Xunit; @@ -8,7 +16,7 @@ namespace Npgsql.EntityFrameworkCore.PostgreSQL.Query /// /// Provides unit tests for network address operator translations. /// - public class NetworkAddressQueryNpgsqlTest : IClassFixture + public class NetworkAddressQueryNpgsqlTest : IClassFixture { /// /// Provides resources for unit tests. @@ -18,23 +26,14 @@ public class NetworkAddressQueryNpgsqlTest : IClassFixture /// Initializes resources for unit tests. /// - /// - /// The fixture of resources for testing. - /// + /// The fixture of resources for testing. public NetworkAddressQueryNpgsqlTest(NetworkAddressQueryNpgsqlFixture fixture) { Fixture = fixture; Fixture.TestSqlLoggerFactory.Clear(); } - /// - /// Asserts that the SQL fragment appears in the logs. - /// - /// The SQL statement or fragment to search for in the logs. - public void AssertContainsSql(string sql) - { - Assert.Contains(sql, Fixture.TestSqlLoggerFactory.Sql); - } + #region Tests /// /// Tests translation for . @@ -97,7 +96,7 @@ public void IPAddressDoesNotContainsIPAddress() /// Tests inverse translation for . /// [Fact] - public void NpgsqlInetDoesNotContainsNpgsqlInet() + public void NpgsqlInetDoesNotContainNpgsqlInet() { using (NetContext context = Fixture.CreateContext()) { @@ -116,7 +115,7 @@ public void NpgsqlInetDoesNotContainsNpgsqlInet() /// Tests translation for . /// [Fact] - public void IPAddressContainsOrEqualsIPAddress() + public void IPAddressContainOrEqualIPAddress() { using (NetContext context = Fixture.CreateContext()) { @@ -187,5 +186,146 @@ public void NpgsqlInetDoesNotContainOrEqualNpgsqlInet() AssertContainsSql("WHERE NOT (x.\"CidrMappedToNpgsqlInet\" >>= @__npgsqlInet_0 = TRUE)"); } } + + #endregion + + #region Fixtures + + /// + /// Represents a fixture suitable for testing network address operators. + /// + public class NetworkAddressQueryNpgsqlFixture : IDisposable + { + /// + /// The used for testing. + /// + private readonly NpgsqlTestStore _testStore; + + /// + /// The used for testing. + /// + private readonly DbContextOptions _options; + + /// + /// The logger factory used for testing. + /// + public TestSqlLoggerFactory TestSqlLoggerFactory { get; } + + /// + /// Initializes a . + /// + // ReSharper disable once UnusedMember.Global + public NetworkAddressQueryNpgsqlFixture() + { + TestSqlLoggerFactory = new TestSqlLoggerFactory(); + + _testStore = NpgsqlTestStore.CreateScratch(); + + _options = + new DbContextOptionsBuilder() + .UseNpgsql(_testStore.ConnectionString, b => b.ApplyConfiguration()) + .UseInternalServiceProvider( + new ServiceCollection() + .AddEntityFrameworkNpgsql() + .AddSingleton(TestSqlLoggerFactory) + .BuildServiceProvider()) + .Options; + + using (NetContext context = CreateContext()) + { + context.Database.EnsureCreated(); + + context.NetTestEntities + .AddRange( + new NetTestEntity { Id = 1, InetMappedToIPAddress = new IPAddress(1), CidrMappedToNpgsqlInet = new IPAddress(1) }, + new NetTestEntity { Id = 2, InetMappedToIPAddress = new IPAddress(2), CidrMappedToNpgsqlInet = new IPAddress(2) }, + new NetTestEntity { Id = 3, InetMappedToIPAddress = new IPAddress(3), CidrMappedToNpgsqlInet = new IPAddress(3) }, + new NetTestEntity { Id = 4, InetMappedToIPAddress = new IPAddress(4), CidrMappedToNpgsqlInet = new IPAddress(4) }, + new NetTestEntity { Id = 5, InetMappedToIPAddress = new IPAddress(5), CidrMappedToNpgsqlInet = new IPAddress(5) }, + new NetTestEntity { Id = 6, InetMappedToIPAddress = new IPAddress(6), CidrMappedToNpgsqlInet = new IPAddress(6) }, + new NetTestEntity { Id = 7, InetMappedToIPAddress = new IPAddress(7), CidrMappedToNpgsqlInet = new IPAddress(7) }, + new NetTestEntity { Id = 8, InetMappedToIPAddress = new IPAddress(8), CidrMappedToNpgsqlInet = new IPAddress(8) }, + new NetTestEntity { Id = 9, InetMappedToIPAddress = new IPAddress(9), CidrMappedToNpgsqlInet = new IPAddress(9) }, + new NetTestEntity { Id = 10, InetMappedToIPAddress = new IPAddress(10), CidrMappedToNpgsqlInet = new IPAddress(10) }); + + context.SaveChanges(); + } + } + + /// + /// Creates a new . + /// + /// + /// A for testing. + /// + public NetContext CreateContext() + { + return new NetContext(_options); + } + + /// + public void Dispose() + { + _testStore.Dispose(); + } + } + + /// + /// Represents an entity suitable for testing network address operators. + /// + public class NetTestEntity + { + /// + /// The primary key. + /// + [Key] + public int Id { get; set; } + + /// + /// The network address. + /// + [Column(TypeName = "inet")] + public IPAddress InetMappedToIPAddress { get; set; } + + /// + /// The network address. + /// + [Column(TypeName = "cidr")] + public NpgsqlInet CidrMappedToNpgsqlInet { get; set; } + } + + /// + /// Represents a database suitable for testing network address operators. + /// + public class NetContext : DbContext + { + /// + /// Represents a set of entities with properties. + /// + public DbSet NetTestEntities { get; set; } + + /// + /// Initializes a . + /// + /// + /// The options to be used for configuration. + /// + public NetContext(DbContextOptions options) : base(options) { } + } + + #endregion + + #region Helpers + + /// + /// Asserts that the SQL fragment appears in the logs. + /// + /// The SQL statement or fragment to search for in the logs. + public void AssertContainsSql(string sql) + { + Assert.Contains(sql, Fixture.TestSqlLoggerFactory.Sql); + } + + #endregion } }