Skip to content

Commit

Permalink
Adding some regression tests for issues fixed earlier
Browse files Browse the repository at this point in the history
Resolves #19927
Resolves #22701
  • Loading branch information
maumar committed Aug 26, 2021
1 parent e5b696d commit 2334c34
Show file tree
Hide file tree
Showing 7 changed files with 274 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.InMemory.Internal;
using Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel;
Expand Down Expand Up @@ -70,5 +68,11 @@ public override async Task Projecting_some_properties_as_well_as_correlated_coll

Assert.Equal(InMemoryStrings.DistinctOnSubqueryNotSupported, message);
}

[ConditionalTheory(Skip = "Issue #25735")]
public override Task Project_navigation_defined_on_derived_from_entity_with_inheritance_using_soft_cast(bool async)
{
return base.Project_navigation_defined_on_derived_from_entity_with_inheritance_using_soft_cast(async);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel;
using Microsoft.EntityFrameworkCore.TestUtilities;
Expand Down Expand Up @@ -293,6 +290,22 @@ public IReadOnlyDictionary<Type, object> GetEntityAsserters()
Assert.Equal(ee.SynergyWithId, aa.SynergyWithId);
}
}
},
{
typeof(LocustHighCommand), (e, a) =>
{
Assert.Equal(e == null, a == null);
if (a != null)
{
var ee = (LocustHighCommand)e;
var aa = (LocustHighCommand)a;
Assert.Equal(ee.Id, aa.Id);
Assert.Equal(ee.IsOperational, aa.IsOperational);
Assert.Equal(ee.Name, aa.Name);
}
}
}
}.ToDictionary(e => e.Key, e => (object)e.Value);

Expand Down
144 changes: 140 additions & 4 deletions test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Diagnostics.Internal;
using Microsoft.EntityFrameworkCore.Infrastructure;
Expand Down Expand Up @@ -8978,6 +8974,146 @@ public virtual Task Contains_on_readonly_enumerable(bool async)
ss => ss.Set<Weapon>().Where(w => _weaponTypes.Contains(w.AmmunitionType)));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Project_navigation_defined_on_base_from_entity_with_inheritance_using_soft_cast(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Gear>().Select(g => new
{
Gear = g,
Tag = (g as Officer).Tag,
IsNull = (g as Officer).Tag == null,
Property = (g as Officer).Nickname,
PropertyAfterNavigation = (g as Officer).Tag.Id,
NestedOuter = new
{
CityOfBirth = (g as Officer).CityOfBirth,
IsNull = (g as Officer).CityOfBirth == null,
Property = (g as Officer).Nickname,
PropertyAfterNavigation = (g as Officer).CityOfBirth.Name,
NestedInner = new
{
Squad = (g as Officer).Squad,
IsNull = (g as Officer).Squad == null,
Property = (g as Officer).Nickname,
PropertyAfterNavigation = (g as Officer).Squad.Id
}
}
}),
ss => ss.Set<Gear>().Select(g => new
{
Gear = g,
Tag = g.Tag,
IsNull = g.Tag == null,
Property = g.Nickname,
PropertyAfterNavigation = g.Tag.Id,
NestedOuter = new
{
CityOfBirth = g.CityOfBirth,
IsNull = g.CityOfBirth == null,
Property = g.Nickname,
PropertyAfterNavigation = g.CityOfBirth.Name,
NestedInner = new
{
Squad = g.Squad,
IsNull = g.Squad == null,
Property = g.Nickname,
PropertyAfterNavigation = g.Squad.Id
}
}
}),
elementSorter: e => e.Gear.Nickname,
elementAsserter: (e, a) =>
{
AssertEqual(e.Gear, a.Gear);
AssertEqual(e.Tag, a.Tag);
AssertEqual(e.IsNull, a.IsNull);
AssertEqual(e.Property, a.Property);
AssertEqual(e.PropertyAfterNavigation, a.PropertyAfterNavigation);

AssertEqual(e.NestedOuter.CityOfBirth, a.NestedOuter.CityOfBirth);
AssertEqual(e.NestedOuter.IsNull, a.NestedOuter.IsNull);
AssertEqual(e.NestedOuter.Property, a.NestedOuter.Property);
AssertEqual(e.NestedOuter.PropertyAfterNavigation, a.NestedOuter.PropertyAfterNavigation);

AssertEqual(e.NestedOuter.NestedInner.Squad, a.NestedOuter.NestedInner.Squad);
AssertEqual(e.NestedOuter.NestedInner.IsNull, a.NestedOuter.NestedInner.IsNull);
AssertEqual(e.NestedOuter.NestedInner.Property, a.NestedOuter.NestedInner.Property);
AssertEqual(e.NestedOuter.NestedInner.PropertyAfterNavigation, a.NestedOuter.NestedInner.PropertyAfterNavigation);
});
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Project_navigation_defined_on_derived_from_entity_with_inheritance_using_soft_cast(bool async)
{
return AssertQuery(
async,
ss => ss.Set<LocustLeader>().Select(l => new
{
Leader = l,
DefeatedBy = (l as LocustCommander).DefeatedBy,
IsNull = (l as LocustCommander).DefeatedBy == null,
Property = (l as LocustCommander).DefeatedByNickname,
PropertyAfterNavigation = (bool?)(l as LocustCommander).DefeatedBy.HasSoulPatch,
NestedOuter = new
{
CommandingFaction = (l as LocustCommander).CommandingFaction,
IsNull = (l as LocustCommander).CommandingFaction == null,
Property = (int?)(l as LocustCommander).HighCommandId,
PropertyAfterNavigation = (l as LocustCommander).CommandingFaction.Eradicated,
NestedInner = new
{
HighCommand = (l as LocustCommander).HighCommand,
IsNull = (l as LocustCommander).HighCommand == null,
Property = (l as LocustCommander).DefeatedBySquadId,
PropertyAfterNavigation = (l as LocustCommander).HighCommand.Name
}
}
}),
ss => ss.Set<LocustLeader>().Select(l => new
{
Leader = l,
DefeatedBy = (l as LocustCommander).DefeatedBy,
IsNull = (l as LocustCommander).DefeatedBy == null,
Property = (l as LocustCommander).DefeatedByNickname,
PropertyAfterNavigation = (bool?)(l as LocustCommander).DefeatedBy.HasSoulPatch,
NestedOuter = new
{
CommandingFaction = (l as LocustCommander).CommandingFaction,
IsNull = (l as LocustCommander).CommandingFaction == null,
Property = (int?)(l as LocustCommander).HighCommandId,
PropertyAfterNavigation = (l as LocustCommander).CommandingFaction.MaybeScalar(x => x.Eradicated),
NestedInner = new
{
HighCommand = (l as LocustCommander).HighCommand,
IsNull = (l as LocustCommander).HighCommand == null,
Property = (l as LocustCommander).MaybeScalar(x => x.DefeatedBySquadId),
PropertyAfterNavigation = (l as LocustCommander).HighCommand.Name
}
}
}),
elementSorter: e => e.Leader.Name,
elementAsserter: (e, a) =>
{
AssertEqual(e.Leader, a.Leader);
AssertEqual(e.DefeatedBy, a.DefeatedBy);
AssertEqual(e.IsNull, a.IsNull);
AssertEqual(e.Property, a.Property);
AssertEqual(e.PropertyAfterNavigation, a.PropertyAfterNavigation);
AssertEqual(e.NestedOuter.CommandingFaction, a.NestedOuter.CommandingFaction);
AssertEqual(e.NestedOuter.IsNull, a.NestedOuter.IsNull);
AssertEqual(e.NestedOuter.Property, a.NestedOuter.Property);
AssertEqual(e.NestedOuter.PropertyAfterNavigation, a.NestedOuter.PropertyAfterNavigation);
AssertEqual(e.NestedOuter.NestedInner.HighCommand, a.NestedOuter.NestedInner.HighCommand);
AssertEqual(e.NestedOuter.NestedInner.IsNull, a.NestedOuter.NestedInner.IsNull);
AssertEqual(e.NestedOuter.NestedInner.Property, a.NestedOuter.NestedInner.Property);
AssertEqual(e.NestedOuter.NestedInner.PropertyAfterNavigation, a.NestedOuter.NestedInner.PropertyAfterNavigation);
});
}

protected GearsOfWarContext CreateContext()
=> Fixture.CreateContext();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.TestModels.Northwind;
using Microsoft.EntityFrameworkCore.TestUtilities;
using Xunit;
Expand Down Expand Up @@ -2038,7 +2034,7 @@ public virtual Task Projecting_count_of_navigation_which_is_generic_collection(b
assertOrder: true);
}

[ConditionalTheory(Skip = "issue #22701")]
[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Projecting_count_of_navigation_which_is_generic_collection_using_convert(bool async)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel;
using Microsoft.EntityFrameworkCore.TestUtilities;
using Xunit;
Expand Down Expand Up @@ -8157,6 +8155,48 @@ FROM [Weapons] AS [w]
WHERE [w].[AmmunitionType] = 1");
}

public override async Task Project_navigation_defined_on_base_from_entity_with_inheritance_using_soft_cast(bool async)
{
await base.Project_navigation_defined_on_base_from_entity_with_inheritance_using_soft_cast(async);

AssertSql(
@"SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note], CASE
WHEN [t].[Id] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull], [c].[Name], [c].[Location], [c].[Nation], CASE
WHEN [c].[Name] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull], [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name], CASE
WHEN [s].[Id] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull]
FROM [Gears] AS [g]
LEFT JOIN [Tags] AS [t] ON ([g].[Nickname] = [t].[GearNickName]) AND ([g].[SquadId] = [t].[GearSquadId])
LEFT JOIN [Cities] AS [c] ON [g].[CityOfBirthName] = [c].[Name]
LEFT JOIN [Squads] AS [s] ON [g].[SquadId] = [s].[Id]");
}

public override async Task Project_navigation_defined_on_derived_from_entity_with_inheritance_using_soft_cast(bool async)
{
await base.Project_navigation_defined_on_derived_from_entity_with_inheritance_using_soft_cast(async);

AssertSql(
@"SELECT [l].[Name], [l].[Discriminator], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], [l].[DefeatedByNickname], [l].[DefeatedBySquadId], [l].[HighCommandId], [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], CASE
WHEN [g].[Nickname] IS NULL OR [g].[SquadId] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull], [f].[Id], [f].[CapitalName], [f].[Discriminator], [f].[Name], [f].[ServerAddress], [f].[CommanderName], [f].[Eradicated], CASE
WHEN [f].[Id] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull], [l0].[Id], [l0].[IsOperational], [l0].[Name], CASE
WHEN [l0].[Id] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull]
FROM [LocustLeaders] AS [l]
LEFT JOIN [Gears] AS [g] ON ([l].[DefeatedByNickname] = [g].[Nickname]) AND ([l].[DefeatedBySquadId] = [g].[SquadId])
LEFT JOIN [Factions] AS [f] ON [l].[Name] = [f].[CommanderName]
LEFT JOIN [LocustHighCommands] AS [l0] ON [l].[HighCommandId] = [l0].[Id]");
}

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.TestUtilities;
using Xunit;
using Xunit.Abstractions;

namespace Microsoft.EntityFrameworkCore.Query
Expand Down Expand Up @@ -1476,6 +1472,17 @@ FROM [Customers] AS [c]
ORDER BY [c].[CustomerID]");
}

public override async Task Projecting_count_of_navigation_which_is_generic_collection_using_convert(bool async)
{
await base.Projecting_count_of_navigation_which_is_generic_collection_using_convert(async);

AssertSql(
@"SELECT [c].[CustomerID], [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate]
FROM [Customers] AS [c]
LEFT JOIN [Orders] AS [o] ON [c].[CustomerID] = [o].[CustomerID]
ORDER BY [c].[CustomerID]");
}

public override async Task Projection_take_projection_doesnt_project_intermittent_column(bool async)
{
await base.Projection_take_projection_doesnt_project_intermittent_column(async);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel;
using Xunit;
using Xunit.Abstractions;
Expand Down Expand Up @@ -9087,6 +9085,64 @@ public override async Task Where_TimeOnly_subtract_TimeOnly(bool async)
AssertSql("");
}

public override async Task Project_navigation_defined_on_base_from_entity_with_inheritance_using_soft_cast(bool async)
{
await base.Project_navigation_defined_on_base_from_entity_with_inheritance_using_soft_cast(async);

AssertSql(
@"SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], CASE
WHEN [o].[Nickname] IS NOT NULL THEN N'Officer'
END AS [Discriminator], [t].[Id], [t].[GearNickName], [t].[GearSquadId], [t].[IssueDate], [t].[Note], CASE
WHEN [t].[Id] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull], [c].[Name], [c].[Location], [c].[Nation], CASE
WHEN [c].[Name] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull], [s].[Id], [s].[Banner], [s].[Banner5], [s].[InternalNumber], [s].[Name], CASE
WHEN [s].[Id] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull]
FROM [Gears] AS [g]
LEFT JOIN [Officers] AS [o] ON ([g].[Nickname] = [o].[Nickname]) AND ([g].[SquadId] = [o].[SquadId])
LEFT JOIN [Tags] AS [t] ON ([g].[Nickname] = [t].[GearNickName]) AND ([g].[SquadId] = [t].[GearSquadId])
LEFT JOIN [Cities] AS [c] ON [g].[CityOfBirthName] = [c].[Name]
LEFT JOIN [Squads] AS [s] ON [g].[SquadId] = [s].[Id]");
}

public override async Task Project_navigation_defined_on_derived_from_entity_with_inheritance_using_soft_cast(bool async)
{
await base.Project_navigation_defined_on_derived_from_entity_with_inheritance_using_soft_cast(async);

AssertSql(
@"SELECT [l].[Name], [l].[LocustHordeId], [l].[ThreatLevel], [l].[ThreatLevelByte], [l].[ThreatLevelNullableByte], [l0].[DefeatedByNickname], [l0].[DefeatedBySquadId], [l0].[HighCommandId], CASE
WHEN [l0].[Name] IS NOT NULL THEN N'LocustCommander'
END AS [Discriminator], [t].[Nickname], [t].[SquadId], [t].[AssignedCityName], [t].[CityOfBirthName], [t].[FullName], [t].[HasSoulPatch], [t].[LeaderNickname], [t].[LeaderSquadId], [t].[Rank], [t].[Discriminator], CASE
WHEN [t].[Nickname] IS NULL OR [t].[SquadId] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull], [t0].[Id], [t0].[CapitalName], [t0].[Name], [t0].[ServerAddress], [t0].[CommanderName], [t0].[Eradicated], CASE
WHEN [t0].[Id] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull], [l2].[Id], [l2].[IsOperational], [l2].[Name], CASE
WHEN [l2].[Id] IS NULL THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END AS [IsNull]
FROM [LocustLeaders] AS [l]
LEFT JOIN [LocustCommanders] AS [l0] ON [l].[Name] = [l0].[Name]
LEFT JOIN (
SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], CASE
WHEN [o].[Nickname] IS NOT NULL THEN N'Officer'
END AS [Discriminator]
FROM [Gears] AS [g]
LEFT JOIN [Officers] AS [o] ON ([g].[Nickname] = [o].[Nickname]) AND ([g].[SquadId] = [o].[SquadId])
) AS [t] ON ([l0].[DefeatedByNickname] = [t].[Nickname]) AND ([l0].[DefeatedBySquadId] = [t].[SquadId])
LEFT JOIN (
SELECT [f].[Id], [f].[CapitalName], [f].[Name], [f].[ServerAddress], [l1].[CommanderName], [l1].[Eradicated]
FROM [Factions] AS [f]
INNER JOIN [LocustHordes] AS [l1] ON [f].[Id] = [l1].[Id]
) AS [t0] ON [l].[Name] = [t0].[CommanderName]
LEFT JOIN [LocustHighCommands] AS [l2] ON [l0].[HighCommandId] = [l2].[Id]");
}

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
Expand Down

0 comments on commit 2334c34

Please sign in to comment.