diff --git a/.gitignore b/.gitignore index 256b66e..1a225ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ + *.user *.obj *.lib @@ -5,7 +6,6 @@ *.ncb *.cache *.gem -[Ll]ib [Oo]bj [Bb]in [Bb]uild @@ -14,4 +14,9 @@ _ReSharper*/ *.vs10x Source/Gallio Reports -Source/TestResults \ No newline at end of file +Source/TestResults +Source/_UpgradeReport_Files/ +*.orig +Source/UpgradeLog* +Source/packages +Source/.vs diff --git a/Source/.nuget/NuGet.Config b/Source/.nuget/NuGet.Config new file mode 100644 index 0000000..67f8ea0 --- /dev/null +++ b/Source/.nuget/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Source/.nuget/NuGet.exe b/Source/.nuget/NuGet.exe new file mode 100644 index 0000000..4c60aa3 Binary files /dev/null and b/Source/.nuget/NuGet.exe differ diff --git a/Source/.nuget/NuGet.targets b/Source/.nuget/NuGet.targets new file mode 100644 index 0000000..3ae18ce --- /dev/null +++ b/Source/.nuget/NuGet.targets @@ -0,0 +1,71 @@ + + + + $(MSBuildProjectDirectory)\..\ + + + $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) + $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) + $([System.IO.Path]::Combine($(SolutionDir), "packages")) + + + $(SolutionDir).nuget + packages.config + $(SolutionDir)packages + + + $(NuGetToolsPath)\nuget.exe + "$(NuGetExePath)" + mono --runtime=v4.0.30319 $(NuGetExePath) + + $(TargetDir.Trim('\\')) + + + "" + + + false + + + false + + + $(NuGetCommand) install "$(PackagesConfig)" -source $(PackageSources) -o "$(PackagesDir)" + $(NuGetCommand) pack "$(ProjectPath)" -p Configuration=$(Configuration) -o "$(PackageOutputDir)" -symbols + + + + RestorePackages; + $(BuildDependsOn); + + + + + $(BuildDependsOn); + BuildPackage; + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/Debug.xunit b/Source/Debug.xunit new file mode 100644 index 0000000..f6a167c --- /dev/null +++ b/Source/Debug.xunit @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Source/FluentMetadata.AutoMapper.Specs/FluentMetadata.AutoMapper.Specs.csproj b/Source/FluentMetadata.AutoMapper.Specs/FluentMetadata.AutoMapper.Specs.csproj new file mode 100644 index 0000000..9723371 --- /dev/null +++ b/Source/FluentMetadata.AutoMapper.Specs/FluentMetadata.AutoMapper.Specs.csproj @@ -0,0 +1,90 @@ + + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {36BC8904-D8F8-4778-A5BB-F27F1346BAE9} + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Library + Properties + FluentMetadata.AutoMapper.Specs + FluentMetadata.AutoMapper.Specs + v4.0 + 512 + ..\ + true + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\AutoMapper.6.2.2\lib\net40\AutoMapper.dll + + + + + + + + + + + False + ..\..\external\xUnit\xunit.dll + + + + + + + + + + {3EA6A0AC-8377-4C2F-A0EA-61278245620E} + FluentMetadata.AutoMapper + + + {C73F37FA-D859-4714-8335-35069322176A} + FluentMetadata.Core + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/Source/FluentMetadata.AutoMapper.Specs/Properties/AssemblyInfo.cs b/Source/FluentMetadata.AutoMapper.Specs/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3a174f7 --- /dev/null +++ b/Source/FluentMetadata.AutoMapper.Specs/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FluentMetadata.AutoMapper.Specs")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("FluentMetadata.AutoMapper.Specs")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("10e83014-1379-41a6-821d-50d5a1317676")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Source/FluentMetadata.AutoMapper.Specs/SystemUnderTest.cs b/Source/FluentMetadata.AutoMapper.Specs/SystemUnderTest.cs new file mode 100644 index 0000000..a690e3a --- /dev/null +++ b/Source/FluentMetadata.AutoMapper.Specs/SystemUnderTest.cs @@ -0,0 +1,68 @@ +using AutoMapper; + +namespace FluentMetadata.AutoMapper.Specs +{ + internal class Source + { + public string MyProperty { get; set; } + internal string NonPublic { get; set; } + public int Named { get; set; } + public Nested Nested { get; set; } + public string StringField { get; set; } + } + + internal class Nested + { + public FurtherNested FurtherNested { get; set; } + } + + internal class FurtherNested + { + public int Id { get; set; } + } + + internal class Destination + { + public string MyProperty { get; set; } + internal string NonPublic { get; set; } + public int Renamed { get; set; } + public int NestedFurtherNestedId { get; set; } + public int IntProperty { get; set; } + } + + internal class FakeResolver : IMemberValueResolver + { + public int Resolve(Source source, Destination destination, string sourceMember, int destMember, ResolutionContext context) + { + return default(int); + } + } + + internal class SourceMetaData : ClassMetadata + { + public SourceMetaData() + { + Class.Display.Name("rzjsfghgafsdfh"); + Property(x => x.MyProperty).Display.Name("pockänsdfsdf"); + Property(x => x.NonPublic).Description("non-public"); + Property(x => x.Named).Description("adföoiulkanhsda"); + Property(x => x.StringField).UIHint("üoicvnqwnb"); + } + } + + internal class FurtherNestedMetaData : ClassMetadata + { + public FurtherNestedMetaData() + { + Property(x => x.Id).Is.Required(); + } + } + + internal class TargetMetaData : ClassMetadata + { + public TargetMetaData() + { + this.CopyAutoMappedMetadataFrom(typeof(Source)); + } + } +} \ No newline at end of file diff --git a/Source/FluentMetadata.AutoMapper.Specs/When_copying_metadata_from_an_AutoMapped_Type.cs b/Source/FluentMetadata.AutoMapper.Specs/When_copying_metadata_from_an_AutoMapped_Type.cs new file mode 100644 index 0000000..e4e5f1f --- /dev/null +++ b/Source/FluentMetadata.AutoMapper.Specs/When_copying_metadata_from_an_AutoMapped_Type.cs @@ -0,0 +1,66 @@ +using AutoMapper; +using Xunit; + +namespace FluentMetadata.AutoMapper.Specs +{ + public class When_copying_metadata_from_an_AutoMapped_Type + { + private readonly Metadata destinationMetadata; + + public When_copying_metadata_from_an_AutoMapped_Type() + { + FluentMetadataBuilder.Reset(); + Mapper.Reset(); + + Mapper.Initialize(cfg => + { + cfg.ShouldMapProperty = pi => true; //in order to test NonPublic member mapping as well + + cfg.CreateMap() + .ForMember(d => d.Renamed, o => o.MapFrom(s => s.Named)) + .ForMember(d => d.IntProperty, o => o.ResolveUsing(s => s.StringField)); + }); + + Mapper.AssertConfigurationIsValid(); + FluentMetadataBuilder.ForAssemblyOfType(); + + destinationMetadata = QueryFluentMetadata.GetMetadataFor(typeof(Destination)); + } + + [Fact] + public void a_destination_property_should_have_metadata_from_the_source_property_it_is_mapped_to() + { + Assert.Equal("pockänsdfsdf", destinationMetadata.Properties[nameof(Destination.MyProperty)].GetDisplayName()); + } + + [Fact] + public void a_non_public_destination_property_should_have_metadata_from_the_source_property_it_is_mapped_to() + { + Assert.Equal("non-public", destinationMetadata.Properties[nameof(Destination.NonPublic)].GetDescription()); + } + + [Fact] + public void the_destination_type_should_have_metadata_from_the_source_type_it_is_mapped_to() + { + Assert.Equal("rzjsfghgafsdfh", destinationMetadata.GetDisplayName()); + } + + [Fact] + public void a_projected_destination_property_should_have_metadata_from_the_source_property_it_is_mapped_to() + { + Assert.Equal("adföoiulkanhsda", destinationMetadata.Properties[nameof(Destination.Renamed)].GetDescription()); + } + + [Fact] + public void a_flattened_destination_property_should_have_metadata_from_the_source_property_it_is_mapped_to() + { + Assert.Equal(true, destinationMetadata.Properties[nameof(Destination.NestedFurtherNestedId)].Required); + } + + [Fact] + public void a_destination_property_resolved_from_a_source_property_should_have_metadata_from_the_source_property() + { + Assert.Equal("üoicvnqwnb", destinationMetadata.Properties[nameof(Destination.IntProperty)].TemplateHint); + } + } +} \ No newline at end of file diff --git a/Source/FluentMetadata.AutoMapper.Specs/app.config b/Source/FluentMetadata.AutoMapper.Specs/app.config new file mode 100644 index 0000000..4ae5b9c --- /dev/null +++ b/Source/FluentMetadata.AutoMapper.Specs/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Source/FluentMetadata.AutoMapper.Specs/packages.config b/Source/FluentMetadata.AutoMapper.Specs/packages.config new file mode 100644 index 0000000..9bb70d2 --- /dev/null +++ b/Source/FluentMetadata.AutoMapper.Specs/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/Source/FluentMetadata.AutoMapper/AutoMapperHelper.cs b/Source/FluentMetadata.AutoMapper/AutoMapperHelper.cs new file mode 100644 index 0000000..6873f44 --- /dev/null +++ b/Source/FluentMetadata.AutoMapper/AutoMapperHelper.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using AutoMapper; + +namespace FluentMetadata.AutoMapper +{ + internal class AutoMapperHelper + { + /// + /// Gets the mapped members for a source/destination type pair. + /// + /// The source Type. + /// The destination Type. + /// + internal static IEnumerable GetMemberMapsOf(Type source, Type destination) + { + var maps = new Collection(); + + foreach (var propertyMap in GetRelevantMappedMembersOf(source, destination)) + { + if (propertyMap.SourceMember != null) + { + maps.Add(new MemberMap + { + SourceName = propertyMap.SourceMembers.Count() > 1 ? + propertyMap.SourceMembers.Aggregate(string.Empty, (result, svr) => result + svr.Name) : + propertyMap.SourceMember.Name, + DestinationName = propertyMap.DestinationProperty.Name + }); + } + else if (propertyMap.ValueResolverConfig != null) + { + maps.Add(new MemberMap + { + SourceName = propertyMap.ValueResolverConfig.SourceMemberName ?? ExpressionHelper.GetPropertyName(propertyMap.ValueResolverConfig.SourceMember), + DestinationName = propertyMap.DestinationProperty.Name + }); + } + } + + return maps; + } + + /// + /// Gets the mapped members for a source/destination type pair + /// leaving out mapped members that are irrelevant. + /// + /// The source type. + /// The destination type. + /// + private static IEnumerable GetRelevantMappedMembersOf(Type source, Type destination) + { + var typeMap = Mapper.Configuration.FindTypeMapFor(source, destination); + // filter by non-ignored PropertyMaps + return typeMap != null ? typeMap.GetPropertyMaps().Where(m => !m.Ignored) : Enumerable.Empty(); + } + } +} \ No newline at end of file diff --git a/Source/FluentMetadata.AutoMapper/ClassMetadataAutoMapperExtensions.cs b/Source/FluentMetadata.AutoMapper/ClassMetadataAutoMapperExtensions.cs new file mode 100644 index 0000000..ae9a828 --- /dev/null +++ b/Source/FluentMetadata.AutoMapper/ClassMetadataAutoMapperExtensions.cs @@ -0,0 +1,23 @@ +using System; + +namespace FluentMetadata.AutoMapper +{ + /// + /// AutoMapper extensions to + /// + public static class ClassMetadataAutoMapperExtensions + { + /// + /// Copies the the source type's metadata to the destination type's metadata + /// using the mapping information provided by AutoMapper. + /// + /// The type of the destination. + /// The destination metadata. + /// The source type. + public static void CopyAutoMappedMetadataFrom(this ClassMetadata to, Type from) + { + var destinationType = typeof(TDestination); + MetadataHelper.CopyMappedMetadata(from, destinationType, AutoMapperHelper.GetMemberMapsOf(from, destinationType)); + } + } +} \ No newline at end of file diff --git a/Source/FluentMetadata.AutoMapper/FluentMetadata.AutoMapper.csproj b/Source/FluentMetadata.AutoMapper/FluentMetadata.AutoMapper.csproj new file mode 100644 index 0000000..6cc1ac1 --- /dev/null +++ b/Source/FluentMetadata.AutoMapper/FluentMetadata.AutoMapper.csproj @@ -0,0 +1,72 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {3EA6A0AC-8377-4C2F-A0EA-61278245620E} + Library + Properties + FluentMetadata.AutoMapper + FluentMetadata.AutoMapper + v4.0 + 512 + ..\ + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + bin\Debug\FluentMetadata.AutoMapper.XML + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\FluentMetadata.AutoMapper.XML + + + + ..\packages\AutoMapper.6.2.2\lib\net40\AutoMapper.dll + + + + + + + + + Properties\GlobalAssemblyInfo.cs + + + + + + + + {C73F37FA-D859-4714-8335-35069322176A} + FluentMetadata.Core + + + + + + + + + \ No newline at end of file diff --git a/Source/FluentMetadata.AutoMapper/Properties/AssemblyInfo.cs b/Source/FluentMetadata.AutoMapper/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..5b6a4b9 --- /dev/null +++ b/Source/FluentMetadata.AutoMapper/Properties/AssemblyInfo.cs @@ -0,0 +1,13 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FluentMetadata.AutoMapper")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8e80ca63-7b53-49c9-b5e5-a708c8f3de7e")] \ No newline at end of file diff --git a/Source/FluentMetadata.AutoMapper/packages.config b/Source/FluentMetadata.AutoMapper/packages.config new file mode 100644 index 0000000..5a9c7ed --- /dev/null +++ b/Source/FluentMetadata.AutoMapper/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/Builder/DisplayBuilderTests.cs b/Source/FluentMetadata.Core.Specs/Builder/DisplayBuilderTests.cs index 65dc3cf..d56575e 100644 --- a/Source/FluentMetadata.Core.Specs/Builder/DisplayBuilderTests.cs +++ b/Source/FluentMetadata.Core.Specs/Builder/DisplayBuilderTests.cs @@ -17,46 +17,56 @@ public DisplayBuilderTests() [Fact] public void DisplayBuilder_Ctor_NullText_IsNull() { - Assert.Null(metadata.NullDisplayText); + Assert.Null(metadata.GetNullDisplayText()); } [Fact] public void DisplayBuilder_Ctor_Format_IsNull() { - Assert.Null(metadata.DisplayFormat); + Assert.Null(metadata.GetDisplayFormat()); } [Fact] public void DisplayBuilder_Ctor_Name_IsNull() { - Assert.Null(metadata.DisplayName); + Assert.Null(metadata.GetDisplayName()); } [Fact] public void DisplayBuilder_NullText_NullText_IsValue() { builder.NullText("TheNullText"); - Assert.Equal("TheNullText", metadata.NullDisplayText); - Assert.Null(metadata.DisplayName); - Assert.Null(metadata.DisplayFormat); + Assert.Equal("TheNullText", metadata.GetNullDisplayText()); + Assert.Null(metadata.GetDisplayName()); + Assert.Null(metadata.GetDisplayFormat()); } [Fact] public void DisplayBuilder_Name_Name_IsValue() { builder.Name("TheNameText"); - Assert.Equal("TheNameText", metadata.DisplayName); - Assert.Null(metadata.NullDisplayText); - Assert.Null(metadata.DisplayFormat); + Assert.Equal("TheNameText", metadata.GetDisplayName()); + Assert.Null(metadata.GetNullDisplayText()); + Assert.Null(metadata.GetDisplayFormat()); + } + + [Fact] + public void DisplayBuilder_Name_Function_Equals_Metadata_DisplayName() + { + const string displayName = "asdf"; + builder.Name(() => displayName); + Assert.Equal(displayName, metadata.GetDisplayName()); + Assert.Null(metadata.GetNullDisplayText()); + Assert.Null(metadata.GetDisplayFormat()); } [Fact] public void DisplayBuilder_Format_Format_IsValue() { builder.Format("TheFormatText"); - Assert.Equal("TheFormatText", metadata.DisplayFormat); - Assert.Null(metadata.NullDisplayText); - Assert.Null(metadata.DisplayName); + Assert.Equal("TheFormatText", metadata.GetDisplayFormat()); + Assert.Null(metadata.GetNullDisplayText()); + Assert.Null(metadata.GetDisplayName()); } [Fact] @@ -65,10 +75,9 @@ public void DisplayBuilder_Allset_IsValue() builder.Format("TheFormatText"); builder.Name("TheNameText"); builder.NullText("TheNullText"); - Assert.Equal("TheFormatText", metadata.DisplayFormat); - Assert.Equal("TheNameText", metadata.DisplayName); - Assert.Equal("TheNullText", metadata.NullDisplayText); + Assert.Equal("TheFormatText", metadata.GetDisplayFormat()); + Assert.Equal("TheNameText", metadata.GetDisplayName()); + Assert.Equal("TheNullText", metadata.GetNullDisplayText()); } - } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/Builder/EditorBuilderTests.cs b/Source/FluentMetadata.Core.Specs/Builder/EditorBuilderTests.cs index 888b7b0..cfd4f65 100644 --- a/Source/FluentMetadata.Core.Specs/Builder/EditorBuilderTests.cs +++ b/Source/FluentMetadata.Core.Specs/Builder/EditorBuilderTests.cs @@ -23,13 +23,13 @@ public void EditorBuilder_Ctor_ErrorMessage_IsNull() [Fact] public void EditorBuilder_Ctor_Format_IsNull() { - Assert.Null(metadata.EditorFormat); + Assert.Null(metadata.GetEditorFormat()); } [Fact] public void EditorBuilder_Ctor_Watermark_IsNull() { - Assert.Null(metadata.Watermark); + Assert.Null(metadata.GetWatermark()); } [Fact] @@ -37,24 +37,24 @@ public void EditorBuilder_ErrorMessage_ErrorMessage_IsValue() { builder.ErrorMessage("TheNullText"); Assert.Equal("TheNullText", metadata.ErrorMessage); - Assert.Null(metadata.EditorFormat); - Assert.Null(metadata.Watermark); + Assert.Null(metadata.GetEditorFormat()); + Assert.Null(metadata.GetWatermark()); } [Fact] public void EditorBuilder_Name_Name_IsValue() { builder.Watermark("TheNameText"); - Assert.Equal("TheNameText", metadata.Watermark); - Assert.Null(metadata.EditorFormat); + Assert.Equal("TheNameText", metadata.GetWatermark()); + Assert.Null(metadata.GetEditorFormat()); } [Fact] public void EditorBuilder_Format_Format_IsValue() { builder.Format("TheFormatText"); - Assert.Equal("TheFormatText", metadata.EditorFormat); - Assert.Null(metadata.Watermark); + Assert.Equal("TheFormatText", metadata.GetEditorFormat()); + Assert.Null(metadata.GetWatermark()); } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/Builder/IsBuilderTests.cs b/Source/FluentMetadata.Core.Specs/Builder/IsBuilderTests.cs index 3c3f275..5e14bf0 100644 --- a/Source/FluentMetadata.Core.Specs/Builder/IsBuilderTests.cs +++ b/Source/FluentMetadata.Core.Specs/Builder/IsBuilderTests.cs @@ -1,12 +1,14 @@ -using FluentMetadata.Builder; +using System.Linq; +using FluentMetadata.Builder; +using FluentMetadata.Rules; using Xunit; namespace FluentMetadata.Specs.Builder { public class IsBuilderTests { - private readonly IIsProperty isBuilder; - private readonly Metadata metadata; + readonly IIsProperty isBuilder; + readonly Metadata metadata; public IsBuilderTests() { @@ -23,35 +25,46 @@ public void IsBuilder_Ctor_IsNotSet() [Fact] public void IsBuilder_Ctor_IsNotReadOnly() { - Assert.False(metadata.Readonly); + Assert.False(metadata.ReadOnly); } [Fact] - public void IsBuilder_Required_IsRequired() + public void SettingRequiredResultsInMetadataRequiredAnd1RequiredRule() { isBuilder.Required(); Assert.True(metadata.Required.Value); + Assert.Equal(1, metadata.Rules.OfType().Count()); } [Fact] - public void IsBuilder_Not_Required_IsNotRequired() + public void SettingNotRequiredResultsInMetadataNotRequiredAnd0RequiredRules() { isBuilder.Not.Required(); Assert.False(metadata.Required.Value); + Assert.Equal(0, metadata.Rules.OfType().Count()); + } + + [Fact] + public void SettingNotRequiredAfterRequiredResultsInMetadataNotRequiredAnd0RequiredRules() + { + isBuilder.Required(); + isBuilder.Not.Required(); + Assert.False(metadata.Required.Value); + Assert.Equal(0, metadata.Rules.OfType().Count()); } [Fact] public void IsBuilder_Readonly_IsReadOnly() { isBuilder.ReadOnly(); - Assert.True(metadata.Readonly); + Assert.True(metadata.ReadOnly); } [Fact] public void IsBuilder_Not_Readonly_IsNotReadOnly() { isBuilder.Not.ReadOnly(); - Assert.False(metadata.Readonly); + Assert.False(metadata.ReadOnly); } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_copying_metadata_with_circular_references.cs b/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_copying_metadata_with_circular_references.cs new file mode 100644 index 0000000..33d1cb8 --- /dev/null +++ b/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_copying_metadata_with_circular_references.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FluentMetadata.Specs.Builder +{ + public class When_FluentMetadataBuilder_builds_copying_metadata_with_circular_references + { + Exception exception; + + public When_FluentMetadataBuilder_builds_copying_metadata_with_circular_references() + { + FluentMetadataBuilder.Reset(); + + try + { + FluentMetadataBuilder.BuildMetadataDefinitions( + GetUnbuildableMetadataDefinitions()); + } + catch (Exception ex) + { + exception = ex; + } + } + + internal static IEnumerable GetUnbuildableMetadataDefinitions() + { + var type = typeof(When_FluentMetadataBuilder_builds_copying_metadata_with_circular_references); + return type.Assembly.GetTypes() + .Where(t => t.FullName.StartsWith(type.FullName) && + t.Is()); + } + + [Fact] + public void It_throws_a_CircularRefenceException() + { + Assert.IsType(exception); + } + + [Fact] + public void The_CircularRefenceException_contains_the_full_name_of_each_type_building_the_circular_reference() + { + GetUnbuildableMetadataDefinitions() + .ToList() + .ForEach(t => Assert.Contains(t.FullName, exception.Message)); + } + + #region metadata with circular references + + class SomeType { } + class SomeOtherType { } + class SomeThirdType { } + class SomeTypeMetadata : ClassMetadata + { + public SomeTypeMetadata() + { + CopyMetadataFrom(); + } + } + class SomeOtherTypeMetadata : ClassMetadata + { + public SomeOtherTypeMetadata() + { + CopyMetadataFrom(); + } + } + class SomeThirdTypeMetadata : ClassMetadata + { + public SomeThirdTypeMetadata() + { + CopyMetadataFrom(); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_metadata_copying_from_non_existing_metadata.cs b/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_metadata_copying_from_non_existing_metadata.cs new file mode 100644 index 0000000..985fe87 --- /dev/null +++ b/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_metadata_copying_from_non_existing_metadata.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace FluentMetadata.Specs.Builder +{ + public class When_FluentMetadataBuilder_builds_metadata_copying_from_non_existing_metadata + { + readonly Exception exception; + + public When_FluentMetadataBuilder_builds_metadata_copying_from_non_existing_metadata() + { + FluentMetadataBuilder.Reset(); + + try + { + FluentMetadataBuilder.BuildMetadataDefinitions( + GetUnbuildableMetadataDefinitions()); + } + catch (Exception ex) + { + exception = ex; + } + } + + internal static IEnumerable GetUnbuildableMetadataDefinitions() + { + var type = typeof(When_FluentMetadataBuilder_builds_metadata_copying_from_non_existing_metadata); + return type.Assembly.GetTypes() + .Where(t => t.FullName.StartsWith(type.FullName) && + t.Is()); + } + + [Fact] + public void It_throws_a_NoMetadataDefinedException() + { + Assert.IsType(exception); + } + + [Fact] + public void The_NoMetadataDefinedException_contains_the_full_name_of_the_metadata_type_that_is_unbuildable() + { + Assert.Contains(typeof(SomeTypeMetadata).FullName, exception.Message); + } + + [Fact] + public void The_NoMetadataDefinedException_contains_the_full_name_of_the_model_type_whose_metadata_cannot_be_found() + { + Assert.Contains(typeof(SomeOtherType).FullName, exception.Message); + } + + #region metadata copying from non-existing + + class SomeType { } + class SomeOtherType { } + + class SomeTypeMetadata : ClassMetadata + { + public SomeTypeMetadata() + { + CopyMetadataFrom(); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata.cs b/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata.cs new file mode 100644 index 0000000..c362376 --- /dev/null +++ b/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata.cs @@ -0,0 +1,217 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FluentMetadata.Rules; +using Xunit; + +namespace FluentMetadata.Specs.Builder +{ + public class When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata + { + readonly List builtMetadata = FluentMetadataBuilder.BuiltMetadataDefininitions; + readonly IEnumerable someViewModelRules, someViewModelMyPropertyRules, someViewModelMyStringPropertyRules; + readonly Exception exception; + + public When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata() + { + FluentMetadataBuilder.Reset(); + var typesToBuildInLaterBatch = new[] { typeof(SomeTypeInAnotherAssemblyMetadata) }; + try + { + FluentMetadataBuilder.BuildMetadataDefinitions( + GetUnbuildableMetadataDefinitions() + .Except(typesToBuildInLaterBatch)); + FluentMetadataBuilder.BuildMetadataDefinitions(typesToBuildInLaterBatch); + someViewModelRules = QueryFluentMetadata.GetMetadataFor(typeof(SomeViewModel)).Rules; + someViewModelMyPropertyRules = QueryFluentMetadata.GetMetadataFor(typeof(SomeViewModel), "MyProperty").Rules; + someViewModelMyStringPropertyRules = QueryFluentMetadata.GetMetadataFor(typeof(SomeViewModel), "MyStringProperty").Rules; + } + catch (Exception ex) + { + exception = ex; + } + } + + internal static IEnumerable GetUnbuildableMetadataDefinitions() + { + var type = typeof(When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata); + return type.Assembly.GetTypes() + .Where(t => t.FullName.StartsWith(type.FullName) && + t.Is()); + } + + [Fact] + public void It_does_not_throw_an_exception() + { + Assert.Null(exception); + } + + [Fact] + public void Dependent_metadata_may_be_built_before_its_dependency() + { + Assert.True( + builtMetadata.IndexOf(typeof(SomeViewModelMetadata)) < + builtMetadata.IndexOf(typeof(SomeDomainModelMetadata))); + } + + [Fact] + public void Dependent_metadata_is_built_again_after_its_dependencies_because_it_copies_metadata_from_them() + { + Assert.Equal(2, builtMetadata.Count(t => t == typeof(SomeViewModelMetadata))); + Assert.True( + builtMetadata.LastIndexOf(typeof(SomeDomainModelMetadata)) < + builtMetadata.LastIndexOf(typeof(SomeViewModelMetadata))); + } + + [Fact] + public void Open_generic_metadata_is_built_before_non_generic_metadata() + { + Assert.True( + builtMetadata.IndexOf(typeof(SomeDomainBaseTypeMetadata<>)) < + builtMetadata.IndexOf(typeof(SomeDomainModelMetadata))); + } + + [Fact] + public void Dependent_metadata_is_built_again_if_dependency_is_built_again() + { + Assert.Equal(2, builtMetadata.Count(t => t == typeof(SomeOtherViewModelMetadata))); + Assert.True( + builtMetadata.LastIndexOf(typeof(SomeViewModelMetadata)) < + builtMetadata.LastIndexOf(typeof(SomeOtherViewModelMetadata))); + } + + [Fact] + public void Dependent_metadata_built_in_a_later_batch_is_built_correctly() + { + Assert.Equal(1, builtMetadata.Count(t => t == typeof(SomeTypeInAnotherAssemblyMetadata))); + } + + [Fact] + public void It_does_not_duplicate_generic_class_rules() + { + Assert.Equal(1, someViewModelRules.OfType>().Count()); + } + + [Fact] + public void It_does_not_duplicate_PropertyMustBeLessThanOtherRules() + { + Assert.Equal(1, someViewModelRules.OfType>().Count()); + } + + [Fact] + public void It_does_not_duplicate_PropertyMustMatchRules() + { + Assert.Equal(1, someViewModelRules.OfType>().Count()); + } + + [Fact] + public void It_does_not_duplicate_RequiredRules() + { + Assert.Equal(1, someViewModelMyPropertyRules.OfType().Count()); + } + + [Fact] + public void It_does_not_duplicate_PropertyMustMatchRegexRules() + { + Assert.Equal(1, someViewModelMyStringPropertyRules.OfType().Count()); + } + + [Fact] + public void It_does_not_duplicate_RangeRules() + { + Assert.Equal(1, someViewModelMyPropertyRules.OfType().Count()); + } + + [Fact] + public void It_does_not_duplicate_StringLengthRules() + { + Assert.Equal(1, someViewModelMyStringPropertyRules.OfType().Count()); + } + + [Fact] + public void It_does_not_duplicate_generic_property_rules() + { + Assert.Equal(1, someViewModelMyPropertyRules.OfType>().Count()); + } + + [Fact] + public void It_does_not_duplicate_ClassRuleValidatingAPropertyWrapper() + { + Assert.Equal(1, someViewModelMyPropertyRules.OfType().Count()); + } + + #region System under test + + #region dependent metadata is defined before its dependency + + class SomeDomainModel : SomeDomainBaseType { } + class SomeViewModel + { + public int MyProperty { get; set; } + public int MyProperty2 { get; set; } + public string MyStringProperty { get; set; } + } + class SomeViewModelMetadata : ClassMetadata + { + public SomeViewModelMetadata() + { + CopyMetadataFrom(); + Class + .AssertThat( + svm => false, + string.Empty) + .ComparableProperty(svm => svm.MyProperty) + .ShouldBeLessThan(svm => svm.MyProperty2) + .Property(svm => svm.MyProperty) + .ShouldEqual(svm => svm.MyStringProperty); + Property(svm => svm.MyProperty) + .Is.Required() + .Range(0, 1) + .AssertThat( + v => v > 100, + string.Empty); + Property(svm => svm.MyStringProperty) + .Should.MatchRegex("here be some regex") + .Length(1, 1); + } + } + class SomeDomainModelMetadata : SomeDomainBaseTypeMetadata { } + + #endregion + + #region open generic metadata is defined after non generic metadata + + class SomeDomainBaseType { } + class SomeDomainBaseTypeMetadata : ClassMetadata where T : SomeDomainBaseType { } + + #endregion + + #region metadata depentent on incorrectly build metadata + + class SomeOtherViewModel { } + class SomeOtherViewModelMetadata : ClassMetadata + { + public SomeOtherViewModelMetadata() + { + CopyMetadataFrom(); + } + } + + #endregion + + #region metadata built in a later batch + + class SomeTypeInAnotherAssembly { } + class SomeTypeInAnotherAssemblyMetadata : ClassMetadata + { + public SomeTypeInAnotherAssemblyMetadata() + { + CopyMetadataFrom(); + } + } + + #endregion + + #endregion + } +} \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata_that_does_not_apply.cs b/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata_that_does_not_apply.cs new file mode 100644 index 0000000..52815f1 --- /dev/null +++ b/Source/FluentMetadata.Core.Specs/Builder/When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata_that_does_not_apply.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FluentMetadata.Rules; +using Xunit; + +namespace FluentMetadata.Specs.Builder +{ + public class When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata_that_does_not_apply + { + readonly List builtMetadata = FluentMetadataBuilder.BuiltMetadataDefininitions; + readonly IEnumerable someViewModelRules, someViewModelMyPropertyRules; + readonly Exception exception; + + public When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata_that_does_not_apply() + { + FluentMetadataBuilder.Reset(); + + try + { + FluentMetadataBuilder.BuildMetadataDefinitions(GetUnbuildableMetadataDefinitions()); + someViewModelRules = QueryFluentMetadata.GetMetadataFor(typeof(SomeViewModel)).Rules; + someViewModelMyPropertyRules = QueryFluentMetadata.GetMetadataFor(typeof(SomeViewModel), "MyProperty").Rules; + } + catch (Exception ex) + { + exception = ex; + } + } + + internal static IEnumerable GetUnbuildableMetadataDefinitions() + { + var type = typeof(When_FluentMetadataBuilder_builds_metadata_copying_from_other_metadata_that_does_not_apply); + return type.Assembly.GetTypes() + .Where(t => t.FullName.StartsWith(type.FullName) && + t.Is()); + } + + [Fact] + public void It_does_not_throw_an_exception() + { + Assert.Null(exception); + } + + [Fact] + public void It_does_not_copy_generic_class_rules() + { + Assert.Equal(0, someViewModelRules.OfType>().Count()); + } + + [Fact] + public void It_does_not_copy_PropertyMustBeLessThanOtherRules() + { + Assert.Equal(0, someViewModelRules.OfType>().Count()); + } + + [Fact] + public void It_does_not_copy_PropertyMustMatchRules() + { + Assert.Equal(0, someViewModelRules.OfType>().Count()); + } + + [Fact] + public void It_does_copy_RequiredRules() + { + Assert.Equal(1, someViewModelMyPropertyRules.OfType().Count()); + } + + [Fact] + public void It_does_not_copy_PropertyMustMatchRegexRules() + { + Assert.Equal(0, someViewModelMyPropertyRules.OfType().Count()); + } + + [Fact] + public void It_does_not_copy_RangeRules() + { + Assert.Equal(0, someViewModelMyPropertyRules.OfType().Count()); + } + + [Fact] + public void It_does_not_copy_StringLengthRules() + { + Assert.Equal(0, someViewModelMyPropertyRules.OfType().Count()); + } + + [Fact] + public void It_does_not_copy_generic_property_rules() + { + Assert.Equal(0, someViewModelMyPropertyRules.OfType>().Count()); + } + + [Fact] + public void It_does_not_copy_ClassRuleValidatingAPropertyWrapper() + { + Assert.Equal(0, someViewModelMyPropertyRules.OfType().Count()); + } + + #region System under test + + class SomeDomainModel + { + public int MyProperty { get; set; } + public int MyProperty2 { get; set; } + } + class SomeViewModel + { + public string MyProperty { get; set; } + } + class SomeDomainModelMetadata : ClassMetadata + { + public SomeDomainModelMetadata() + { + Class + .AssertThat( + svm => false, + string.Empty) + .ComparableProperty(svm => svm.MyProperty) + .ShouldBeLessThan(svm => svm.MyProperty2) + .Property(svm => svm.MyProperty) + .ShouldEqual(svm => svm.MyProperty2); + Property(svm => svm.MyProperty) + .Is.Required() + .Should.MatchRegex("here be some regex") + .Range(0, 1) + .Length(1, 1) + .AssertThat( + v => v > 100, + string.Empty); + } + } + class SomeViewModelMetadata : ClassMetadata + { + public SomeViewModelMetadata() + { + CopyMetadataFrom(); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/ClassMetadata_with_Person.cs b/Source/FluentMetadata.Core.Specs/ClassMetadata_with_Person.cs index 5725708..1f24cca 100644 --- a/Source/FluentMetadata.Core.Specs/ClassMetadata_with_Person.cs +++ b/Source/FluentMetadata.Core.Specs/ClassMetadata_with_Person.cs @@ -1,3 +1,5 @@ +using System.Linq; +using FluentMetadata.Rules; using FluentMetadata.Specs.SampleClasses; using Xunit; @@ -5,31 +7,45 @@ namespace FluentMetadata.Specs { public class ClassMetadata_with_Person : MetadataTestBase { - private Metadata classMetadata; + readonly Metadata classMetadata; public ClassMetadata_with_Person() { - var query = new QueryFluentMetadata(); - classMetadata = query.GetMetadataFor(typeof (Person)); + classMetadata = QueryFluentMetadata.GetMetadataFor(typeof(Person)); } [Fact] public void Metadata_ModelType_is_Person() { - Assert.Equal(typeof (Person), classMetadata.ModelType); + Assert.Equal(typeof(Person), classMetadata.ModelType); } [Fact] public void Metadata_ModelName_is_Null() { - Assert.Null(classMetadata.ModelName); -// Assert.Equal("Person", classMetadata.ModelName); + Assert.Null(classMetadata.ModelName); } [Fact] public void Metadata_Display_is_Benutzer() { - Assert.Equal("Benutzer", classMetadata.DisplayName); + Assert.Equal("Benutzer", classMetadata.GetDisplayName()); + } + + [Fact] + public void Instance_with_FirstName_different_from_LastName_is_invalid() + { + var rule = classMetadata.Rules.OfType>().Last(); + var person = new Person { FirstName = "foo", LastName = "bar" }; + Assert.False(rule.IsValid(person)); + } + + [Fact] + public void Instance_with_FirstName_equal_to_LastName_is_valid() + { + var rule = classMetadata.Rules.OfType>().Last(); + var person = new Person { FirstName = "foo", LastName = "foo" }; + Assert.True(rule.IsValid(person)); } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/ClassMetadata_with_WebUser.cs b/Source/FluentMetadata.Core.Specs/ClassMetadata_with_WebUser.cs index dba101d..30e0044 100644 --- a/Source/FluentMetadata.Core.Specs/ClassMetadata_with_WebUser.cs +++ b/Source/FluentMetadata.Core.Specs/ClassMetadata_with_WebUser.cs @@ -1,3 +1,6 @@ +using System; +using System.Linq; +using FluentMetadata.Rules; using FluentMetadata.Specs.SampleClasses; using Xunit; @@ -5,12 +8,11 @@ namespace FluentMetadata.Specs { public class ClassMetadata_with_WebUser : MetadataTestBase { - private Metadata classMetadata; + readonly Metadata classMetadata; public ClassMetadata_with_WebUser() { - var query = new QueryFluentMetadata(); - classMetadata = query.GetMetadataFor(typeof(WebUser)); + classMetadata = QueryFluentMetadata.GetMetadataFor(typeof(WebUser)); } [Fact] @@ -28,8 +30,36 @@ public void ModeType_is_WebUser() [Fact] public void DisplayName_is_Benutzer() { - Assert.Equal("Benutzer", classMetadata.DisplayName); + Assert.Equal("Benutzer", classMetadata.GetDisplayName()); } + [Fact] + public void Generic_name_rule_is_valid_when_Username_is_not_equal_to_AutorName() + { + var nameRule = classMetadata.Rules + .OfType>() + .Single(); + + var webUser = new WebUser(); + webUser.Username = "Holger"; + webUser.Autor = new Autor { Name = "Albert" }; + + Assert.True(nameRule.IsValid(webUser)); + } + + [Fact] + public void Generic_name_rule_is_invalid_when_Username_is_equal_to_AutorName() + { + var nameRule = classMetadata.Rules + .OfType>() + .Single(); + + var webUser = new WebUser(); + webUser.Username = "Holger"; + webUser.Autor = new Autor { Name = "Holger" }; + + Console.WriteLine(nameRule.FormatErrorMessage(classMetadata.GetDisplayName())); + Assert.False(nameRule.IsValid(webUser)); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/ClassMetadata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/ClassMetadata_with_WebUserIndexModel.cs index 7f888b2..9837cad 100644 --- a/Source/FluentMetadata.Core.Specs/ClassMetadata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/ClassMetadata_with_WebUserIndexModel.cs @@ -5,31 +5,17 @@ namespace FluentMetadata.Specs { public class ClassMetadata_with_WebUserIndexModel : MetadataTestBase { - private Metadata classMetadata; - - public ClassMetadata_with_WebUserIndexModel() - { - var query = new QueryFluentMetadata(); - classMetadata = query.GetMetadataFor(typeof(WebUserIndexModel)); - } - - [Fact] - public void ModelName_is_Null() - { - Assert.Null(classMetadata.ModelName); -// Assert.Equal("WebUserIndexModel", classMetadata.ModelName); - } - - [Fact] - public void ModeType_is_WebUserIndexModel() - { - Assert.Equal(typeof(WebUserIndexModel), classMetadata.ModelType); - } + private readonly Metadata classMetadata; + public ClassMetadata_with_WebUserIndexModel() { classMetadata = QueryFluentMetadata.GetMetadataFor(typeof(WebUserIndexModel)); } + [Fact] public void ModelName_is_Null() { Assert.Null(classMetadata.ModelName); } + [Fact] public void ModelType_is_WebUserIndexModel() { Assert.Equal(typeof(WebUserIndexModel), classMetadata.ModelType); } + [Fact] public void DisplayName_is_Benutzer() { Assert.Equal("Benutzer", classMetadata.GetDisplayName()); } + } - [Fact] - public void DisplayName_is_Benutzer() - { - Assert.Equal("Benutzer",classMetadata.DisplayName); - } + public class ClassMetadata_with_WebUserIndexGetModel : MetadataTestBase + { + private readonly Metadata classMetadata; + public ClassMetadata_with_WebUserIndexGetModel() { classMetadata = QueryFluentMetadata.GetMetadataFor(typeof(WebUserIndexGetModel)); } + [Fact] public void DisplayName_is_Benutzer() { Assert.Equal("Benutzer", classMetadata.GetDisplayName()); } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/Derive_Class_Tests.cs b/Source/FluentMetadata.Core.Specs/Derive_Class_Tests.cs index c2210bf..4937e16 100644 --- a/Source/FluentMetadata.Core.Specs/Derive_Class_Tests.cs +++ b/Source/FluentMetadata.Core.Specs/Derive_Class_Tests.cs @@ -5,12 +5,11 @@ namespace FluentMetadata.Specs { public class BaseClass_Tests : MetadataTestBase { - private Metadata id; + readonly Metadata id; public BaseClass_Tests() { - var query = new QueryFluentMetadata(); - id = query.GetMetadataFor(typeof(BaseClass), "Id"); + id = QueryFluentMetadata.GetMetadataFor(typeof(BaseClass), "Id"); } [Fact] @@ -20,17 +19,14 @@ public void Id_Required_is_True() } } - public class DerivedClass_Tests : MetadataTestBase { - private Metadata id; - private Metadata title; + readonly Metadata id, title; public DerivedClass_Tests() { - var query = new QueryFluentMetadata(); - id = query.GetMetadataFor(typeof (DerivedClass), "Id"); - title = query.GetMetadataFor(typeof(DerivedClass), "Title"); + id = QueryFluentMetadata.GetMetadataFor(typeof(DerivedClass), "Id"); + title = QueryFluentMetadata.GetMetadataFor(typeof(DerivedClass), "Title"); } [Fact] @@ -40,24 +36,20 @@ public void Title_Required_is_true() } [Fact] - public void Id_Required_is_True() { id.Required.Value.ShouldBeTrue(); } } - public class DerivedDerivedClass_Tests : MetadataTestBase { - private Metadata id; - private Metadata title; + readonly Metadata id, title; public DerivedDerivedClass_Tests() { - var query = new QueryFluentMetadata(); - id = query.GetMetadataFor(typeof(DerivedDerivedClass), "Id"); - title = query.GetMetadataFor(typeof(DerivedDerivedClass), "Title"); + id = QueryFluentMetadata.GetMetadataFor(typeof(DerivedDerivedClass), "Id"); + title = QueryFluentMetadata.GetMetadataFor(typeof(DerivedDerivedClass), "Title"); } [Fact] @@ -67,7 +59,6 @@ public void Title_Required_is_true() } [Fact] - public void Id_Required_is_True() { id.Required.Value.ShouldBeTrue(); diff --git a/Source/FluentMetadata.Core.Specs/DummyClass.cs b/Source/FluentMetadata.Core.Specs/DummyClass.cs index 6eac739..f8b55fc 100644 --- a/Source/FluentMetadata.Core.Specs/DummyClass.cs +++ b/Source/FluentMetadata.Core.Specs/DummyClass.cs @@ -2,6 +2,5 @@ { public class DummyClass { - } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/FluentMetadata.Core.Specs.csproj b/Source/FluentMetadata.Core.Specs/FluentMetadata.Core.Specs.csproj index e8a0055..b308b55 100644 --- a/Source/FluentMetadata.Core.Specs/FluentMetadata.Core.Specs.csproj +++ b/Source/FluentMetadata.Core.Specs/FluentMetadata.Core.Specs.csproj @@ -1,5 +1,6 @@  + Debug AnyCPU @@ -13,7 +14,8 @@ FluentMetadata.Core.Specs v4.0 512 - 0 + + 4.0 publish\ @@ -32,6 +34,8 @@ false true + + true @@ -77,19 +81,27 @@ + + + + - + + + + + @@ -127,7 +139,16 @@ true + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/FluentMetadata.EntityFramework.Specs/Content_Metadata_Tests.cs b/Source/FluentMetadata.EntityFramework.Specs/Content_Metadata_Tests.cs index 6a751b1..1654677 100644 --- a/Source/FluentMetadata.EntityFramework.Specs/Content_Metadata_Tests.cs +++ b/Source/FluentMetadata.EntityFramework.Specs/Content_Metadata_Tests.cs @@ -1,4 +1,3 @@ -using System; using FluentMetadata.EntityFramework.Specs.DomainObjects; using Xunit; @@ -6,12 +5,6 @@ namespace FluentMetadata.EntityFramework.Specs { public class Content_Metadata_Tests : IUseFixture { - private QueryFluentMetadata query; - - public Content_Metadata_Tests() - { - query = new QueryFluentMetadata(); - } public void SetFixture(MetadataSetup data) { } @@ -19,7 +12,7 @@ public void SetFixture(MetadataSetup data) [Fact] public void Content_Title_Is_Required() { - var metaData = query.GetMetadataFor(typeof (Content), "Title"); + var metaData = QueryFluentMetadata.GetMetadataFor(typeof(Content), "Title"); Assert.True(metaData.Required.Value); } } diff --git a/Source/FluentMetadata.EntityFramework.Specs/DbContextTest.cs b/Source/FluentMetadata.EntityFramework.Specs/DbContextTest.cs index ea6abff..b56a342 100644 --- a/Source/FluentMetadata.EntityFramework.Specs/DbContextTest.cs +++ b/Source/FluentMetadata.EntityFramework.Specs/DbContextTest.cs @@ -1,7 +1,4 @@ -using System; using System.Data.Entity; -using System.Data.Entity.Infrastructure; -using System.Data.Entity.ModelConfiguration; using System.IO; using Xunit; @@ -11,7 +8,7 @@ public class DbContextTest : IUseFixture { public DbContextTest() { - Database.SetInitializer(new AlwaysRecreateDatabase()); + Database.SetInitializer(new DropCreateDatabaseAlways()); } [Fact] @@ -33,7 +30,6 @@ public class NoDatabaseCreate : IDatabaseInitializer where T : DbContext { public void InitializeDatabase(T context) { - } } } \ No newline at end of file diff --git a/Source/FluentMetadata.EntityFramework.Specs/DomainObjects/DomainObject.cs b/Source/FluentMetadata.EntityFramework.Specs/DomainObjects/DomainObject.cs index 6844d77..69ea27b 100644 --- a/Source/FluentMetadata.EntityFramework.Specs/DomainObjects/DomainObject.cs +++ b/Source/FluentMetadata.EntityFramework.Specs/DomainObjects/DomainObject.cs @@ -6,16 +6,16 @@ public abstract class DomainObject : IInitializable { protected DomainObject() { - + } public virtual void Initialize() { Created = DateTime.UtcNow; - Updated = Created; + Updated = Created; } - public int Id { get; private set; } + public int Id { get; private set; } - public DateTime Created { get; private set; } + public DateTime Created { get; private set; } public DateTime Updated { get; private set; } @@ -40,14 +40,15 @@ public override bool Equals(object obj) { return true; } - if (!typeof(DomainObject).IsAssignableFrom(obj.GetType())) + if (!(obj is DomainObject)) { return false; } - return Equals((DomainObject) obj); + return Equals((DomainObject)obj); } - public override int GetHashCode() { + public override int GetHashCode() + { return string.Format("{0}({1})", GetType().Name, Id).GetHashCode(); } diff --git a/Source/FluentMetadata.EntityFramework.Specs/DomainObjects/WebUser.cs b/Source/FluentMetadata.EntityFramework.Specs/DomainObjects/WebUser.cs index 03a5b4d..820a48f 100644 --- a/Source/FluentMetadata.EntityFramework.Specs/DomainObjects/WebUser.cs +++ b/Source/FluentMetadata.EntityFramework.Specs/DomainObjects/WebUser.cs @@ -1,10 +1,19 @@ using System; -using System.Globalization; namespace FluentMetadata.EntityFramework.Specs.DomainObjects { public class WebUser : DomainObject { + public string Username { get; private set; } + public string EMail { get; private set; } + public string PasswordHash { get; private set; } + public bool Confirmed { get; private set; } + public bool Active { get; private set; } + public int BounceCount { get; private set; } + public DateTime? LastLogin { get; private set; } + public Guid? ConfirmationKey { get; private set; } + public string Role { get; private set; } + private WebUser() { } @@ -16,23 +25,11 @@ public override void Initialize() Confirmed = false; Active = false; } - public string Username { get; private set; } - - public string EMail { get; private set; } - - public string PasswordHash { get; private set; } - public bool Confirmed { get; private set; } - public bool Active { get; private set; } - - public int BounceCount { get; private set; } - public DateTime? LastLogin { get; private set; } - public Guid? ConfirmationKey { get; private set; } - public string Role { get; private set; } - public void SetEMailAddress(string emailAddress) { emailAddress = emailAddress.ToLower(); + if (string.CompareOrdinal(EMail, emailAddress) != 0) { EMail = emailAddress; @@ -40,7 +37,6 @@ public void SetEMailAddress(string emailAddress) } } - public void Activate() { Active = true; @@ -73,10 +69,10 @@ public void EnsureConfirmationKey() { return; } + ConfirmationKey = Guid.NewGuid(); } - public void LoggedIn() { LastLogin = DateTime.UtcNow; @@ -85,11 +81,13 @@ public void LoggedIn() public bool ConfirmationKeyIsValid(Guid confirmationKey) { - bool isValid = false; + var isValid = false; + if (ConfirmationKey.HasValue) { isValid = ConfirmationKey.Value == confirmationKey; } + return isValid; } @@ -100,8 +98,8 @@ public void SetUsername(string userName) Username = userName; return; } + throw new InvalidOperationException("Username is already set"); } - } } \ No newline at end of file diff --git a/Source/FluentMetadata.EntityFramework.Specs/EntityFrameworkAdapterTests.cs b/Source/FluentMetadata.EntityFramework.Specs/EntityFrameworkAdapterTests.cs index 41c5bdd..52321c6 100644 --- a/Source/FluentMetadata.EntityFramework.Specs/EntityFrameworkAdapterTests.cs +++ b/Source/FluentMetadata.EntityFramework.Specs/EntityFrameworkAdapterTests.cs @@ -1,40 +1,37 @@ -using System.Data.Entity.ModelConfiguration; +using System.Data.Entity; using FluentMetadata.EntityFramework.Specs.DomainObjects; using Xunit; namespace FluentMetadata.EntityFramework.Specs { + //TODO reinclude tests after updating to newest version of Entity Framework public class EntityFrameworkAdapterTests { - private ModelBuilder modelBuilder; + private DbModelBuilder modelBuilder; private EntityFrameworkAdapter adapter; public EntityFrameworkAdapterTests() { - modelBuilder = new ModelBuilder(); + modelBuilder = new DbModelBuilder(); adapter = new EntityFrameworkAdapter(); } - [Fact] + [Fact(Skip = "This test was written against an outdated version of Entity Framework")] public void Can_Map_WebUser() { - var configuration = modelBuilder.Entity(); - adapter.MapProperties(typeof(WebUser),configuration); + adapter.MapProperties(modelBuilder.Entity()); } - [Fact] + [Fact(Skip = "This test was written against an outdated version of Entity Framework")] public void Can_Map_Content() { - var configuration = modelBuilder.Entity(); - adapter.MapProperties(typeof(Content), configuration); + adapter.MapProperties(modelBuilder.Entity()); } - [Fact] + [Fact(Skip = "This test was written against an outdated version of Entity Framework")] public void Can_Map_Layout() { - var configuration = modelBuilder.Entity(); - adapter.MapProperties(typeof(Layout), configuration); + adapter.MapProperties(modelBuilder.Entity()); } - } } \ No newline at end of file diff --git a/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_ContentBase_Tests.cs b/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_ContentBase_Tests.cs index 1faee08..9546c1b 100644 --- a/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_ContentBase_Tests.cs +++ b/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_ContentBase_Tests.cs @@ -6,48 +6,40 @@ namespace FluentMetadata.EntityFramework.Specs { public class ExpressionGenerator_with_ContentBase_Tests { - private readonly ExpressionGenerator generator; - - public ExpressionGenerator_with_ContentBase_Tests() - { - generator=new ExpressionGenerator(); - } - - [Fact] public void Generate_for_Id() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(ContentBase), "Id")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(ContentBase), "Id")); } [Fact] public void Generate_for_Created() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(ContentBase), "Created")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(ContentBase), "Created")); } [Fact] public void Generate_for_Title() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(ContentBase), "Title")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(ContentBase), "Title")); } [Fact] public void Generate_for_Author() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(ContentBase), "Author")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(ContentBase), "Author")); } [Fact] public void Generate_for_Comments() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(ContentBase), "Comments")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(ContentBase), "Comments")); } [Fact] public void Generate_for_Layout() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(ContentBase), "Layout")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(ContentBase), "Layout")); } } } \ No newline at end of file diff --git a/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_Content_Tests.cs b/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_Content_Tests.cs index f3ca29a..8c6df52 100644 --- a/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_Content_Tests.cs +++ b/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_Content_Tests.cs @@ -6,51 +6,40 @@ namespace FluentMetadata.EntityFramework.Specs { public class ExpressionGenerator_with_Content_Tests { - private readonly ExpressionGenerator generator; - - public ExpressionGenerator_with_Content_Tests() - { - generator=new ExpressionGenerator(); - } - - [Fact] public void Generate_for_Id() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(Content), "Id")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(Content), "Id")); } [Fact] public void Generate_for_Created() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(Content), "Created")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(Content), "Created")); } [Fact] public void Generate_for_Title() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(Content), "Title")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(Content), "Title")); } - - [Fact] public void Generate_for_Author() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(Content),"Author")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(Content), "Author")); } [Fact] public void Generate_for_Comments() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(Content), "Comments")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(Content), "Comments")); } [Fact] public void Generate_for_WebSite() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(Content), "WebSite")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(Content), "WebSite")); } - } } \ No newline at end of file diff --git a/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_WebUser_Tests.cs b/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_WebUser_Tests.cs index 437467f..239d02d 100644 --- a/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_WebUser_Tests.cs +++ b/Source/FluentMetadata.EntityFramework.Specs/ExpressionGenerator_with_WebUser_Tests.cs @@ -6,42 +6,34 @@ namespace FluentMetadata.EntityFramework.Specs { public class ExpressionGenerator_with_WebUser_Tests { - private readonly ExpressionGenerator generator; - - public ExpressionGenerator_with_WebUser_Tests() - { - generator=new ExpressionGenerator(); - } - [Fact] public void Generate_for_Username() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(WebUser),"Username")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(WebUser), "Username")); } [Fact] public void Wont_Generate_for_Dummy() { - Assert.Null(generator.CreateExpressionForProperty(typeof(WebUser), "Dummy")); + Assert.Null(ExpressionGenerator.CreateExpressionForProperty(typeof(WebUser), "Dummy")); } [Fact] public void Generate_for_BountCount() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(WebUser), "Confirmed")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(WebUser), "Confirmed")); } [Fact] public void Generate_for_LastLogin() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(WebUser), "LastLogin")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(WebUser), "LastLogin")); } [Fact] public void Generate_for_ConfirmationKey() { - Assert.NotNull(generator.CreateExpressionForProperty(typeof(WebUser), "ConfirmationKey")); + Assert.NotNull(ExpressionGenerator.CreateExpressionForProperty(typeof(WebUser), "ConfirmationKey")); } - } } \ No newline at end of file diff --git a/Source/FluentMetadata.EntityFramework.Specs/FluentMetadata.EntityFramework.Specs.csproj b/Source/FluentMetadata.EntityFramework.Specs/FluentMetadata.EntityFramework.Specs.csproj index 19c0bdd..e23174c 100644 --- a/Source/FluentMetadata.EntityFramework.Specs/FluentMetadata.EntityFramework.Specs.csproj +++ b/Source/FluentMetadata.EntityFramework.Specs/FluentMetadata.EntityFramework.Specs.csproj @@ -1,5 +1,6 @@  + Debug AnyCPU @@ -13,6 +14,25 @@ FluentMetadata.EntityFramework.Specs v4.0 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + ..\ + true + + true @@ -22,6 +42,7 @@ DEBUG;TRACE prompt 4 + AllRules.ruleset pdbonly @@ -30,13 +51,18 @@ TRACE prompt 4 + AllRules.ruleset - + + ..\packages\EntityFramework.6.0.1\lib\net40\EntityFramework.dll + + + ..\packages\EntityFramework.6.0.1\lib\net40\EntityFramework.SqlServer.dll + - @@ -94,6 +120,7 @@ Always + @@ -105,7 +132,36 @@ FluentMetadata.EntityFramework + + + False + Microsoft .NET Framework 4 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 3.1 + true + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + \ No newline at end of file diff --git a/Source/FluentMetadata.EntityFramework/EntityFrameworkAdapter.cs b/Source/FluentMetadata.EntityFramework/EntityFrameworkAdapter.cs index c6f55fe..95cb26c 100644 --- a/Source/FluentMetadata.EntityFramework/EntityFrameworkAdapter.cs +++ b/Source/FluentMetadata.EntityFramework/EntityFrameworkAdapter.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Data.Entity.ModelConfiguration; +using System.Data.Entity.ModelConfiguration.Configuration; using FluentMetadata.EntityFramework.Internal; using FluentMetadata.EntityFramework.Internal.ConfigurationAdapters; @@ -8,24 +6,11 @@ namespace FluentMetadata.EntityFramework { public class EntityFrameworkAdapter { - private readonly QueryFluentMetadata query = new QueryFluentMetadata(); - private readonly ExpressionGenerator generator = new ExpressionGenerator(); - private readonly PropertyMethodMapping methodMapping = new PropertyMethodMapping(); + readonly ConfigurationAdapterFactory factory = new ConfigurationAdapterFactory(); - private readonly ConfigurationAdapterFactory factory = new ConfigurationAdapterFactory(); - - public void MapProperties(IEnumerable configurations) - { - foreach (var configuration in configurations) - { - Type instanceType = configuration.GetType().GetGenericArguments()[0]; - MapProperties(instanceType, configuration); - } - } - - internal void MapProperties(Type instanceType, StructuralTypeConfiguration configuration) + internal void MapProperties(StructuralTypeConfiguration configuration) where T : class { - var metaDatas = query.GetMetadataFor(instanceType).Properties; + var metaDatas = QueryFluentMetadata.GetMetadataFor(typeof(T)).Properties; foreach (var data in metaDatas) { @@ -33,21 +18,23 @@ internal void MapProperties(Type instanceType, StructuralTypeConfiguration confi { continue; } - if (!data.StringLength.HasValue && !data.Required.HasValue) + if (!data.GetMaximumLength().HasValue && !data.Required.HasValue) { continue; } - var methodInfo = methodMapping.GetPropertyMappingMethod(configuration.GetType(), instanceType, - data.ModelType); + var methodInfo = PropertyMethodMapping.GetPropertyMappingMethod( + configuration.GetType(), + typeof(T), + data.ModelType); if (methodInfo == null) { continue; } - var lambda = generator.CreateExpressionForProperty(instanceType, data.ModelName); + var lambda = ExpressionGenerator.CreateExpressionForProperty(typeof(T), data.ModelName); if (lambda != null) { - var propertyConfiguration = (PropertyConfiguration) methodInfo.Invoke(configuration, new[] {lambda}); + var propertyConfiguration = (PrimitivePropertyConfiguration)methodInfo.Invoke(configuration, new[] { lambda }); factory.Create(propertyConfiguration).Convert(data, propertyConfiguration); } diff --git a/Source/FluentMetadata.EntityFramework/FluentMetadata.EntityFramework.csproj b/Source/FluentMetadata.EntityFramework/FluentMetadata.EntityFramework.csproj index 1b98ecf..9a99cc5 100644 --- a/Source/FluentMetadata.EntityFramework/FluentMetadata.EntityFramework.csproj +++ b/Source/FluentMetadata.EntityFramework/FluentMetadata.EntityFramework.csproj @@ -12,6 +12,23 @@ FluentMetadata.EntityFramework v4.0 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + ..\ + true true @@ -21,6 +38,8 @@ DEBUG;TRACE prompt 4 + AllRules.ruleset + bin\Debug\FluentMetadata.EntityFramework.XML pdbonly @@ -29,13 +48,18 @@ TRACE prompt 4 + AllRules.ruleset + bin\Release\FluentMetadata.EntityFramework.XML - - False - ..\..\external\EntityFramework\Microsoft.Data.Entity.CTP.dll + + ..\packages\EntityFramework.6.0.1\lib\net40\EntityFramework.dll + + + ..\packages\EntityFramework.6.0.1\lib\net40\EntityFramework.SqlServer.dll + @@ -64,7 +88,34 @@ FluentMetadata.Core + + + False + Microsoft .NET Framework 4 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 3.1 + true + + + + + + + + \ No newline at end of file diff --git a/Source/FluentMetadata.FluentNHibernate.Specs/Properties/AssemblyInfo.cs b/Source/FluentMetadata.FluentNHibernate.Specs/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9e3ce2b --- /dev/null +++ b/Source/FluentMetadata.FluentNHibernate.Specs/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("FluentMetadata.FluentNHibernate.Specs")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("FluentMetadata.FluentNHibernate.Specs")] +[assembly: AssemblyCopyright("Copyright © 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("bc0543ee-1db5-4a27-bb0b-073ebbc5a070")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Source/FluentMetadata.FluentNHibernate.Specs/app.config b/Source/FluentMetadata.FluentNHibernate.Specs/app.config new file mode 100644 index 0000000..b6fcbe2 --- /dev/null +++ b/Source/FluentMetadata.FluentNHibernate.Specs/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Source/FluentMetadata.FluentNHibernate.Specs/packages.config b/Source/FluentMetadata.FluentNHibernate.Specs/packages.config new file mode 100644 index 0000000..ea488db --- /dev/null +++ b/Source/FluentMetadata.FluentNHibernate.Specs/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Source/FluentMetadata.FluentNHibernate/Conventions/FluentMetaDataConvention.cs b/Source/FluentMetadata.FluentNHibernate/Conventions/FluentMetaDataConvention.cs index 8d496e8..8209629 100644 --- a/Source/FluentMetadata.FluentNHibernate/Conventions/FluentMetaDataConvention.cs +++ b/Source/FluentMetadata.FluentNHibernate/Conventions/FluentMetaDataConvention.cs @@ -3,35 +3,35 @@ namespace FluentMetadata.FluentNHibernate.Conventions { - public class FluentMetaDataConvention : IPropertyConvention + public class FluentMetadataConvention : IPropertyConvention, IReferenceConvention { - private readonly QueryFluentMetadata query = new QueryFluentMetadata(); public void Apply(IPropertyInstance instance) { - var meta = query.GetMetadataFor(instance.EntityType,instance.Property.Name); - if (meta.Required.HasValue) - { - ApplyRequired(meta.Required.Value, instance); - } - if (meta.StringLength.HasValue) - { - ApplyStringLength(meta.StringLength.Value, instance); - } - } + var meta = QueryFluentMetadata.FindMetadataFor(instance.EntityType, instance.Property.Name); - private static void ApplyStringLength(int stringLength, IPropertyInstance target) - { - if (stringLength > 0) + if (meta != null) { - target.Length(stringLength); + if (meta.Required.HasValue && meta.Required.Value) + { + instance.Not.Nullable(); + } + + var maxLength = meta.GetMaximumLength(); + + if (maxLength.HasValue && maxLength.Value > 0) + { + instance.Length(maxLength.Value); + } } } - private static void ApplyRequired(bool required, IPropertyInstance target) + public void Apply(IManyToOneInstance instance) { - if (required) + var meta = QueryFluentMetadata.FindMetadataFor(instance.EntityType, instance.Property.Name); + + if (meta != null && meta.Required.HasValue && meta.Required.Value) { - target.Not.Nullable(); + instance.Not.Nullable(); } } } diff --git a/Source/FluentMetadata.FluentNHibernate/FluentMetadata.FluentNHibernate.csproj b/Source/FluentMetadata.FluentNHibernate/FluentMetadata.FluentNHibernate.csproj index 36d7301..33afc85 100644 --- a/Source/FluentMetadata.FluentNHibernate/FluentMetadata.FluentNHibernate.csproj +++ b/Source/FluentMetadata.FluentNHibernate/FluentMetadata.FluentNHibernate.csproj @@ -32,6 +32,8 @@ false true + ..\ + true true @@ -42,6 +44,7 @@ prompt 4 AllRules.ruleset + bin\Debug\FluentMetadata.FluentNHibernate.XML pdbonly @@ -51,11 +54,19 @@ prompt 4 AllRules.ruleset + bin\Release\FluentMetadata.FluentNHibernate.XML - + + ..\packages\FluentNHibernate.1.3.0.733\lib\FluentNHibernate.dll + + + False + ..\packages\Iesi.Collections.3.3.3.4001\lib\Net35\Iesi.Collections.dll + + False - ..\..\external\NHibernate\Additional\FluentNHibernate.dll + ..\packages\NHibernate.3.3.3.4001\lib\Net35\NHibernate.dll @@ -74,7 +85,7 @@ Properties\GlobalAssemblyInfo.cs - + @@ -100,7 +111,11 @@ true + + + +