Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add regression tests #22282

Merged
1 commit merged into from
Aug 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4184,6 +4184,18 @@ public override Task Entity_equality_on_subquery_with_null_check(bool async)
return base.Entity_equality_on_subquery_with_null_check(async);
}

[ConditionalTheory(Skip = "DefaultIfEmpty Issue#17246")]
public override Task DefaultIfEmpty_over_empty_collection_followed_by_projecting_constant(bool async)
{
return base.DefaultIfEmpty_over_empty_collection_followed_by_projecting_constant(async);
}

[ConditionalTheory(Skip = "Non embedded collection subquery Issue#17246")]
public override Task FirstOrDefault_with_predicate_nested(bool async)
{
return base.FirstOrDefault_with_predicate_nested(async);
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,24 +125,30 @@ public override Task Include_collection_with_last_no_orderby(bool async)
() => base.Include_collection_with_last_no_orderby(async), RelationalStrings.MissingOrderingInSqlExpression);
}

[ConditionalTheory(Skip = "Collection Include on nested collection")]
[ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")]
public override Task Multi_level_includes_are_applied_with_take(bool async)
{
return base.Multi_level_includes_are_applied_with_take(async);
}

[ConditionalTheory(Skip = "Collection Include on nested collection")]
[ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")]
public override Task Multi_level_includes_are_applied_with_skip(bool async)
{
return base.Multi_level_includes_are_applied_with_skip(async);
}

[ConditionalTheory(Skip = "Collection Include on nested collection")]
[ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")]
public override Task Multi_level_includes_are_applied_with_skip_take(bool async)
{
return base.Multi_level_includes_are_applied_with_skip_take(async);
}

[ConditionalTheory(Skip = "Issue#22283 Collection Include on nested entity")]
public override Task Include_in_let_followed_by_FirstOrDefault(bool async)
{
return base.Include_in_let_followed_by_FirstOrDefault(async);
}

protected override Expression RewriteServerQueryExpression(Expression serverQueryExpression)
{
serverQueryExpression = base.RewriteServerQueryExpression(serverQueryExpression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,24 +113,30 @@ public override Task Include_collection_with_last_no_orderby(bool async)
() => base.Include_collection_with_last_no_orderby(async), RelationalStrings.MissingOrderingInSqlExpression);
}

[ConditionalTheory(Skip = "Collection Include on nested collection")]
[ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")]
public override Task Multi_level_includes_are_applied_with_take(bool async)
{
return base.Multi_level_includes_are_applied_with_take(async);
}

[ConditionalTheory(Skip = "Collection Include on nested collection")]
[ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")]
public override Task Multi_level_includes_are_applied_with_skip(bool async)
{
return base.Multi_level_includes_are_applied_with_skip(async);
}

[ConditionalTheory(Skip = "Collection Include on nested collection")]
[ConditionalTheory(Skip = "Issue#22283 Collection Include on nested collection")]
public override Task Multi_level_includes_are_applied_with_skip_take(bool async)
{
return base.Multi_level_includes_are_applied_with_skip_take(async);
}

[ConditionalTheory(Skip = "Issue#22283 Collection Include on nested entity")]
public override Task Include_in_let_followed_by_FirstOrDefault(bool async)
{
return base.Include_in_let_followed_by_FirstOrDefault(async);
}

protected override Expression RewriteServerQueryExpression(Expression serverQueryExpression)
{
serverQueryExpression = base.RewriteServerQueryExpression(serverQueryExpression);
Expand Down
48 changes: 48 additions & 0 deletions test/EFCore.Specification.Tests/CustomConvertersTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,43 @@ protected class OwnedWithConverter
public int Value { get; set; }
}

[ConditionalFact]
public virtual void Id_object_as_entity_key()
{
using var context = CreateContext();
var books = context.Set<Book>().Where(b => b.Id == new BookId(1)).ToList();

Assert.Equal("Book1", Assert.Single(books).Value);
}

public class Book
{
public BookId Id { get; set; }

public string Value { get; set; }

public Book(BookId id)
{
Id = id;
}
}

public class BookId
{
public readonly int Id;

public BookId(int id)
{
Id = id;
}

public override bool Equals(object obj)
=> obj is BookId item && Id == item.Id;

public override int GetHashCode()
=> Id.GetHashCode();
}

public abstract class CustomConvertersFixtureBase : BuiltInDataTypesFixtureBase
{
protected override string StoreName { get; } = "CustomConverters";
Expand Down Expand Up @@ -1172,6 +1209,17 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con
new Parent { Id = 1 },
new Parent { Id = 2 });
});

modelBuilder.Entity<Book>(
b =>
{
b.HasKey(e => e.Id);
b.Property(e => e.Id).HasConversion(
e => e.Id,
e => new BookId(e));

b.HasData(new Book(new BookId(1)) { Value = "Book1" });
});
}

private static class StringToDictionarySerializer
Expand Down
43 changes: 29 additions & 14 deletions test/EFCore.Specification.Tests/Query/GearsOfWarQueryTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,8 @@ public virtual Task Select_enum_has_flag(bool async)
.Select(
b => new
{
hasFlagTrue = b.Rank.HasFlag(MilitaryRank.Corporal), hasFlagFalse = b.Rank.HasFlag(MilitaryRank.Sergeant)
hasFlagTrue = b.Rank.HasFlag(MilitaryRank.Corporal),
hasFlagFalse = b.Rank.HasFlag(MilitaryRank.Sergeant)
}));
}

Expand Down Expand Up @@ -1195,12 +1196,12 @@ public virtual Task Where_conditional_equality_1(bool async)
return AssertQuery(
async,
ss => from g in ss.Set<Gear>()
orderby g.Nickname
where (g.LeaderNickname != null
? g.HasSoulPatch
: null)
== null
select g.Nickname,
orderby g.Nickname
where (g.LeaderNickname != null
? g.HasSoulPatch
: null)
== null
select g.Nickname,
assertOrder: true);
}

Expand Down Expand Up @@ -1269,11 +1270,11 @@ public virtual Task Where_compare_anonymous_types(bool async)
ss => from g in ss.Set<Gear>()
from o in ss.Set<Gear>().OfType<Officer>()
where new
{
Name = g.LeaderNickname,
Squad = g.LeaderSquadId,
Five = 5
}
{
Name = g.LeaderNickname,
Squad = g.LeaderSquadId,
Five = 5
}
== new
{
Name = o.Nickname,
Expand Down Expand Up @@ -3151,7 +3152,8 @@ where f is LocustHorde
orderby f.Name
select new
{
Name = EF.Property<string>(horde, "Name"), Eradicated = EF.Property<bool>((LocustHorde)f, "Eradicated")
Name = EF.Property<string>(horde, "Name"),
Eradicated = EF.Property<bool>((LocustHorde)f, "Eradicated")
},
assertOrder: true);
}
Expand Down Expand Up @@ -3433,7 +3435,8 @@ public virtual Task Project_collection_navigation_with_inheritance3(bool async)
.Select(
f => new
{
f.Id, Gears = EF.Property<ICollection<Gear>>((Officer)((LocustHorde)f).Commander.DefeatedBy, "Reports")
f.Id,
Gears = EF.Property<ICollection<Gear>>((Officer)((LocustHorde)f).Commander.DefeatedBy, "Reports")
}),
elementSorter: e => e.Id,
elementAsserter: (e, a) =>
Expand Down Expand Up @@ -7845,6 +7848,18 @@ from w in ss.Set<Weapon>().Where(x => x.OwnerFullName != g.FullName).OrderBy(x =
});
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task FirstOrDefault_over_int_compared_to_zero(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Squad>().Where(s => s.Name == "Kilo")
.Where(s => s.Members.Where(m => m.HasSoulPatch).Select(m => m.SquadId).FirstOrDefault() != 0)
.Select(s => s.Name),
elementSorter: e => e);
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1646,6 +1646,28 @@ from order in group1.DefaultIfEmpty()
entryCount: 55);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Include_in_let_followed_by_FirstOrDefault(bool async)
{
return AssertQuery(
async,
ss => from c in ss.Set<Customer>()
let order = ss.Set<Order>().Where(o => o.CustomerID == c.CustomerID)
.OrderBy(o => o.OrderDate)
.Include(o => o.OrderDetails)
.FirstOrDefault()
where c.CustomerID.StartsWith("F")
select new
{
c.CustomerID,
Order = order
},
elementSorter: e => e.CustomerID,
elementAsserter: (e, a) => AssertEqual(e.Order, a.Order),
entryCount: 26);
}

protected virtual void ClearLog()
{
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -900,5 +900,80 @@ public virtual Task SelectMany_with_selecting_outer_element(bool async)
.Select(e => new { e, Complex = e.CustomerID + e.City })
.SelectMany(c => c.e.Orders.Select(o => c.Complex)));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task SelectMany_with_selecting_outer_entity_column_and_inner_column(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Customer>()
.OrderBy(c => c.CustomerID)
.SelectMany(c => c.Orders.OrderBy(o => o.OrderID).Skip(0).Select(o => new { c.City, o.OrderDate })),
assertOrder: true);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task SelectMany_correlated_subquery_take(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Customer>()
.Select(c => new { c.CustomerID })
.SelectMany(c => ss.Set<Customer>()
.Where(i => i.CustomerID == c.CustomerID)
.OrderBy(i => i.CustomerID + i.City)
.Take(2)),
entryCount: 91);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Distinct_SelectMany_correlated_subquery_take(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Customer>()
.Select(c => new { c.CustomerID })
.Distinct()
.SelectMany(c => ss.Set<Customer>()
.Where(i => i.CustomerID == c.CustomerID)
.OrderBy(i => i.CustomerID + i.City)
.Take(2)),
entryCount: 91);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Distinct_SelectMany_correlated_subquery_take_2(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Customer>()
.Distinct()
.SelectMany(c => ss.Set<Customer>()
.Where(i => i.CustomerID == c.CustomerID)
.OrderBy(i => i.CustomerID + i.City)
.Take(2)),
entryCount: 91);
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task Take_SelectMany_correlated_subquery_take(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Customer>()
.Select(c => new { c.CustomerID })
.OrderBy(c => c.CustomerID)
.Take(2)
.SelectMany(c => ss.Set<Customer>()
.Where(i => i.CustomerID == c.CustomerID)
.OrderBy(i => i.CustomerID + i.City)
.Take(2)),
entryCount: 2);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6260,5 +6260,51 @@ public virtual Task Entity_equality_on_subquery_with_null_check(bool async)
elementSorter: c => c.CustomerID,
elementAsserter: (e, a) => AssertEqual(e.Order, a.Order));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task DefaultIfEmpty_over_empty_collection_followed_by_projecting_constant(bool async)
{
return AssertFirstOrDefault(
async,
ss => ss.Set<Customer>().Where(c => false).DefaultIfEmpty().Select(c => "520"));
}

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual Task FirstOrDefault_with_predicate_nested(bool async)
{
return AssertQuery(
async,
ss => ss.Set<Customer>().Where(c => c.CustomerID.StartsWith("F")).OrderBy(c => c.CustomerID).Select(TestDto.Projection),
ss => ss.Set<Customer>().Where(c => c.CustomerID.StartsWith("F")).OrderBy(c => c.CustomerID)
.Select(x => new TestDto
{
CustomerID = x.CustomerID,
OrderDate = x.Orders
.FirstOrDefault(t => t.OrderID == t.OrderID)
.MaybeScalar(e => e.OrderDate)
}),
assertOrder: true,
elementAsserter: (e, a) =>
{
Assert.Equal(e.CustomerID, a.CustomerID);
Assert.Equal(e.OrderDate, a.OrderDate);
});
}

public class TestDto
{
public string CustomerID { get; set; }
public DateTime? OrderDate { get; set; }

public static readonly Expression<Func<Customer, TestDto>> Projection = x => new TestDto
{
CustomerID = x.CustomerID,
OrderDate = x.Orders
.FirstOrDefault(t => t.OrderID == t.OrderID)
.OrderDate
};
}
}
}
Loading