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 more model validation tests #28706

Merged
1 commit merged into from
Aug 15, 2022
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
2 changes: 1 addition & 1 deletion src/EFCore/Infrastructure/ModelValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ protected virtual void ValidateTypeMappings(
{
_ = property.GetCurrentValueComparer(); // Will throw if there is no way to compare
}

var providerComparer = property.GetProviderValueComparer();
if (providerComparer == null)
{
Expand Down
2 changes: 1 addition & 1 deletion src/EFCore/Storage/CoreTypeMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public virtual ValueComparer ProviderValueComparer
this,
static c => (c.Converter?.ProviderClrType ?? c.ClrType) == c.ClrType
? c.KeyComparer
: ValueComparer.CreateDefault(c.Converter?.ProviderClrType ?? c.ClrType, favorStructuralComparisons: true));
: ValueComparer.CreateDefault(c.Converter!.ProviderClrType, favorStructuralComparisons: true));

/// <summary>
/// Returns a new copy of this type mapping with the given <see cref="ValueConverter" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,39 @@ public override void Detects_key_property_which_cannot_be_compared()
modelBuilder);
}

public override void Detects_noncomparable_key_property_with_comparer()
{
var modelBuilder = CreateConventionModelBuilder();

modelBuilder.Entity<WithNonComparableKey>(
eb =>
{
eb.Property(e => e.Id).HasConversion(typeof(NotComparable), typeof(CustomValueComparer<NotComparable>));
eb.HasKey(e => e.Id);
});

VerifyError(
CoreStrings.PropertyNotMapped(nameof(NotComparable), nameof(WithNonComparableKey), nameof(WithNonComparableKey.Id)),
modelBuilder);
}

public override void Detects_noncomparable_key_property_with_provider_comparer()
{
var modelBuilder = CreateConventionModelBuilder();

modelBuilder.Entity<WithNonComparableKey>(
eb =>
{
eb.Property(e => e.Id).HasConversion(
typeof(CastingConverter<NotComparable, NotComparable>), null, typeof(CustomValueComparer<NotComparable>));
eb.HasKey(e => e.Id);
});

VerifyError(
CoreStrings.PropertyNotMapped(nameof(NotComparable), nameof(WithNonComparableKey), nameof(WithNonComparableKey.Id)),
modelBuilder);
}

public override void Detects_unique_index_property_which_cannot_be_compared()
{
var modelBuilder = CreateConventionModelBuilder();
Expand Down Expand Up @@ -2613,7 +2646,7 @@ public virtual void Detects_keyless_entity_type_mapped_to_a_stored_procedure()
RelationalStrings.StoredProcedureKeyless(nameof(Animal), "Animal_Insert"),
modelBuilder);
}

[ConditionalFact]
public virtual void Detects_tableless_entity_type_mapped_to_some_stored_procedures()
{
Expand Down Expand Up @@ -2723,7 +2756,7 @@ public virtual void Detects_unmatched_stored_procedure_result_columns_in_TPH()
RelationalStrings.StoredProcedureResultColumnNotFound("Missing", nameof(Animal), "dbo.Update"),
modelBuilder);
}

[ConditionalFact]
public virtual void Detects_duplicate_parameter()
{
Expand All @@ -2738,7 +2771,7 @@ public virtual void Detects_duplicate_parameter()
RelationalStrings.StoredProcedureDuplicateParameterName("Id", "Animal_Insert"),
modelBuilder);
}

[ConditionalFact]
public virtual void Detects_duplicate_result_column()
{
Expand Down Expand Up @@ -2822,7 +2855,7 @@ public virtual void Detects_delete_stored_procedure_result_columns_in_TPH()
RelationalStrings.StoredProcedureResultColumnDelete(nameof(Animal), nameof(Animal.Name), "Delete"),
modelBuilder);
}

[ConditionalFact]
public virtual void Detects_generated_properties_mapped_to_result_and_parameter()
{
Expand All @@ -2838,7 +2871,7 @@ public virtual void Detects_generated_properties_mapped_to_result_and_parameter(
RelationalStrings.StoredProcedureResultColumnParameterConflict(nameof(Animal), nameof(Animal.Name), "Animal_Update"),
modelBuilder);
}

[ConditionalFact]
public virtual void Detects_generated_properties_mapped_to_original_and_current_parameter()
{
Expand All @@ -2854,7 +2887,7 @@ public virtual void Detects_generated_properties_mapped_to_original_and_current_
RelationalStrings.StoredProcedureOutputParameterConflict(nameof(Animal), nameof(Animal.Name), "Animal_Update"),
modelBuilder);
}

[ConditionalFact]
public virtual void Detects_unmapped_concurrency_token()
{
Expand Down
50 changes: 47 additions & 3 deletions test/EFCore.Tests/Infrastructure/ModelValidatorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,50 @@ protected class WithNonComparableKey
public NotComparable Id { get; set; }
}

[ConditionalFact]
public virtual void Detects_noncomparable_key_property_with_comparer()
{
var modelBuilder = CreateConventionModelBuilder();

modelBuilder.Entity<WithNonComparableKey>(
eb =>
{
eb.Property(e => e.Id).HasConversion(typeof(NotComparable), typeof(CustomValueComparer<NotComparable>));
eb.HasKey(e => e.Id);
});

VerifyError(
CoreStrings.NonComparableKeyType(nameof(WithNonComparableKey), nameof(WithNonComparableKey.Id), nameof(NotComparable)),
modelBuilder);
}

[ConditionalFact]
public virtual void Detects_noncomparable_key_property_with_provider_comparer()
{
var modelBuilder = CreateConventionModelBuilder();

modelBuilder.Entity<WithNonComparableKey>(
eb =>
{
eb.Property(e => e.Id).HasConversion(
typeof(CastingConverter<NotComparable, NotComparable>), null, typeof(CustomValueComparer<NotComparable>));
eb.HasKey(e => e.Id);
});

VerifyError(
CoreStrings.NonComparableKeyTypes(
nameof(WithNonComparableKey), nameof(WithNonComparableKey.Id), nameof(NotComparable), nameof(NotComparable)),
modelBuilder);
}

public class CustomValueComparer<T> : ValueComparer<T> // Doesn't implement IComparer
{
public CustomValueComparer()
: base(false)
{
}
}

[ConditionalFact]
public virtual void Detects_unique_index_property_which_cannot_be_compared()
{
Expand Down Expand Up @@ -1396,7 +1440,7 @@ public virtual void Detects_incompatible_discriminator_value()

VerifyError(CoreStrings.DiscriminatorValueIncompatible("1", nameof(A), "int"), modelBuilder);
}

[ConditionalFact]
public virtual void Detects_missing_discriminator_value_on_base()
{
Expand All @@ -1412,7 +1456,7 @@ public virtual void Detects_missing_discriminator_value_on_base()

entityA.SetDiscriminatorProperty(entityA.AddProperty("D", typeof(int)));
entityA.RemoveDiscriminatorValue();

entityC.SetDiscriminatorValue(1);

VerifyError(CoreStrings.NoDiscriminatorValue(entityA.DisplayName()), modelBuilder);
Expand All @@ -1433,7 +1477,7 @@ public virtual void Detects_missing_discriminator_value_on_leaf()

entityAbstract.SetDiscriminatorProperty(entityAbstract.AddProperty("D", typeof(int)));
entityAbstract.SetDiscriminatorValue(0);

entityGeneric.RemoveDiscriminatorValue();

VerifyError(CoreStrings.NoDiscriminatorValue(entityGeneric.DisplayName()), modelBuilder);
Expand Down
12 changes: 6 additions & 6 deletions test/EFCore.Tests/ModelBuilding/ModelBuilderGenericTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -517,14 +517,14 @@ public override TestPropertyBuilder<TProperty> HasField(string fieldName)
public override TestPropertyBuilder<TProperty> UsePropertyAccessMode(PropertyAccessMode propertyAccessMode)
=> Wrap(PropertyBuilder.UsePropertyAccessMode(propertyAccessMode));

public override TestPropertyBuilder<TProperty> HasConversion<TProvider>()
=> Wrap(PropertyBuilder.HasConversion<TProvider>());
public override TestPropertyBuilder<TProperty> HasConversion<TConversion>()
=> Wrap(PropertyBuilder.HasConversion<TConversion>());

public override TestPropertyBuilder<TProperty> HasConversion<TProvider>(ValueComparer? valueComparer)
=> Wrap(PropertyBuilder.HasConversion<TProvider>(valueComparer));
public override TestPropertyBuilder<TProperty> HasConversion<TConversion>(ValueComparer? valueComparer)
=> Wrap(PropertyBuilder.HasConversion<TConversion>(valueComparer));

public override TestPropertyBuilder<TProperty> HasConversion<TProvider>(ValueComparer? valueComparer, ValueComparer? providerComparerType)
=> Wrap(PropertyBuilder.HasConversion<TProvider>(valueComparer, providerComparerType));
public override TestPropertyBuilder<TProperty> HasConversion<TConversion>(ValueComparer? valueComparer, ValueComparer? providerComparerType)
=> Wrap(PropertyBuilder.HasConversion<TConversion>(valueComparer, providerComparerType));

public override TestPropertyBuilder<TProperty> HasConversion<TProvider>(
Expression<Func<TProperty, TProvider>> convertToProviderExpression,
Expand Down
12 changes: 6 additions & 6 deletions test/EFCore.Tests/ModelBuilding/ModelBuilderNonGenericTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -597,14 +597,14 @@ public override TestPropertyBuilder<TProperty> HasField(string fieldName)
public override TestPropertyBuilder<TProperty> UsePropertyAccessMode(PropertyAccessMode propertyAccessMode)
=> Wrap(PropertyBuilder.UsePropertyAccessMode(propertyAccessMode));

public override TestPropertyBuilder<TProperty> HasConversion<TProvider>()
=> Wrap(PropertyBuilder.HasConversion<TProvider>());
public override TestPropertyBuilder<TProperty> HasConversion<TConversion>()
=> Wrap(PropertyBuilder.HasConversion(typeof(TConversion)));

public override TestPropertyBuilder<TProperty> HasConversion<TProvider>(ValueComparer? valueComparer)
=> Wrap(PropertyBuilder.HasConversion<TProvider>(valueComparer));
public override TestPropertyBuilder<TProperty> HasConversion<TConversion>(ValueComparer? valueComparer)
=> Wrap(PropertyBuilder.HasConversion(typeof(TConversion), valueComparer));

public override TestPropertyBuilder<TProperty> HasConversion<TProvider>(ValueComparer? valueComparer, ValueComparer? providerComparerType)
=> Wrap(PropertyBuilder.HasConversion<TProvider>(valueComparer, providerComparerType));
public override TestPropertyBuilder<TProperty> HasConversion<TConversion>(ValueComparer? valueComparer, ValueComparer? providerComparerType)
=> Wrap(PropertyBuilder.HasConversion(typeof(TConversion), valueComparer, providerComparerType));

public override TestPropertyBuilder<TProperty> HasConversion<TProvider>(
Expression<Func<TProperty, TProvider>> convertToProviderExpression,
Expand Down
6 changes: 3 additions & 3 deletions test/EFCore.Tests/ModelBuilding/ModelBuilderTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -400,9 +400,9 @@ public abstract TestPropertyBuilder<TProperty> HasValueGeneratorFactory<TFactory
public abstract TestPropertyBuilder<TProperty> HasField(string fieldName);
public abstract TestPropertyBuilder<TProperty> UsePropertyAccessMode(PropertyAccessMode propertyAccessMode);

public abstract TestPropertyBuilder<TProperty> HasConversion<TProvider>();
public abstract TestPropertyBuilder<TProperty> HasConversion<TProvider>(ValueComparer? valueComparer);
public abstract TestPropertyBuilder<TProperty> HasConversion<TProvider>(ValueComparer? valueComparer, ValueComparer? providerComparerType);
public abstract TestPropertyBuilder<TProperty> HasConversion<TConversion>();
public abstract TestPropertyBuilder<TProperty> HasConversion<TConversion>(ValueComparer? valueComparer);
public abstract TestPropertyBuilder<TProperty> HasConversion<TConversion>(ValueComparer? valueComparer, ValueComparer? providerComparerType);

public abstract TestPropertyBuilder<TProperty> HasConversion<TProvider>(
Expression<Func<TProperty, TProvider>> convertToProviderExpression,
Expand Down