Skip to content

Commit

Permalink
Add more model validation tests (#28706)
Browse files Browse the repository at this point in the history
  • Loading branch information
AndriySvyryd authored Aug 15, 2022
1 parent 35d6fa1 commit ec3d80a
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 25 deletions.
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

0 comments on commit ec3d80a

Please sign in to comment.