From 53e8df9bee772ccddbb70c3c0280fd5f66628e4b Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Fri, 25 Mar 2011 19:49:59 +0100 Subject: [PATCH 01/56] fixed Error message of StringLengthRule --- Source/FluentMetadata.Core/Rules/StringLengthRule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/FluentMetadata.Core/Rules/StringLengthRule.cs b/Source/FluentMetadata.Core/Rules/StringLengthRule.cs index 71d0c58..b39b5aa 100644 --- a/Source/FluentMetadata.Core/Rules/StringLengthRule.cs +++ b/Source/FluentMetadata.Core/Rules/StringLengthRule.cs @@ -8,7 +8,7 @@ public class StringLengthRule : Rule private readonly int maxLength; public StringLengthRule(int maxLength) - : base("the string for {0} should be longer than {1} characters") + : base("the string for {0} should not be longer than {1} characters") { this.maxLength = maxLength; } From 92741b58bf58f17be99297cafe8d30afd3e50c4c Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Tue, 29 Mar 2011 15:45:35 +0200 Subject: [PATCH 02/56] renamed ConcernOfComparingComplexModelMetadata to ConcernOfComparingMetadata to match class name --- ...ingComplexModelMetadata.cs => ConcernOfComparingMetadata.cs} | 0 Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename Source/FluentMetadata.MVC.Specs/{ConcernOfComparingComplexModelMetadata.cs => ConcernOfComparingMetadata.cs} (100%) diff --git a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingComplexModelMetadata.cs b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs similarity index 100% rename from Source/FluentMetadata.MVC.Specs/ConcernOfComparingComplexModelMetadata.cs rename to Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs diff --git a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj index dcc0914..8411234 100644 --- a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj +++ b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj @@ -54,7 +54,7 @@ - + From bab48926daa6adf624a571024833404e36e0fbce Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Tue, 29 Mar 2011 18:13:46 +0200 Subject: [PATCH 03/56] changed reference to System.Web.Mvc from relative HintPath to GAC preventing the test runner from crashing if the reference is not found --- .../FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj index 8411234..3dc199d 100644 --- a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj +++ b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj @@ -35,10 +35,7 @@ - - False - ..\..\..\..\..\Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC 2\Assemblies\System.Web.Mvc.dll - + From aa44a44d6e5f6a2c9eff0266a4f1612c6c67d556 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 4 Apr 2011 18:52:07 +0200 Subject: [PATCH 04/56] fixing psake by running tests using xunit.console.clr4.exe --- default.ps1 | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/default.ps1 b/default.ps1 index 841a8cc..a560e53 100644 --- a/default.ps1 +++ b/default.ps1 @@ -38,13 +38,10 @@ task Compile -depends Init { copy-item readme.txt $build_dir\readme.txt } -task Test20 -depends Compile { - exec { & $tools_dir\xUnit\xunit.console.exe $build_dir\FluentMetadata.Core.Specs.dll } - exec { & $tools_dir\xUnit\xunit.console.exe $build_dir\FluentMetadata.MVC.Specs.dll } -} - -task Test40 -depends Test20 { +task Test40 -depends Compile { exec { & $tools_dir\xUnit\xunit.console.clr4.exe $build_dir\FluentMetadata.EntityFramework.Specs.dll } + exec { & $tools_dir\xUnit\xunit.console.clr4.exe $build_dir\FluentMetadata.Core.Specs.dll } + exec { & $tools_dir\xUnit\xunit.console.clr4.exe $build_dir\FluentMetadata.MVC.Specs.dll } } task Test -depends Test40 From 86dee292c07aa07000d680d15c2af629d9f0a1f8 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 4 Apr 2011 18:52:38 +0200 Subject: [PATCH 05/56] skipping test requiring EF to be installed --- .../FluentMetadata.EntityFramework.Specs/DbContextTest.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/FluentMetadata.EntityFramework.Specs/DbContextTest.cs b/Source/FluentMetadata.EntityFramework.Specs/DbContextTest.cs index ea6abff..f60b0bd 100644 --- a/Source/FluentMetadata.EntityFramework.Specs/DbContextTest.cs +++ b/Source/FluentMetadata.EntityFramework.Specs/DbContextTest.cs @@ -1,7 +1,5 @@ -using System; using System.Data.Entity; using System.Data.Entity.Infrastructure; -using System.Data.Entity.ModelConfiguration; using System.IO; using Xunit; @@ -14,7 +12,8 @@ public DbContextTest() Database.SetInitializer(new AlwaysRecreateDatabase()); } - [Fact] + //TODO refactor this test. It breaks the build if Entity Framework is not installed + [Fact(Skip = "This test requires Entity Framework to be installed")] public void CanCreateDbContext() { if (File.Exists("TestDatabase.sdf")) @@ -33,7 +32,6 @@ public class NoDatabaseCreate : IDatabaseInitializer where T : DbContext { public void InitializeDatabase(T context) { - } } } \ No newline at end of file From bd9cf4b53ed3a2f5aca0febe08292075f11956be Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 4 Apr 2011 19:42:47 +0200 Subject: [PATCH 06/56] remove unused variable --- .../Builder/ClassMetadataBuilder.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Source/FluentMetadata.Core/Builder/ClassMetadataBuilder.cs b/Source/FluentMetadata.Core/Builder/ClassMetadataBuilder.cs index f6bb82b..5e5b51c 100644 --- a/Source/FluentMetadata.Core/Builder/ClassMetadataBuilder.cs +++ b/Source/FluentMetadata.Core/Builder/ClassMetadataBuilder.cs @@ -1,5 +1,3 @@ -using System; - namespace FluentMetadata.Builder { internal class ClassMetadataBuilder : IClassBuilder @@ -11,18 +9,16 @@ internal class ClassMetadataBuilder : IClassBuilder public ClassMetadataBuilder(Metadata metadata) { this.metadata = metadata; - metadata.ModelType = typeof (T); -// metadata.ModelName = typeof (T).Name; + metadata.ModelType = typeof(T); InitPropertyMetadata(); } private void InitPropertyMetadata() { - string a; - var builder = FluentMetadataBuilder.GetTypeBuilder(typeof (T)); - foreach (var propertyInfo in typeof (T).GetProperties()) + var builder = FluentMetadataBuilder.GetTypeBuilder(typeof(T)); + foreach (var propertyInfo in typeof(T).GetProperties()) { - if (propertyInfo.GetIndexParameters().Length==0) + if (propertyInfo.GetIndexParameters().Length == 0) { var propertyMetadata = builder.MapProperty(typeof(T), propertyInfo.Name, propertyInfo.PropertyType); metadata.Properties.Add(propertyMetadata); From 23538774949269acf38af560ff79d90a5196b57c Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 18 Apr 2011 12:52:52 +0200 Subject: [PATCH 07/56] corrected ErrorMessageFormat of RangeRule and parameter order of exception message --- Source/FluentMetadata.Core/Rules/RangeRule.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Source/FluentMetadata.Core/Rules/RangeRule.cs b/Source/FluentMetadata.Core/Rules/RangeRule.cs index ebca20a..9507f3c 100644 --- a/Source/FluentMetadata.Core/Rules/RangeRule.cs +++ b/Source/FluentMetadata.Core/Rules/RangeRule.cs @@ -10,16 +10,18 @@ public class RangeRule : Rule private object valueMinimum; private RangeRule() - : base("the value of {0} must be between {0} and {1}") + : base("the value of '{0}' must be between {1} and {2}") { } - public RangeRule(double minimum, double maximum) : this() + public RangeRule(double minimum, double maximum) + : this() { Initialize(minimum, maximum, o => Convert.ToDouble(o)); } - public RangeRule(int minimum, int maximum) : this() + public RangeRule(int minimum, int maximum) + : this() { Initialize(minimum, maximum, o => Convert.ToInt32(o)); } @@ -36,7 +38,7 @@ private void Initialize(IComparable minimum, IComparable maximum, Func= 0)); } From 4508bad4a4ed936665629df336e0c2e5dbedbbb7 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 18 Apr 2011 17:44:45 +0200 Subject: [PATCH 08/56] updated gitignore with UpgradeReport files & *.orig files from KDiff3 merge tool --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 256b66e..6ac084c 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,7 @@ _ReSharper*/ *.vs10x Source/Gallio Reports -Source/TestResults \ No newline at end of file +Source/TestResults +Source/_UpgradeReport_Files/ +*.orig +Source/UpgradeLog* \ No newline at end of file From 9a36a8fc9342fe885feb681b379e569e3cb5a4ef Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Tue, 19 Apr 2011 14:37:49 +0200 Subject: [PATCH 09/56] fixed ClassRuleModelValidator.Validate method to use Metadata.Model as validated object because System.Web.Mvc.DefaultModelBinder passes null as the moethod's container parameter --- Source/FluentMetadata.MVC/RuleModelValidator.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/FluentMetadata.MVC/RuleModelValidator.cs b/Source/FluentMetadata.MVC/RuleModelValidator.cs index 2aefa6c..9698943 100644 --- a/Source/FluentMetadata.MVC/RuleModelValidator.cs +++ b/Source/FluentMetadata.MVC/RuleModelValidator.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Web.Mvc; using FluentMetadata.Rules; @@ -45,9 +44,11 @@ public ClassRuleModelValidator(IClassRule rule, ModelMetadata metadata, Controll this.rule = rule; } + // TODO: write a test for this method using System.Web.Mvc.DefaultModelBinder.BindModel public override IEnumerable Validate(object container) { - if (rule.IsValid(container)) + // container is useless because System.Web.Mvc.DefaultModelBinder passes null for it + if (rule.IsValid(container ?? Metadata.Model)) { yield break; } From 9874f1aef07608281c27ceffeb5828d9fc2f7d15 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 18:07:47 +0200 Subject: [PATCH 10/56] fixed comments --- Source/FluentMetadata.Core/MetaData.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 2d77d9c..85d5914 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -258,7 +258,7 @@ internal void CopyMetaDataFrom(Metadata metadata) // TODO MVC2 public virtual string SimpleDisplayText { get; set; } /// - /// Gets or sets the template hint. + /// Gets or sets a hint that suggests what template to use for this model. /// /// /// A hint that suggests what template to use for this model. @@ -266,7 +266,7 @@ internal void CopyMetaDataFrom(Metadata metadata) public string TemplateHint { get; set; } /// - /// Gets or sets a hint that suggests what template to use for this model. + /// Gets or sets a value that can be used as a watermark. /// /// /// The watermark. From 3d71c469085fe05de98d5b1de19770ac94f6b47b Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 28 Mar 2011 18:35:12 +0200 Subject: [PATCH 11/56] added ConvertEmptyStringToNull property to Metadata --- Source/FluentMetadata.Core/Builder/IsBuilder.cs | 11 +++++++++-- Source/FluentMetadata.Core/IIsProperty.cs | 12 +++++------- Source/FluentMetadata.Core/MetaData.cs | 11 ++++++++++- Source/FluentMetadata.MVC.Specs/ComplexModel.cs | 6 ++++-- .../FluentMetadata.MVC.Specs.csproj | 1 + Source/FluentMetadata.MVC/MetadataMapper.cs | 1 + 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Source/FluentMetadata.Core/Builder/IsBuilder.cs b/Source/FluentMetadata.Core/Builder/IsBuilder.cs index d6b5899..a87cad7 100644 --- a/Source/FluentMetadata.Core/Builder/IsBuilder.cs +++ b/Source/FluentMetadata.Core/Builder/IsBuilder.cs @@ -17,7 +17,7 @@ public IsBuilder(PropertyMetadataBuilder propertyMetaDataBuilder) this.propertyMetaDataBuilder = propertyMetaDataBuilder; } - public IProperty Required() + public IProperty Required() { Metadata.Required = !notted; notted = false; @@ -28,7 +28,7 @@ public IProperty Required() return propertyMetaDataBuilder; } - public IProperty ReadOnly() + public IProperty ReadOnly() { Metadata.Readonly = !notted; notted = false; @@ -44,5 +44,12 @@ public IIsNotProperty Not return this; } } + + public IProperty ConvertEmptyStringToNull() + { + Metadata.ConvertEmptyStringToNull = !notted; + notted = false; + return propertyMetaDataBuilder; + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/IIsProperty.cs b/Source/FluentMetadata.Core/IIsProperty.cs index d7b9cdf..a698d97 100644 --- a/Source/FluentMetadata.Core/IIsProperty.cs +++ b/Source/FluentMetadata.Core/IIsProperty.cs @@ -1,16 +1,14 @@ -using System; -using System.Linq.Expressions; - -namespace FluentMetadata +namespace FluentMetadata { public interface IIsProperty : IIsNotProperty { IIsNotProperty Not { get; } } - public interface IIsNotProperty + public interface IIsNotProperty { - IProperty Required(); - IProperty ReadOnly(); + IProperty Required(); + IProperty ReadOnly(); + IProperty ConvertEmptyStringToNull(); } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 85d5914..61d9abb 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -11,6 +11,7 @@ public class Metadata public Metadata() { + ConvertEmptyStringToNull = true; ShowDisplay = true; ShowEditor = true; rules = new List(); @@ -71,7 +72,15 @@ internal void CopyMetaDataFrom(Metadata metadata) // Returns: // true if empty strings that are posted back in forms should be converted to // null; otherwise, false. The default value is true. - // TODO MVC2 public virtual bool ConvertEmptyStringToNull { get; set; } + /// + /// Gets or sets a value that indicates whether empty strings that are posted + /// back in forms should be converted to null. + /// + /// + /// true if empty strings that are posted back in forms should be + /// converted to null; otherwise, false. The default value is true + /// + public bool ConvertEmptyStringToNull { get; set; } // ~ System.Web.Mvc.ModelMetadata.DataTypeName /// diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index f406e48..be283a0 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -1,19 +1,21 @@ using System.ComponentModel; +using System.ComponentModel.DataAnnotations; namespace FluentMetadata.MVC.Specs { - public class ComplexModelMetadata:ClassMetadata + public class ComplexModelMetadata : ClassMetadata { public ComplexModelMetadata() { Class.Display.Name("Komplex"); - Property(e => e.FirstName).Display.Name("Vorname"); + Property(e => e.FirstName).Display.Name("Vorname").Is.Not.ConvertEmptyStringToNull(); } } [DisplayName("Komplex")] public class ComplexModel { [DisplayName("Vorname")] + [DisplayFormat(ConvertEmptyStringToNull = false)] public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } diff --git a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj index 3dc199d..f62e069 100644 --- a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj +++ b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj @@ -34,6 +34,7 @@ + diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index 6306063..265674e 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -9,6 +9,7 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) destination.DisplayName = source.DisplayName; destination.ShowForDisplay = source.ShowDisplay; destination.DataTypeName = GetDataTypeName(source); + destination.ConvertEmptyStringToNull = source.ConvertEmptyStringToNull; } private static string GetDataTypeName(Metadata metadata) From 491810a5e8ada07e93f463602d55b9fafd3e6ffe Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Tue, 29 Mar 2011 15:43:42 +0200 Subject: [PATCH 12/56] just clarified tasks --- Source/FluentMetadata.Core/MetaData.cs | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 61d9abb..01c584a 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -53,7 +53,7 @@ internal void CopyMetaDataFrom(Metadata metadata) // // Returns: // A dictionary that contains additional metadata about the model. - // TODO MVC2 public virtual Dictionary AdditionalValues { get; } + // TODO MVC2 [in order to complete properties corresponding to System.Web.Mvc.ModelMetadata] public virtual Dictionary AdditionalValues { get; } // ~ System.Web.Mvc.ModelMetadata.ContainerType /// @@ -64,14 +64,6 @@ internal void CopyMetaDataFrom(Metadata metadata) /// public Type ContainerType { get; set; } - // - // Summary: - // Gets or sets a value that indicates whether empty strings that are posted - // back in forms should be converted to null. - // - // Returns: - // true if empty strings that are posted back in forms should be converted to - // null; otherwise, false. The default value is true. /// /// Gets or sets a value that indicates whether empty strings that are posted /// back in forms should be converted to null. @@ -145,7 +137,7 @@ internal void CopyMetaDataFrom(Metadata metadata) // Returns: // A value that indicates whether the model is considered a complex type by // the MVC framework. - // TODO MVC2 ? public virtual bool IsComplexType { get; } + // TODO MVC2 [in order to complete properties corresponding to System.Web.Mvc.ModelMetadata] public virtual bool IsComplexType { get; } // // Summary: @@ -153,7 +145,7 @@ internal void CopyMetaDataFrom(Metadata metadata) // // Returns: // true if the type is nullable; otherwise, false. - // TODO MVC2 ? public bool IsNullableValueType { get; } + // TODO MVC2 [in order to complete properties corresponding to System.Web.Mvc.ModelMetadata] public bool IsNullableValueType { get; } // ~ System.Web.Mvc.ModelMetadata.IsReadOnly /// @@ -181,7 +173,7 @@ internal void CopyMetaDataFrom(Metadata metadata) // The value of the model. For more information about System.Web.Mvc.ModelMetadata, // see the entry ASP.NET MVC 2 Templates, Part 2: ModelMetadata on Brad Wilson's // blog - // TODO MVC2 ? public object Model { get; set; } + // TODO MVC2 [in order to complete properties corresponding to System.Web.Mvc.ModelMetadata] public object Model { get; set; } // ~ System.Web.Mvc.ModelMetadata.ModelType /// @@ -207,7 +199,7 @@ internal void CopyMetaDataFrom(Metadata metadata) // // Returns: // The order value of the current metadata. - // TODO MVC3 public virtual int Order { get; set; } + // TODO MVC3 [in order to complete properties corresponding to System.Web.Mvc.ModelMetadata] public virtual int Order { get; set; } // ~ System.Web.Mvc.ModelMetadata.Properties /// @@ -238,7 +230,7 @@ internal void CopyMetaDataFrom(Metadata metadata) // // Returns: // The short display name. - // TODO MVC2 public virtual string ShortDisplayName { get; set; } + // TODO MVC2 [in order to complete properties corresponding to System.Web.Mvc.ModelMetadata] public virtual string ShortDisplayName { get; set; } // ~ System.Web.Mvc.ModelMetadata.ShowForDisplay /// @@ -264,7 +256,7 @@ internal void CopyMetaDataFrom(Metadata metadata) // // Returns: // The simple display string for the model. - // TODO MVC2 public virtual string SimpleDisplayText { get; set; } + // TODO MVC2 [in order to complete properties corresponding to System.Web.Mvc.ModelMetadata] public virtual string SimpleDisplayText { get; set; } /// /// Gets or sets a hint that suggests what template to use for this model. From 8e05e477c0c140f1db6b3ae17fd6d402e52bd774 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 4 Apr 2011 14:06:28 +0200 Subject: [PATCH 13/56] task for writing missing Metadata.CopyMetaDataFrom tests --- Source/FluentMetadata.Core/MetaData.cs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 01c584a..4b044c4 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -29,21 +29,32 @@ public Metadata(Metadata metadata, Type containerType) internal void CopyMetaDataFrom(Metadata metadata) { - Required = metadata.Required; - StringLength = metadata.StringLength; - ErrorMessage = metadata.ErrorMessage; + //TODO write tests for CopyMetaDataFrom: properties commented here have not associated tests yet + //ContainerType = metadata.ContainerType; DataTypeName = metadata.DataTypeName; + //Description = metadata.Description; + //DisplayFormat = metadata.DisplayFormat; + DisplayName = metadata.DisplayName; + //EditorFormat = metadata.EditorFormat; + //HideSurroundingHtml = metadata.HideSurroundingHtml; Readonly = metadata.Readonly; + Required = metadata.Required; + //ModelType = metadata.ModelType; + NullDisplayText = metadata.NullDisplayText; + //Properties = metadata.Properties; + //ModelName = metadata.ModelName; ShowDisplay = metadata.ShowDisplay; ShowEditor = metadata.ShowEditor; TemplateHint = metadata.TemplateHint; - NullDisplayText = metadata.NullDisplayText; - DisplayName = metadata.DisplayName; + //Watermark = metadata.Watermark; + StringLength = metadata.StringLength; + ErrorMessage = metadata.ErrorMessage; + //Hidden = metadata.Hidden; + foreach (var rule in metadata.Rules) { AddRule(rule); } - } #region properties corresponding to System.Web.Mvc.ModelMetadata From 06baf7119c0fdf8a8e88434e8086e76f2d4294b8 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 4 Apr 2011 22:59:50 +0200 Subject: [PATCH 14/56] added Custom DataType to IAsProperty --- .../FluentMetadata.Core/Builder/AsBuilder.cs | 18 ++++++++++----- Source/FluentMetadata.Core/IAsProperty.cs | 13 ++++++----- .../FluentMetadata.MVC.Specs/ComplexModel.cs | 2 ++ .../MetaData_ComplexModel_Specs.cs | 22 ++++++++++++------- 4 files changed, 35 insertions(+), 20 deletions(-) diff --git a/Source/FluentMetadata.Core/Builder/AsBuilder.cs b/Source/FluentMetadata.Core/Builder/AsBuilder.cs index 3c08180..0732289 100644 --- a/Source/FluentMetadata.Core/Builder/AsBuilder.cs +++ b/Source/FluentMetadata.Core/Builder/AsBuilder.cs @@ -11,7 +11,7 @@ public AsBuilder(PropertyMetadataBuilder propertyMetaDataBuilder) this.propertyMetaDataBuilder = propertyMetaDataBuilder; } - public IProperty EmailAddress() + public IProperty EmailAddress() { SetDataTypeName(DataType.EmailAddress); return propertyMetaDataBuilder; @@ -22,34 +22,40 @@ private void SetDataTypeName(DataType dataType) propertyMetaDataBuilder.Metadata.DataTypeName = dataType.ToString(); } - public IProperty Url() + public IProperty Url() { SetDataTypeName(DataType.Url); return propertyMetaDataBuilder; } - public IProperty Html() + public IProperty Html() { SetDataTypeName(DataType.Html); return propertyMetaDataBuilder; } - public IProperty Text() + public IProperty Text() { SetDataTypeName(DataType.Text); return propertyMetaDataBuilder; } - public IProperty MultilineText() + public IProperty MultilineText() { SetDataTypeName(DataType.MultilineText); return propertyMetaDataBuilder; } - public IProperty Password() + public IProperty Password() { SetDataTypeName(DataType.Password); return propertyMetaDataBuilder; } + + public IProperty Custom(string dataTypeName) + { + propertyMetaDataBuilder.Metadata.DataTypeName = dataTypeName; + return propertyMetaDataBuilder; + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/IAsProperty.cs b/Source/FluentMetadata.Core/IAsProperty.cs index 041217f..e46c815 100644 --- a/Source/FluentMetadata.Core/IAsProperty.cs +++ b/Source/FluentMetadata.Core/IAsProperty.cs @@ -2,11 +2,12 @@ { public interface IAsProperty { - IProperty EmailAddress(); - IProperty Url(); - IProperty Html(); - IProperty Text(); - IProperty MultilineText(); - IProperty Password(); + IProperty EmailAddress(); + IProperty Url(); + IProperty Html(); + IProperty Text(); + IProperty MultilineText(); + IProperty Password(); + IProperty Custom(string dataTypeName); } } \ No newline at end of file diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index be283a0..560dcbe 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -9,6 +9,7 @@ public ComplexModelMetadata() { Class.Display.Name("Komplex"); Property(e => e.FirstName).Display.Name("Vorname").Is.Not.ConvertEmptyStringToNull(); + Property(e => e.Age).As.Custom("Years"); } } [DisplayName("Komplex")] @@ -18,6 +19,7 @@ public class ComplexModel [DisplayFormat(ConvertEmptyStringToNull = false)] public string FirstName { get; set; } public string LastName { get; set; } + [DataType("Years")] public int Age { get; set; } public decimal Amount { get; set; } public char Sex { get; set; } diff --git a/Source/FluentMetadata.MVC.Specs/MetaData_ComplexModel_Specs.cs b/Source/FluentMetadata.MVC.Specs/MetaData_ComplexModel_Specs.cs index 5e49844..e0ceee9 100644 --- a/Source/FluentMetadata.MVC.Specs/MetaData_ComplexModel_Specs.cs +++ b/Source/FluentMetadata.MVC.Specs/MetaData_ComplexModel_Specs.cs @@ -1,6 +1,3 @@ -using System; -using System.Collections.Generic; -using System.Linq; using Xunit; namespace FluentMetadata.MVC.Specs @@ -28,7 +25,7 @@ protected void CreatePropertyMetadata(string propertyName) } } - [Concern(typeof (FluentMetadataProvider))] + [Concern(typeof(FluentMetadataProvider))] public class When_getting_the_Metadata_of_the_Type_ComplexModel : ConcernOfComplexModel { public override void CreateMetadata() @@ -38,7 +35,7 @@ public override void CreateMetadata() } } - [Concern(typeof (FluentMetadataProvider))] + [Concern(typeof(FluentMetadataProvider))] public class When_getting_the_Metadata_of_ComplexModel_Property_FirstName : ConcernOfComplexModel { public override void CreateMetadata() @@ -47,7 +44,7 @@ public override void CreateMetadata() } } - [Concern(typeof (FluentMetadataProvider))] + [Concern(typeof(FluentMetadataProvider))] public class When_getting_the_Metadata_of_ComplexModel_Property_LastName : ConcernOfComplexModel { public override void CreateMetadata() @@ -56,7 +53,7 @@ public override void CreateMetadata() } } - [Concern(typeof (FluentMetadataProvider))] + [Concern(typeof(FluentMetadataProvider))] public class When_getting_the_Metadata_of_ComplexModel_Property_Sex : ConcernOfComplexModel { public override void CreateMetadata() @@ -65,7 +62,7 @@ public override void CreateMetadata() } } - [Concern(typeof (FluentMetadataProvider))] + [Concern(typeof(FluentMetadataProvider))] public class When_getting_the_Metadata_of_ComplexModel_Property_Amount : ConcernOfComplexModel { public override void CreateMetadata() @@ -73,4 +70,13 @@ public override void CreateMetadata() CreatePropertyMetadata("Amount"); } } + + [Concern(typeof(FluentMetadataProvider))] + public class When_getting_the_Metadata_of_ComplexModel_Property_Age : ConcernOfComplexModel + { + public override void CreateMetadata() + { + CreatePropertyMetadata("Age"); + } + } } \ No newline at end of file From 895b2320524031c9a8e6540c12d66711ee9a419e Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 18 Apr 2011 14:00:45 +0200 Subject: [PATCH 15/56] refactored RangeRule to accept IComparables --- Source/FluentMetadata.Core/Rules/RangeRule.cs | 39 +++++++------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/Source/FluentMetadata.Core/Rules/RangeRule.cs b/Source/FluentMetadata.Core/Rules/RangeRule.cs index 9507f3c..89de8ea 100644 --- a/Source/FluentMetadata.Core/Rules/RangeRule.cs +++ b/Source/FluentMetadata.Core/Rules/RangeRule.cs @@ -5,28 +5,15 @@ namespace FluentMetadata.Rules { public class RangeRule : Rule { - private Func valueConversion; - private object valueMaximum; - private object valueMinimum; + private IComparable valueMaximum; + private IComparable valueMinimum; private RangeRule() : base("the value of '{0}' must be between {1} and {2}") { } - public RangeRule(double minimum, double maximum) - : this() - { - Initialize(minimum, maximum, o => Convert.ToDouble(o)); - } - - public RangeRule(int minimum, int maximum) - : this() - { - Initialize(minimum, maximum, o => Convert.ToInt32(o)); - } - - public RangeRule(DateTime minimum, DateTime maximum) + public RangeRule(IComparable minimum, IComparable maximum) : this() { Initialize(minimum, maximum, o => Convert.ToDateTime(o)); @@ -36,14 +23,19 @@ private void Initialize(IComparable minimum, IComparable maximum, Func 0) { - throw new ArgumentOutOfRangeException("maximum", maximum, - string.Format(CultureInfo.CurrentCulture, - "the minimum value {0} is higher then the maximum value {1}", - minimum, maximum)); + throw new ArgumentOutOfRangeException( + "maximum", + maximum, + string.Format( + CultureInfo.CurrentCulture, + "the minimum value {0} is higher then the maximum value {1}", + minimum, + maximum + ) + ); } valueMinimum = minimum; valueMaximum = maximum; - valueConversion = conversion; } public override bool IsValid(object value) @@ -52,14 +44,13 @@ public override bool IsValid(object value) { return true; } - if ((value is string) && string.IsNullOrEmpty((string)value)) + if ((value is string) && string.IsNullOrEmpty(value as string)) { return true; } - object currentValue = valueConversion(value); var min = (IComparable)valueMinimum; var max = (IComparable)valueMaximum; - return ((min.CompareTo(currentValue) <= 0) && (max.CompareTo(currentValue) >= 0)); + return ((min.CompareTo(value) <= 0) && (max.CompareTo(value) >= 0)); } public override string FormatErrorMessage(string name) From 6dcf2545a4efe0bf96f99c1a17c7bbfe1002acb4 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 18 Apr 2011 14:16:12 +0200 Subject: [PATCH 16/56] made RangeRule accessible to configuration API via Range(min,max) on IProperty & added GetterFunctions to Metadata --- .../PropertyMedata_with_WebUser.cs | 17 ++++++++++- .../SampleClasses/MetaData/WebUserMetadata.cs | 8 ++++-- .../Builder/PropertyMetadataBuilder.cs | 28 +++++++++++-------- Source/FluentMetadata.Core/IProperty.cs | 18 ++++++------ Source/FluentMetadata.Core/MetaData.cs | 13 +++++++++ Source/FluentMetadata.Core/Rules/RangeRule.cs | 16 +++++++++++ 6 files changed, 77 insertions(+), 23 deletions(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUser.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUser.cs index 2dea710..94d1ef1 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUser.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUser.cs @@ -1,10 +1,12 @@ -using FluentMetadata.Specs.SampleClasses; +using System; +using FluentMetadata.Specs.SampleClasses; using Xunit; namespace FluentMetadata.Specs { public class PropertyMedata_with_WebUser : MetadataTestBase { + private Metadata lastLogin; private Metadata username; private Metadata id; @@ -13,6 +15,7 @@ public PropertyMedata_with_WebUser() var query = new QueryFluentMetadata(); username = query.GetMetadataFor(typeof(WebUser), "Username"); id = query.GetMetadataFor(typeof(WebUser), "Id"); + lastLogin = query.GetMetadataFor(typeof(WebUser), "LastLogin"); } [Fact] @@ -56,5 +59,17 @@ public void Id_Required_is_false() { Assert.False(id.Required.HasValue); } + + [Fact] + public void Last_Login_Minimum_is_2010_1_23() + { + Assert.Equal(new DateTime(2010, 1, 23), lastLogin.GetRangeMinimum()); + } + + [Fact] + public void Last_Login_Maximum_is_DoomsDay() + { + Assert.Equal(DateTime.MaxValue, lastLogin.GetRangeMaximum()); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs index 8376a6d..b42274c 100644 --- a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs +++ b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs @@ -1,6 +1,8 @@ +using System; + namespace FluentMetadata.Specs.SampleClasses.MetaData { - public class WebUserMetadata : DomainObjectMetadata + public class WebUserMetadata : DomainObjectMetadata { public WebUserMetadata() { @@ -15,7 +17,9 @@ public WebUserMetadata() Property(x => x.PasswordHash).Should.Not.ShowInDisplay().Should.Not.ShowInEditor(); Property(x => x.ConfirmationKey).Should.Not.ShowInEditor().Should.Not.ShowInDisplay(); Property(x => x.LastLogin).Should.Not.ShowInEditor() - .Display.Name("Letzte Anmeldung").Display.NullText(""); + .Display.Name("Letzte Anmeldung") + .Display.NullText("") + .Range(new DateTime(2010, 1, 23), DateTime.MaxValue); //support ends on doomsday Property(x => x.BounceCount).Should.Not.ShowInEditor() .Display.Name("E-Mail Fehler"); Property(x => x.Confirmed).Should.Not.HiddenInput() diff --git a/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs b/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs index 5667206..fc15e6c 100644 --- a/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs +++ b/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs @@ -8,7 +8,8 @@ internal abstract class PropertyMetadataBuilder { private readonly Metadata metadata; - protected PropertyMetadataBuilder() : this(new Metadata()) + protected PropertyMetadataBuilder() + : this(new Metadata()) { } @@ -23,7 +24,7 @@ public Metadata Metadata } } - internal class PropertyMetadataBuilder : PropertyMetadataBuilder, IProperty + internal class PropertyMetadataBuilder : PropertyMetadataBuilder, IProperty { public PropertyMetadataBuilder(Metadata metadata) @@ -33,45 +34,43 @@ public PropertyMetadataBuilder(Metadata metadata) public PropertyMetadataBuilder(Expression> expression) { - Metadata.ContainerType = typeof (T); + Metadata.ContainerType = typeof(T); Metadata.ModelName = ExpressionHelper.GetPropertyName(expression); Metadata.ModelType = ExpressionHelper.GetPropertyType(expression); } - public PropertyMetadataBuilder(string propertyName) { Metadata.ContainerType = null; Metadata.ModelName = propertyName; - Metadata.ModelType = typeof (T); + Metadata.ModelType = typeof(T); } - - public IProperty Length(int length) + public IProperty Length(int length) { Metadata.StringLength = length; Metadata.AddRule(new StringLengthRule(length)); return this; } - public IProperty UIHint(string templateHint) + public IProperty UIHint(string templateHint) { Metadata.TemplateHint = templateHint; return this; } - public IProperty Description(string description) + public IProperty Description(string description) { Metadata.Description = description; return this; } - public IEditorProperty Editor + public IEditorProperty Editor { get { return new EditorBuilder(this); } } - public IDisplayProperty Display + public IDisplayProperty Display { get { return new DisplayBuilder(this); } } @@ -90,5 +89,12 @@ public IShouldProperty Should { get { return new ShouldBuilder(this); } } + + public IProperty Range(IComparable minimum, IComparable maximum) + { + Metadata.AddRule(new RangeRule(minimum, maximum)); + + return this; + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/IProperty.cs b/Source/FluentMetadata.Core/IProperty.cs index 9d9c98f..487086e 100644 --- a/Source/FluentMetadata.Core/IProperty.cs +++ b/Source/FluentMetadata.Core/IProperty.cs @@ -1,14 +1,14 @@ -namespace FluentMetadata +using System; +namespace FluentMetadata { - public interface IProperty + public interface IProperty { - IProperty Length(int length); - IProperty UIHint(string templateHint); - - IProperty Description(string description); - - IEditorProperty Editor { get; } - IDisplayProperty Display { get; } + IProperty Length(int length); + IProperty UIHint(string templateHint); + IProperty Description(string description); + IProperty Range(IComparable minimum, IComparable maximum); + IEditorProperty Editor { get; } + IDisplayProperty Display { get; } IAsProperty As { get; } IIsProperty Is { get; } IShouldProperty Should { get; } diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 4b044c4..7f1bd84 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using FluentMetadata.Rules; namespace FluentMetadata @@ -301,5 +302,17 @@ public void AddRule(IRule rule) { rules.Add(rule); } + + public object GetRangeMinimum() + { + var rangeRule = Rules.OfType().LastOrDefault(); + return rangeRule == null ? null : rangeRule.Minimum; + } + + public object GetRangeMaximum() + { + var rangeRule = Rules.OfType().LastOrDefault(); + return rangeRule == null ? null : rangeRule.Maximum; + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/Rules/RangeRule.cs b/Source/FluentMetadata.Core/Rules/RangeRule.cs index 89de8ea..62ab350 100644 --- a/Source/FluentMetadata.Core/Rules/RangeRule.cs +++ b/Source/FluentMetadata.Core/Rules/RangeRule.cs @@ -8,6 +8,22 @@ public class RangeRule : Rule private IComparable valueMaximum; private IComparable valueMinimum; + internal object Minimum + { + get + { + return valueMinimum; + } + } + + internal object Maximum + { + get + { + return valueMaximum; + } + } + private RangeRule() : base("the value of '{0}' must be between {1} and {2}") { From 7f0a5731577276fa930473dbae8a19a1ce55ccb1 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 18 Apr 2011 14:33:12 +0200 Subject: [PATCH 17/56] refactored duplicated StringLength information into Getter function on Metadata reading from Rules --- .../Builder/PropertyMetadataBuilder.cs | 1 - Source/FluentMetadata.Core/MetaData.cs | 13 ++++++++++--- .../FluentMetadata.Core/Rules/StringLengthRule.cs | 8 ++++++++ .../EntityFrameworkAdapter.cs | 4 ++-- .../StringPropertyConfigurationAdapter.cs | 8 +++++--- .../Conventions/FluentMetaDataConvention.cs | 7 ++++--- 6 files changed, 29 insertions(+), 12 deletions(-) diff --git a/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs b/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs index fc15e6c..14fcab9 100644 --- a/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs +++ b/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs @@ -48,7 +48,6 @@ public PropertyMetadataBuilder(string propertyName) public IProperty Length(int length) { - Metadata.StringLength = length; Metadata.AddRule(new StringLengthRule(length)); return this; } diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 7f1bd84..41e0c8a 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -48,7 +48,6 @@ internal void CopyMetaDataFrom(Metadata metadata) ShowEditor = metadata.ShowEditor; TemplateHint = metadata.TemplateHint; //Watermark = metadata.Watermark; - StringLength = metadata.StringLength; ErrorMessage = metadata.ErrorMessage; //Hidden = metadata.Hidden; @@ -288,8 +287,6 @@ internal void CopyMetaDataFrom(Metadata metadata) #endregion - // TODO add StringLengthRule to rules automatically on set - public int? StringLength { get; set; } public string ErrorMessage { get; set; } public bool? Hidden { get; set; } @@ -314,5 +311,15 @@ public object GetRangeMaximum() var rangeRule = Rules.OfType().LastOrDefault(); return rangeRule == null ? null : rangeRule.Maximum; } + + public int? GetMaximumLength() + { + var lengthRule = Rules.OfType().LastOrDefault(); + if (lengthRule == null) + { + return null; + } + return lengthRule.Maximum; + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/Rules/StringLengthRule.cs b/Source/FluentMetadata.Core/Rules/StringLengthRule.cs index b39b5aa..0d40aff 100644 --- a/Source/FluentMetadata.Core/Rules/StringLengthRule.cs +++ b/Source/FluentMetadata.Core/Rules/StringLengthRule.cs @@ -7,6 +7,14 @@ public class StringLengthRule : Rule { private readonly int maxLength; + internal int Maximum + { + get + { + return maxLength; + } + } + public StringLengthRule(int maxLength) : base("the string for {0} should not be longer than {1} characters") { diff --git a/Source/FluentMetadata.EntityFramework/EntityFrameworkAdapter.cs b/Source/FluentMetadata.EntityFramework/EntityFrameworkAdapter.cs index c6f55fe..ab1301f 100644 --- a/Source/FluentMetadata.EntityFramework/EntityFrameworkAdapter.cs +++ b/Source/FluentMetadata.EntityFramework/EntityFrameworkAdapter.cs @@ -33,7 +33,7 @@ internal void MapProperties(Type instanceType, StructuralTypeConfiguration confi { continue; } - if (!data.StringLength.HasValue && !data.Required.HasValue) + if (!data.GetMaximumLength().HasValue && !data.Required.HasValue) { continue; } @@ -47,7 +47,7 @@ internal void MapProperties(Type instanceType, StructuralTypeConfiguration confi var lambda = generator.CreateExpressionForProperty(instanceType, data.ModelName); if (lambda != null) { - var propertyConfiguration = (PropertyConfiguration) methodInfo.Invoke(configuration, new[] {lambda}); + var propertyConfiguration = (PropertyConfiguration)methodInfo.Invoke(configuration, new[] { lambda }); factory.Create(propertyConfiguration).Convert(data, propertyConfiguration); } diff --git a/Source/FluentMetadata.EntityFramework/Internal/ConfigurationAdapters/StringPropertyConfigurationAdapter.cs b/Source/FluentMetadata.EntityFramework/Internal/ConfigurationAdapters/StringPropertyConfigurationAdapter.cs index f380899..69c0c82 100644 --- a/Source/FluentMetadata.EntityFramework/Internal/ConfigurationAdapters/StringPropertyConfigurationAdapter.cs +++ b/Source/FluentMetadata.EntityFramework/Internal/ConfigurationAdapters/StringPropertyConfigurationAdapter.cs @@ -4,17 +4,19 @@ namespace FluentMetadata.EntityFramework.Internal.ConfigurationAdapters { internal class StringPropertyConfigurationAdapter : ConfigurationAdapter { - public StringPropertyConfigurationAdapter() : base(new OptionalPrimitivePropertyConfigurationAdapter()) + public StringPropertyConfigurationAdapter() + : base(new OptionalPrimitivePropertyConfigurationAdapter()) { } protected override void ConvertToConfiguration(Metadata data) { - if (!data.StringLength.HasValue) + var maxLength = data.GetMaximumLength(); + if (!maxLength.HasValue) { return; } - Configuration.MaxLength = data.StringLength; + Configuration.MaxLength = maxLength.Value; } } } \ No newline at end of file diff --git a/Source/FluentMetadata.FluentNHibernate/Conventions/FluentMetaDataConvention.cs b/Source/FluentMetadata.FluentNHibernate/Conventions/FluentMetaDataConvention.cs index 8d496e8..5b61e04 100644 --- a/Source/FluentMetadata.FluentNHibernate/Conventions/FluentMetaDataConvention.cs +++ b/Source/FluentMetadata.FluentNHibernate/Conventions/FluentMetaDataConvention.cs @@ -8,14 +8,15 @@ public class FluentMetaDataConvention : IPropertyConvention private readonly QueryFluentMetadata query = new QueryFluentMetadata(); public void Apply(IPropertyInstance instance) { - var meta = query.GetMetadataFor(instance.EntityType,instance.Property.Name); + var meta = query.GetMetadataFor(instance.EntityType, instance.Property.Name); if (meta.Required.HasValue) { ApplyRequired(meta.Required.Value, instance); } - if (meta.StringLength.HasValue) + var maxLength = meta.GetMaximumLength(); + if (maxLength.HasValue) { - ApplyStringLength(meta.StringLength.Value, instance); + ApplyStringLength(maxLength.Value, instance); } } From e9036806b7f40abf95ec7bbbfcc88d8fe6275b12 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 18 Apr 2011 16:05:16 +0200 Subject: [PATCH 18/56] added support for minimum string length in rule & configuration API --- .../PropertyMedata_with_WebUser.cs | 42 ++++++++- .../Rules/StringLengthRuleSpecs.cs | 87 ++++++++++++++++++- .../SampleClasses/MetaData/WebUserMetadata.cs | 4 +- .../Builder/PropertyMetadataBuilder.cs | 10 ++- Source/FluentMetadata.Core/IProperty.cs | 3 +- Source/FluentMetadata.Core/MetaData.cs | 21 ++++- .../Rules/StringLengthRule.cs | 43 +++++++-- 7 files changed, 189 insertions(+), 21 deletions(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUser.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUser.cs index 94d1ef1..b1dbaa3 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUser.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUser.cs @@ -6,9 +6,7 @@ namespace FluentMetadata.Specs { public class PropertyMedata_with_WebUser : MetadataTestBase { - private Metadata lastLogin; - private Metadata username; - private Metadata id; + Metadata lastLogin, username, id, passWordHash, role; public PropertyMedata_with_WebUser() { @@ -16,6 +14,8 @@ public PropertyMedata_with_WebUser() username = query.GetMetadataFor(typeof(WebUser), "Username"); id = query.GetMetadataFor(typeof(WebUser), "Id"); lastLogin = query.GetMetadataFor(typeof(WebUser), "LastLogin"); + passWordHash = query.GetMetadataFor(typeof(WebUser), "PasswordHash"); + role = query.GetMetadataFor(typeof(WebUser), "Role"); } [Fact] @@ -42,6 +42,42 @@ public void Username_Required_is_true() Assert.True(username.Required.Value); } + [Fact] + public void Username_MinLength_is_3() + { + Assert.Equal(3, username.GetMinimumLength()); + } + + [Fact] + public void Username_MaxLength_is_256() + { + Assert.Equal(256, username.GetMaximumLength()); + } + + [Fact] + public void PassWordHash_MinLength_is_32() + { + Assert.Equal(32, passWordHash.GetMinimumLength()); + } + + [Fact] + public void PassWordHash_MaxLength_is_null() + { + Assert.Null(passWordHash.GetMaximumLength()); + } + + [Fact] + public void Role_MinLength_is_null() + { + Assert.Null(role.GetMinimumLength()); + } + + [Fact] + public void Role_MaxLength_is_256() + { + Assert.Equal(256, role.GetMaximumLength()); + } + [Fact] public void Id_ModelName_is_Id() { diff --git a/Source/FluentMetadata.Core.Specs/Rules/StringLengthRuleSpecs.cs b/Source/FluentMetadata.Core.Specs/Rules/StringLengthRuleSpecs.cs index ca13a79..e614e73 100644 --- a/Source/FluentMetadata.Core.Specs/Rules/StringLengthRuleSpecs.cs +++ b/Source/FluentMetadata.Core.Specs/Rules/StringLengthRuleSpecs.cs @@ -59,9 +59,94 @@ public void Should_Valid_with_a_string_with_length_0() [Observation] public void Should_Valid_with_a_string_is_NULL() { - string badLength = null; + string badLength = null; Sut.IsValid(badLength).ShouldBeTrue(); } + } + + public class When_the_minimal_StringLength_is_8_and_Maximal_StringLength_is_null : InstanceContextSpecification + { + protected override StringLengthRule CreateSut() + { + return new StringLengthRule(8, null); + } + + protected override void Because() + { + } + + [Observation] + public void Should_be_invalid_with_a_null_string() + { + Sut.IsValid(null).ShouldBeFalse(); + } + [Observation] + public void Should_be_invalid_with_a_string_with_length_7() + { + var value = new string('a', 7); + Sut.IsValid(value).ShouldBeFalse(); + } + + [Observation] + public void Should_be_valid_with_a_string_with_length_8() + { + var value = new string('a', 8); + Sut.IsValid(value).ShouldBeTrue(); + } + + [Observation] + public void Should_be_valid_with_a_string_with_length_4001() + { + var value = new string('a', 4001); + Sut.IsValid(value).ShouldBeTrue(); + } + } + + public class When_the_minimal_StringLength_is_5_and_Maximal_StringLength_is_250 : InstanceContextSpecification + { + protected override StringLengthRule CreateSut() + { + return new StringLengthRule(5, 250); + } + + protected override void Because() + { + } + + [Observation] + public void Should_be_invalid_with_a_string_with_length_4() + { + var value = new string('a', 4); + Sut.IsValid(value).ShouldBeFalse(); + } + + [Observation] + public void Should_be_valid_with_a_string_with_length_5() + { + var value = new string('a', 5); + Sut.IsValid(value).ShouldBeTrue(); + } + + [Observation] + public void Should_be_valid_with_a_string_with_length_249() + { + var value = new string('a', 249); + Sut.IsValid(value).ShouldBeTrue(); + } + + [Observation] + public void Should_be_valid_with_a_string_with_length_250() + { + var value = new string('a', 249); + Sut.IsValid(value).ShouldBeTrue(); + } + + [Observation] + public void Should_be_invalid_with_a_string_with_length_251() + { + var value = new string('a', 251); + Sut.IsValid(value).ShouldBeFalse(); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs index b42274c..6d9348d 100644 --- a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs +++ b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs @@ -6,11 +6,11 @@ public class WebUserMetadata : DomainObjectMetadata { public WebUserMetadata() { - Property(x => x.Username).Length(256).Is.Required().Is.ReadOnly() + Property(x => x.Username).Length(3, 256).Is.Required().Is.ReadOnly() .Display.Name("Benutzername"); Property(x => x.EMail).Length(128).Is.Required().As.EmailAddress() .Display.Name("E-Mail").As.EmailAddress(); - Property(x => x.PasswordHash).Length(64).Is.Required() + Property(x => x.PasswordHash).Length(32, null).Is.Required() .Should.Not.ShowInDisplay().Should.Not.ShowInEditor(); Property(x => x.Role).UIHint("Roles").Length(256).Is.Required() .Display.Name("Rolle"); diff --git a/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs b/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs index 14fcab9..f718057 100644 --- a/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs +++ b/Source/FluentMetadata.Core/Builder/PropertyMetadataBuilder.cs @@ -46,9 +46,15 @@ public PropertyMetadataBuilder(string propertyName) Metadata.ModelType = typeof(T); } - public IProperty Length(int length) + public IProperty Length(int maxLength) { - Metadata.AddRule(new StringLengthRule(length)); + Metadata.AddRule(new StringLengthRule(maxLength)); + return this; + } + + public IProperty Length(int minLength, int? maxLength) + { + Metadata.AddRule(new StringLengthRule(minLength, maxLength)); return this; } diff --git a/Source/FluentMetadata.Core/IProperty.cs b/Source/FluentMetadata.Core/IProperty.cs index 487086e..bd9fa56 100644 --- a/Source/FluentMetadata.Core/IProperty.cs +++ b/Source/FluentMetadata.Core/IProperty.cs @@ -3,7 +3,8 @@ namespace FluentMetadata { public interface IProperty { - IProperty Length(int length); + IProperty Length(int maxLength); + IProperty Length(int minLength, int? maxLength); IProperty UIHint(string templateHint); IProperty Description(string description); IProperty Range(IComparable minimum, IComparable maximum); diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 41e0c8a..b938ee0 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -302,24 +302,39 @@ public void AddRule(IRule rule) public object GetRangeMinimum() { - var rangeRule = Rules.OfType().LastOrDefault(); + var rangeRule = GetLastRuleOfType(); return rangeRule == null ? null : rangeRule.Minimum; } public object GetRangeMaximum() { - var rangeRule = Rules.OfType().LastOrDefault(); + var rangeRule = GetLastRuleOfType(); return rangeRule == null ? null : rangeRule.Maximum; } public int? GetMaximumLength() { - var lengthRule = Rules.OfType().LastOrDefault(); + var lengthRule = GetLastRuleOfType(); if (lengthRule == null) { return null; } return lengthRule.Maximum; } + + public int? GetMinimumLength() + { + var lengthRule = GetLastRuleOfType(); + if (lengthRule == null) + { + return null; + } + return lengthRule.Minimum; + } + + T GetLastRuleOfType() + { + return Rules.OfType().LastOrDefault(); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/Rules/StringLengthRule.cs b/Source/FluentMetadata.Core/Rules/StringLengthRule.cs index 0d40aff..bd983f1 100644 --- a/Source/FluentMetadata.Core/Rules/StringLengthRule.cs +++ b/Source/FluentMetadata.Core/Rules/StringLengthRule.cs @@ -3,11 +3,20 @@ namespace FluentMetadata.Rules { // ~ System.ComponentModel.DataAnnotations.StringLengthAttribute.MaximumLength + // ~ System.ComponentModel.DataAnnotations.StringLengthAttribute.MinimumLength public class StringLengthRule : Rule { - private readonly int maxLength; + readonly int? minLength, maxLength; - internal int Maximum + internal int? Minimum + { + get + { + return minLength; + } + } + + internal int? Maximum { get { @@ -16,28 +25,44 @@ internal int Maximum } public StringLengthRule(int maxLength) - : base("the string for {0} should not be longer than {1} characters") + : base("the string for '{0}' should not be longer than {1} characters") + { + this.maxLength = maxLength; + } + + public StringLengthRule(int minLength, int? maxLength) + : base("'{0}' must be " + + (maxLength.HasValue ? " between {2} and {1}" : " at least {2}") + + " characters long") { + this.minLength = minLength; this.maxLength = maxLength; } public override bool IsValid(object value) { - if (value == null) + var valueAsString = value as string; + if (valueAsString == null) { - return true; + return minLength.HasValue ? false : true; } - var strValue = (string)value; - return strValue.Length <= maxLength; + + var length = valueAsString.Length; + if (maxLength.HasValue && length > maxLength || + minLength.HasValue && length < minLength) + { + return false; + } + + return true; } public override string FormatErrorMessage(string name) { - return string.Format(ErrorMessageFormat, name, maxLength); + return string.Format(ErrorMessageFormat, name, maxLength, minLength); } } - // TODO rule equivalent to System.ComponentModel.DataAnnotations.StringLengthAttribute.MinimumLength // TODO rule equivalent to System.ComponentModel.DataAnnotations.RegularExpressionAttribute // TODO implement or delete: What does this rule validate? From 34c1f1406599fd88c3764859668d5265b6d3fa9d Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 18 Apr 2011 17:30:18 +0200 Subject: [PATCH 19/56] made PropertyMustMatchRule available in API throgh Class.PropertiesShouldMatch --- .../ClassMetadata_with_Person.cs | 25 ++++++++++-- .../FluentMetadata.Core.Specs.csproj | 1 + .../PropertyMedata_with_Person.cs | 8 ++-- .../Rules/PropertyMustMatchRuleSpecs.cs | 38 +++++++++++++++++++ .../SampleClasses/MetaData/PersonMetadata.cs | 6 ++- .../Builder/ClassMetadataBuilder.cs | 10 +++++ Source/FluentMetadata.Core/IClassBuilder.cs | 9 ++++- .../Rules/PropertyMustMatchRule.cs | 30 +++++++++------ 8 files changed, 104 insertions(+), 23 deletions(-) create mode 100644 Source/FluentMetadata.Core.Specs/Rules/PropertyMustMatchRuleSpecs.cs diff --git a/Source/FluentMetadata.Core.Specs/ClassMetadata_with_Person.cs b/Source/FluentMetadata.Core.Specs/ClassMetadata_with_Person.cs index 5725708..3825cf7 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; @@ -10,20 +12,19 @@ public class ClassMetadata_with_Person : MetadataTestBase public ClassMetadata_with_Person() { var query = new QueryFluentMetadata(); - classMetadata = query.GetMetadataFor(typeof (Person)); + classMetadata = query.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] @@ -31,5 +32,21 @@ public void Metadata_Display_is_Benutzer() { Assert.Equal("Benutzer", classMetadata.DisplayName); } + + [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/FluentMetadata.Core.Specs.csproj b/Source/FluentMetadata.Core.Specs/FluentMetadata.Core.Specs.csproj index e8a0055..9ef80eb 100644 --- a/Source/FluentMetadata.Core.Specs/FluentMetadata.Core.Specs.csproj +++ b/Source/FluentMetadata.Core.Specs/FluentMetadata.Core.Specs.csproj @@ -87,6 +87,7 @@ + diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_Person.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_Person.cs index fb90c62..58569eb 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_Person.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_Person.cs @@ -11,8 +11,8 @@ public class PropertyMedata_with_Person : MetadataTestBase public PropertyMedata_with_Person() { var query = new QueryFluentMetadata(); - firstName = query.GetMetadataFor(typeof (Person), "FirstName"); - lastName = query.GetMetadataFor(typeof (Person), "LastName"); + firstName = query.GetMetadataFor(typeof(Person), "FirstName"); + lastName = query.GetMetadataFor(typeof(Person), "LastName"); } [Fact] @@ -24,7 +24,7 @@ public void FirstName_ModelName_is_FirstName() [Fact] public void FirstName_ModelType_is_string() { - Assert.Equal(typeof (string), firstName.ModelType); + Assert.Equal(typeof(string), firstName.ModelType); } [Fact] @@ -42,7 +42,7 @@ public void LastName_ModelName_is_LastName() [Fact] public void LastName_ModelType_is_string() { - Assert.Equal(typeof (string), lastName.ModelType); + Assert.Equal(typeof(string), lastName.ModelType); } [Fact] diff --git a/Source/FluentMetadata.Core.Specs/Rules/PropertyMustMatchRuleSpecs.cs b/Source/FluentMetadata.Core.Specs/Rules/PropertyMustMatchRuleSpecs.cs new file mode 100644 index 0000000..93d9499 --- /dev/null +++ b/Source/FluentMetadata.Core.Specs/Rules/PropertyMustMatchRuleSpecs.cs @@ -0,0 +1,38 @@ +using FluentMetadata.Rules; +using Xunit; + +namespace FluentMetadata.Specs.Rules +{ + public class ChangePasswordModel + { + public string OldPassword { get; set; } + public string NewPassword { get; set; } + public string ConfirmPassword { get; set; } + } + + public class When_two_properties_should_be_equal : InstanceContextSpecification> + { + protected override PropertyMustMatchRule CreateSut() + { + return new PropertyMustMatchRule(x => x.NewPassword, x => x.ConfirmPassword); + } + + protected override void Because() + { + } + + [Observation] + public void Should_be_valid_if_properties_match() + { + var model = new ChangePasswordModel { NewPassword = "asdf", ConfirmPassword = "asdf" }; + Sut.IsValid(model).ShouldBeTrue(); + } + + [Observation] + public void Should_be_invalid_if_properties_do_not_match() + { + var model = new ChangePasswordModel { NewPassword = "qwer", ConfirmPassword = "asdf" }; + Sut.IsValid(model).ShouldBeFalse(); + } + } +} \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/PersonMetadata.cs b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/PersonMetadata.cs index 6490b72..425930e 100644 --- a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/PersonMetadata.cs +++ b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/PersonMetadata.cs @@ -5,8 +5,10 @@ public class PersonMetadata : ClassMetadata public PersonMetadata() { Property(p => p.FirstName).Is.Required(); - Class.Display.Name("Benutzer"); - Class.Display.Format("{0} der Benutzer"); + Class + .Display.Name("Benutzer") + .Display.Format("{0} der Benutzer") + .PropertiesShouldMatch(p => p.FirstName, p => p.LastName); } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/Builder/ClassMetadataBuilder.cs b/Source/FluentMetadata.Core/Builder/ClassMetadataBuilder.cs index 5e5b51c..9d0b26a 100644 --- a/Source/FluentMetadata.Core/Builder/ClassMetadataBuilder.cs +++ b/Source/FluentMetadata.Core/Builder/ClassMetadataBuilder.cs @@ -1,3 +1,6 @@ +using System; +using System.Linq.Expressions; +using FluentMetadata.Rules; namespace FluentMetadata.Builder { internal class ClassMetadataBuilder : IClassBuilder @@ -40,5 +43,12 @@ public Metadata Metadata { get { return metadata; } } + + public IClassBuilder PropertiesShouldMatch(Expression> expression, + Expression> confirmExpression) + { + metadata.AddRule(new PropertyMustMatchRule(expression, confirmExpression)); + return this; + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/IClassBuilder.cs b/Source/FluentMetadata.Core/IClassBuilder.cs index 98f0cae..6302ae4 100644 --- a/Source/FluentMetadata.Core/IClassBuilder.cs +++ b/Source/FluentMetadata.Core/IClassBuilder.cs @@ -1,8 +1,15 @@ -namespace FluentMetadata +using System; +using System.Linq.Expressions; + +namespace FluentMetadata { public interface IClassBuilder { Metadata Metadata { get; } IDisplayClass Display { get; } + IClassBuilder PropertiesShouldMatch( + Expression> expression, + Expression> confirmExpression + ); } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/Rules/PropertyMustMatchRule.cs b/Source/FluentMetadata.Core/Rules/PropertyMustMatchRule.cs index c42ab1b..e586a0c 100644 --- a/Source/FluentMetadata.Core/Rules/PropertyMustMatchRule.cs +++ b/Source/FluentMetadata.Core/Rules/PropertyMustMatchRule.cs @@ -4,17 +4,18 @@ namespace FluentMetadata.Rules { - public class PropertyMustMatchRule : ClassRule where T : class + public class PropertyMustMatchRule : ClassRule { private const string DefaultErrorMessage = "'{0}' and '{1}' do not match."; - private readonly string originalPropertyName; private readonly string confirmPropertyName; private Type currentType; - public PropertyMustMatchRule(Expression> expression, - Expression> confirmExpression) : base(DefaultErrorMessage) + public PropertyMustMatchRule( + Expression> expression, + Expression> confirmExpression) + : base(DefaultErrorMessage) { originalPropertyName = ExpressionHelper.GetPropertyName(expression); confirmPropertyName = ExpressionHelper.GetPropertyName(confirmExpression); @@ -22,11 +23,12 @@ public PropertyMustMatchRule(Expression> expression, public override string FormatErrorMessage(string name) { - return String.Format(CultureInfo.CurrentCulture, - ErrorMessageFormat, - GetPropertyDisplayName(originalPropertyName), - GetPropertyDisplayName(confirmPropertyName) - ); + return String.Format( + CultureInfo.CurrentCulture, + ErrorMessageFormat, + GetPropertyDisplayName(originalPropertyName), + GetPropertyDisplayName(confirmPropertyName) + ); } private string GetPropertyDisplayName(string propertyName) @@ -34,7 +36,9 @@ private string GetPropertyDisplayName(string propertyName) var metaData = FluentMetadataBuilder.GetTypeBuilder(currentType).MetaDataFor(propertyName); if (metaData != null) { - propertyName = string.IsNullOrEmpty(metaData.DisplayName) ? propertyName : metaData.DisplayName; + propertyName = string.IsNullOrEmpty(metaData.DisplayName) ? + propertyName : + metaData.DisplayName; } return propertyName; } @@ -45,8 +49,10 @@ public override bool IsValid(T instance) return true; currentType = instance.GetType(); - return Equals(GetValueFromProperty(instance, originalPropertyName), - GetValueFromProperty(instance, confirmPropertyName)); + return Equals( + GetValueFromProperty(instance, originalPropertyName), + GetValueFromProperty(instance, confirmPropertyName) + ); } private static object GetValueFromProperty(object instance, string propertyName) From 83e5b05e7f79a6d461337503f2d3ca622a3d5128 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 18 Apr 2011 17:30:44 +0200 Subject: [PATCH 20/56] added task for System.Web.Mvc.IClientValidatable support --- Source/FluentMetadata.MVC/FluentModelMetadata.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Source/FluentMetadata.MVC/FluentModelMetadata.cs b/Source/FluentMetadata.MVC/FluentModelMetadata.cs index 3e6c43f..39b6728 100644 --- a/Source/FluentMetadata.MVC/FluentModelMetadata.cs +++ b/Source/FluentMetadata.MVC/FluentModelMetadata.cs @@ -5,14 +5,16 @@ namespace FluentMetadata.MVC { + // TODO think of a way to support System.Web.Mvc.IClientValidatable public class FluentModelMetadata : ModelMetadata { private readonly Metadata metadata; - - public FluentModelMetadata(Metadata metadata , ModelMetadataProvider provider, Func modelAccessor) : base(provider, metadata.ContainerType, modelAccessor, metadata.ModelType, metadata.ModelName) + + public FluentModelMetadata(Metadata metadata, ModelMetadataProvider provider, Func modelAccessor) + : base(provider, metadata.ContainerType, modelAccessor, metadata.ModelType, metadata.ModelName) { this.metadata = metadata; - MetadataMapper.CopyMetadata(metadata,this); + MetadataMapper.CopyMetadata(metadata, this); } public override IEnumerable GetValidators(ControllerContext context) @@ -21,13 +23,13 @@ public override IEnumerable GetValidators(ControllerContext cont { if (rule is IClassRule) { - yield return new ClassRuleModelValidator((IClassRule) rule, this, context); + yield return new ClassRuleModelValidator((IClassRule)rule, this, context); } else { yield return new RuleModelValidator(rule, this, context); } - } + } } } } \ No newline at end of file From 99e72f6a94c25b36bfd457c27d951b9f2ead4860 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 16:14:01 +0200 Subject: [PATCH 21/56] commented untested property mappings in Metadata.CopyMetaDataFrom --- Source/FluentMetadata.Core/MetaData.cs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index b938ee0..412898a 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -32,29 +32,29 @@ internal void CopyMetaDataFrom(Metadata metadata) { //TODO write tests for CopyMetaDataFrom: properties commented here have not associated tests yet //ContainerType = metadata.ContainerType; - DataTypeName = metadata.DataTypeName; + //DataTypeName = metadata.DataTypeName; //Description = metadata.Description; //DisplayFormat = metadata.DisplayFormat; DisplayName = metadata.DisplayName; //EditorFormat = metadata.EditorFormat; //HideSurroundingHtml = metadata.HideSurroundingHtml; - Readonly = metadata.Readonly; + //Readonly = metadata.Readonly; Required = metadata.Required; //ModelType = metadata.ModelType; - NullDisplayText = metadata.NullDisplayText; + //NullDisplayText = metadata.NullDisplayText; //Properties = metadata.Properties; //ModelName = metadata.ModelName; - ShowDisplay = metadata.ShowDisplay; - ShowEditor = metadata.ShowEditor; - TemplateHint = metadata.TemplateHint; + //ShowDisplay = metadata.ShowDisplay; + //ShowEditor = metadata.ShowEditor; + //TemplateHint = metadata.TemplateHint; //Watermark = metadata.Watermark; - ErrorMessage = metadata.ErrorMessage; + //ErrorMessage = metadata.ErrorMessage; //Hidden = metadata.Hidden; - foreach (var rule in metadata.Rules) - { - AddRule(rule); - } + //foreach (var rule in metadata.Rules) + //{ + // AddRule(rule); + //} } #region properties corresponding to System.Web.Mvc.ModelMetadata From 17806f990ef7560b8290c354e7cd3a5755cec748 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 16:15:43 +0200 Subject: [PATCH 22/56] copying DataTypeName on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 13 +++++++++---- Source/FluentMetadata.Core/MetaData.cs | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index 8f4c351..b42ba36 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -5,15 +5,14 @@ namespace FluentMetadata.Specs { public class PropertyMedata_with_WebUserIndexModel : MetadataTestBase { - private Metadata username; - private Metadata id; - private Metadata autorName; + Metadata username, id, autorName, email; public PropertyMedata_with_WebUserIndexModel() { var query = new QueryFluentMetadata(); username = query.GetMetadataFor(typeof(WebUserIndexModel), "Username"); id = query.GetMetadataFor(typeof(WebUserIndexModel), "Id"); + email = query.GetMetadataFor(typeof(WebUserIndexModel), "EMail"); autorName = query.GetMetadataFor(typeof(WebUserIndexModel), "AutorName"); } @@ -62,7 +61,13 @@ public void Id_Required_is_false() [Fact] public void AutorName_DisplayName_is_emaN() { - Assert.Equal("emaN",autorName.DisplayName); + Assert.Equal("emaN", autorName.DisplayName); + } + + [Fact] + public void EMail_DataTypeName_is_EmailAddress() + { + Assert.Equal("EmailAddress", email.DataTypeName); } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 412898a..735b53d 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -32,7 +32,7 @@ internal void CopyMetaDataFrom(Metadata metadata) { //TODO write tests for CopyMetaDataFrom: properties commented here have not associated tests yet //ContainerType = metadata.ContainerType; - //DataTypeName = metadata.DataTypeName; + DataTypeName = metadata.DataTypeName; //Description = metadata.Description; //DisplayFormat = metadata.DisplayFormat; DisplayName = metadata.DisplayName; From 29ef2f80324c2d875a4fb1e3045af6bcc11cae5b Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 16:21:11 +0200 Subject: [PATCH 23/56] copying Description on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 6 ++++++ .../SampleClasses/MetaData/WebUserMetadata.cs | 2 +- Source/FluentMetadata.Core/MetaData.cs | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index b42ba36..63da28a 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -69,5 +69,11 @@ public void EMail_DataTypeName_is_EmailAddress() { Assert.Equal("EmailAddress", email.DataTypeName); } + + [Fact] + public void Username_Description_is_Name_des_Benutzers() + { + Assert.Equal("Name des Benutzers", username.Description); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs index 6d9348d..4fb3f10 100644 --- a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs +++ b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs @@ -7,7 +7,7 @@ public class WebUserMetadata : DomainObjectMetadata public WebUserMetadata() { Property(x => x.Username).Length(3, 256).Is.Required().Is.ReadOnly() - .Display.Name("Benutzername"); + .Display.Name("Benutzername").Description("Name des Benutzers"); Property(x => x.EMail).Length(128).Is.Required().As.EmailAddress() .Display.Name("E-Mail").As.EmailAddress(); Property(x => x.PasswordHash).Length(32, null).Is.Required() diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 735b53d..8513e1a 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -33,7 +33,7 @@ internal void CopyMetaDataFrom(Metadata metadata) //TODO write tests for CopyMetaDataFrom: properties commented here have not associated tests yet //ContainerType = metadata.ContainerType; DataTypeName = metadata.DataTypeName; - //Description = metadata.Description; + Description = metadata.Description; //DisplayFormat = metadata.DisplayFormat; DisplayName = metadata.DisplayName; //EditorFormat = metadata.EditorFormat; From b1bce04d46d15037a93d5d51d608b2f5a86c2695 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 16:27:38 +0200 Subject: [PATCH 24/56] copying DisplayFormat on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 6 ++++++ .../SampleClasses/MetaData/WebUserMetadata.cs | 2 +- Source/FluentMetadata.Core/MetaData.cs | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index 63da28a..79b67f5 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -75,5 +75,11 @@ public void Username_Description_is_Name_des_Benutzers() { Assert.Equal("Name des Benutzers", username.Description); } + + [Fact] + public void EMail_DisplayFormat_is_MailtoLink() + { + Assert.Equal("{0}", email.DisplayFormat); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs index 4fb3f10..aa85bcc 100644 --- a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs +++ b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs @@ -9,7 +9,7 @@ public WebUserMetadata() Property(x => x.Username).Length(3, 256).Is.Required().Is.ReadOnly() .Display.Name("Benutzername").Description("Name des Benutzers"); Property(x => x.EMail).Length(128).Is.Required().As.EmailAddress() - .Display.Name("E-Mail").As.EmailAddress(); + .Display.Name("E-Mail").Display.Format("{0}"); Property(x => x.PasswordHash).Length(32, null).Is.Required() .Should.Not.ShowInDisplay().Should.Not.ShowInEditor(); Property(x => x.Role).UIHint("Roles").Length(256).Is.Required() diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 8513e1a..53ac4c6 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -34,7 +34,7 @@ internal void CopyMetaDataFrom(Metadata metadata) //ContainerType = metadata.ContainerType; DataTypeName = metadata.DataTypeName; Description = metadata.Description; - //DisplayFormat = metadata.DisplayFormat; + DisplayFormat = metadata.DisplayFormat; DisplayName = metadata.DisplayName; //EditorFormat = metadata.EditorFormat; //HideSurroundingHtml = metadata.HideSurroundingHtml; From 2ccb7bfde9f4322b0863ae8347bee8015bf900b2 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 16:34:54 +0200 Subject: [PATCH 25/56] copying EditorFormat on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 6 ++++++ .../SampleClasses/MetaData/WebUserMetadata.cs | 3 ++- Source/FluentMetadata.Core/MetaData.cs | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index 79b67f5..3350de2 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -81,5 +81,11 @@ public void EMail_DisplayFormat_is_MailtoLink() { Assert.Equal("{0}", email.DisplayFormat); } + + [Fact] + public void EMail_EditorFormat_is_plain_value() + { + Assert.Equal("{0}", email.EditorFormat); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs index aa85bcc..13984a3 100644 --- a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs +++ b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs @@ -9,7 +9,8 @@ public WebUserMetadata() Property(x => x.Username).Length(3, 256).Is.Required().Is.ReadOnly() .Display.Name("Benutzername").Description("Name des Benutzers"); Property(x => x.EMail).Length(128).Is.Required().As.EmailAddress() - .Display.Name("E-Mail").Display.Format("{0}"); + .Display.Name("E-Mail").Display.Format("{0}") + .Editor.Format("{0}"); Property(x => x.PasswordHash).Length(32, null).Is.Required() .Should.Not.ShowInDisplay().Should.Not.ShowInEditor(); Property(x => x.Role).UIHint("Roles").Length(256).Is.Required() diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 53ac4c6..7cace23 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -36,7 +36,7 @@ internal void CopyMetaDataFrom(Metadata metadata) Description = metadata.Description; DisplayFormat = metadata.DisplayFormat; DisplayName = metadata.DisplayName; - //EditorFormat = metadata.EditorFormat; + EditorFormat = metadata.EditorFormat; //HideSurroundingHtml = metadata.HideSurroundingHtml; //Readonly = metadata.Readonly; Required = metadata.Required; From e6636eecbede5c80edf1a46285477d92684631bd Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 16:42:37 +0200 Subject: [PATCH 26/56] copying HideSurroundingHtml on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 7 +++++++ Source/FluentMetadata.Core/MetaData.cs | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index 3350de2..3f7a01f 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -87,5 +87,12 @@ public void EMail_EditorFormat_is_plain_value() { Assert.Equal("{0}", email.EditorFormat); } + + [Fact] + public void Id_HideSurroundingHtml_is_true() + { + Assert.True(id.HideSurroundingHtml.HasValue); + Assert.True(id.HideSurroundingHtml.Value); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 7cace23..e768bc6 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -37,7 +37,7 @@ internal void CopyMetaDataFrom(Metadata metadata) DisplayFormat = metadata.DisplayFormat; DisplayName = metadata.DisplayName; EditorFormat = metadata.EditorFormat; - //HideSurroundingHtml = metadata.HideSurroundingHtml; + HideSurroundingHtml = metadata.HideSurroundingHtml; //Readonly = metadata.Readonly; Required = metadata.Required; //ModelType = metadata.ModelType; From a64a170b6540bae6027819fda00ea4deaebe08c8 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 16:45:32 +0200 Subject: [PATCH 27/56] copying Readonly on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 6 ++++++ Source/FluentMetadata.Core/MetaData.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index 3f7a01f..3396e9c 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -94,5 +94,11 @@ public void Id_HideSurroundingHtml_is_true() Assert.True(id.HideSurroundingHtml.HasValue); Assert.True(id.HideSurroundingHtml.Value); } + + [Fact] + public void Username_ReadOnly_is_true() + { + Assert.True(username.Readonly); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index e768bc6..9ea96ba 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -38,7 +38,7 @@ internal void CopyMetaDataFrom(Metadata metadata) DisplayName = metadata.DisplayName; EditorFormat = metadata.EditorFormat; HideSurroundingHtml = metadata.HideSurroundingHtml; - //Readonly = metadata.Readonly; + Readonly = metadata.Readonly; Required = metadata.Required; //ModelType = metadata.ModelType; //NullDisplayText = metadata.NullDisplayText; From 8b748ac602813321e28e04399a6fc0f6e3245900 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 16:55:28 +0200 Subject: [PATCH 28/56] copying NullDisplayText on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 6 ++++++ .../SampleClasses/MetaData/WebUserMetadata.cs | 3 ++- Source/FluentMetadata.Core/MetaData.cs | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index 3396e9c..f6476f1 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -100,5 +100,11 @@ public void Username_ReadOnly_is_true() { Assert.True(username.Readonly); } + + [Fact] + public void AutorName_NullDisplayText_is_Anonymous_Autor() + { + Assert.Equal("Anonymous Autor", autorName.NullDisplayText); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs index 13984a3..824e3cc 100644 --- a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs +++ b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs @@ -35,7 +35,8 @@ public class AutorMetadata : DomainObjectMetadata { public AutorMetadata() { - Property(e => e.Name).Display.Name("emaN"); + Property(e => e.Name).Display.Name("emaN") + .Display.NullText("Anonymous Autor"); } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 9ea96ba..9ce0a53 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -41,7 +41,7 @@ internal void CopyMetaDataFrom(Metadata metadata) Readonly = metadata.Readonly; Required = metadata.Required; //ModelType = metadata.ModelType; - //NullDisplayText = metadata.NullDisplayText; + NullDisplayText = metadata.NullDisplayText; //Properties = metadata.Properties; //ModelName = metadata.ModelName; //ShowDisplay = metadata.ShowDisplay; From b7ac31bebf2b26943184492718abf6e70c2d8dcf Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 17:03:35 +0200 Subject: [PATCH 29/56] copying ShowDisplay on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 6 ++++++ Source/FluentMetadata.Core/MetaData.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index f6476f1..44f3aed 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -106,5 +106,11 @@ public void AutorName_NullDisplayText_is_Anonymous_Autor() { Assert.Equal("Anonymous Autor", autorName.NullDisplayText); } + + [Fact] + public void Id_ShowDisplay_is_false() + { + Assert.False(id.ShowDisplay); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 9ce0a53..969a4d2 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -44,7 +44,7 @@ internal void CopyMetaDataFrom(Metadata metadata) NullDisplayText = metadata.NullDisplayText; //Properties = metadata.Properties; //ModelName = metadata.ModelName; - //ShowDisplay = metadata.ShowDisplay; + ShowDisplay = metadata.ShowDisplay; //ShowEditor = metadata.ShowEditor; //TemplateHint = metadata.TemplateHint; //Watermark = metadata.Watermark; From 4008eb9431394af80674f32bedb746cb9edb5b62 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 17:05:22 +0200 Subject: [PATCH 30/56] copying ShowEditor on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 6 ++++++ Source/FluentMetadata.Core/MetaData.cs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index 44f3aed..03a94bf 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -112,5 +112,11 @@ public void Id_ShowDisplay_is_false() { Assert.False(id.ShowDisplay); } + + [Fact] + public void Id_ShowEditor_is_false() + { + Assert.False(id.ShowEditor); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 969a4d2..14d4d52 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -45,7 +45,7 @@ internal void CopyMetaDataFrom(Metadata metadata) //Properties = metadata.Properties; //ModelName = metadata.ModelName; ShowDisplay = metadata.ShowDisplay; - //ShowEditor = metadata.ShowEditor; + ShowEditor = metadata.ShowEditor; //TemplateHint = metadata.TemplateHint; //Watermark = metadata.Watermark; //ErrorMessage = metadata.ErrorMessage; From 47f0104b13e8693bc00ef1c0e960693e72eabed9 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 17:11:38 +0200 Subject: [PATCH 31/56] copying TemplateHint on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 9 ++++++++- Source/FluentMetadata.Core/MetaData.cs | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index 03a94bf..85c2de5 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -5,7 +5,7 @@ namespace FluentMetadata.Specs { public class PropertyMedata_with_WebUserIndexModel : MetadataTestBase { - Metadata username, id, autorName, email; + Metadata username, id, autorName, email, role; public PropertyMedata_with_WebUserIndexModel() { @@ -14,6 +14,7 @@ public PropertyMedata_with_WebUserIndexModel() id = query.GetMetadataFor(typeof(WebUserIndexModel), "Id"); email = query.GetMetadataFor(typeof(WebUserIndexModel), "EMail"); autorName = query.GetMetadataFor(typeof(WebUserIndexModel), "AutorName"); + role = query.GetMetadataFor(typeof(WebUserIndexModel), "Role"); } [Fact] @@ -118,5 +119,11 @@ public void Id_ShowEditor_is_false() { Assert.False(id.ShowEditor); } + + [Fact] + public void Role_TemplateHint_is_Roles() + { + Assert.Equal("Roles", role.TemplateHint); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 14d4d52..21ab12f 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -46,7 +46,7 @@ internal void CopyMetaDataFrom(Metadata metadata) //ModelName = metadata.ModelName; ShowDisplay = metadata.ShowDisplay; ShowEditor = metadata.ShowEditor; - //TemplateHint = metadata.TemplateHint; + TemplateHint = metadata.TemplateHint; //Watermark = metadata.Watermark; //ErrorMessage = metadata.ErrorMessage; //Hidden = metadata.Hidden; From 35bde532dddf366d6ab37a15707adb7244934365 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 18:14:37 +0200 Subject: [PATCH 32/56] copying Watermark on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 6 ++++++ .../SampleClasses/MetaData/WebUserMetadata.cs | 2 +- Source/FluentMetadata.Core/MetaData.cs | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index 85c2de5..dd5e988 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -125,5 +125,11 @@ public void Role_TemplateHint_is_Roles() { Assert.Equal("Roles", role.TemplateHint); } + + [Fact] + public void EMail_Watermark_is_dummy_address() + { + Assert.Equal("john@doe.com", email.Watermark); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs index 824e3cc..4b78c70 100644 --- a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs +++ b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs @@ -10,7 +10,7 @@ public WebUserMetadata() .Display.Name("Benutzername").Description("Name des Benutzers"); Property(x => x.EMail).Length(128).Is.Required().As.EmailAddress() .Display.Name("E-Mail").Display.Format("{0}") - .Editor.Format("{0}"); + .Editor.Format("{0}").Editor.Watermark("john@doe.com"); Property(x => x.PasswordHash).Length(32, null).Is.Required() .Should.Not.ShowInDisplay().Should.Not.ShowInEditor(); Property(x => x.Role).UIHint("Roles").Length(256).Is.Required() diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 21ab12f..50e8bb1 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -47,7 +47,7 @@ internal void CopyMetaDataFrom(Metadata metadata) ShowDisplay = metadata.ShowDisplay; ShowEditor = metadata.ShowEditor; TemplateHint = metadata.TemplateHint; - //Watermark = metadata.Watermark; + Watermark = metadata.Watermark; //ErrorMessage = metadata.ErrorMessage; //Hidden = metadata.Hidden; From 4f312d04a052dd2408c0627bbd8776e7595a6d27 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 19:07:35 +0200 Subject: [PATCH 33/56] copying ConvertEmptyStringToNull on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 6 ++++++ .../SampleClasses/MetaData/WebUserMetadata.cs | 3 ++- Source/FluentMetadata.Core/MetaData.cs | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index dd5e988..e49c53d 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -131,5 +131,11 @@ public void EMail_Watermark_is_dummy_address() { Assert.Equal("john@doe.com", email.Watermark); } + + [Fact] + public void Username_ConvertEmptyStringToNull_is_false() + { + Assert.False(username.ConvertEmptyStringToNull); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs index 4b78c70..803dd4c 100644 --- a/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs +++ b/Source/FluentMetadata.Core.Specs/SampleClasses/MetaData/WebUserMetadata.cs @@ -7,7 +7,8 @@ public class WebUserMetadata : DomainObjectMetadata public WebUserMetadata() { Property(x => x.Username).Length(3, 256).Is.Required().Is.ReadOnly() - .Display.Name("Benutzername").Description("Name des Benutzers"); + .Display.Name("Benutzername").Description("Name des Benutzers") + .Is.Not.ConvertEmptyStringToNull(); Property(x => x.EMail).Length(128).Is.Required().As.EmailAddress() .Display.Name("E-Mail").Display.Format("{0}") .Editor.Format("{0}").Editor.Watermark("john@doe.com"); diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 50e8bb1..4eb7015 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -32,6 +32,7 @@ internal void CopyMetaDataFrom(Metadata metadata) { //TODO write tests for CopyMetaDataFrom: properties commented here have not associated tests yet //ContainerType = metadata.ContainerType; + ConvertEmptyStringToNull = metadata.ConvertEmptyStringToNull; DataTypeName = metadata.DataTypeName; Description = metadata.Description; DisplayFormat = metadata.DisplayFormat; From 96e77b73d781f7860d91a6ca1f4a15b042af08dd Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 19:30:19 +0200 Subject: [PATCH 34/56] copying Hidden on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 7 +++++++ Source/FluentMetadata.Core/MetaData.cs | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index e49c53d..4108594 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -137,5 +137,12 @@ public void Username_ConvertEmptyStringToNull_is_false() { Assert.False(username.ConvertEmptyStringToNull); } + + [Fact] + public void Id_Hidden_is_true() + { + Assert.True(id.Hidden.HasValue); + Assert.True(id.Hidden.Value); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 4eb7015..bfbe7fb 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -50,7 +50,7 @@ internal void CopyMetaDataFrom(Metadata metadata) TemplateHint = metadata.TemplateHint; Watermark = metadata.Watermark; //ErrorMessage = metadata.ErrorMessage; - //Hidden = metadata.Hidden; + Hidden = metadata.Hidden; //foreach (var rule in metadata.Rules) //{ From 42922a782356a956c1a1df457eb5298865c7b0a0 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 20:19:42 +0200 Subject: [PATCH 35/56] copying Rules on CopyMetadataFrom --- .../PropertyMedata_with_WebUserIndexModel.cs | 8 ++++++++ Source/FluentMetadata.Core/MetaData.cs | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index 4108594..d350dc8 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -144,5 +144,13 @@ public void Id_Hidden_is_true() Assert.True(id.Hidden.HasValue); Assert.True(id.Hidden.Value); } + + [Fact] + public void Username_GetMaximumLength_is_256() + { + var maxLength = username.GetMaximumLength(); + Assert.True(maxLength.HasValue); + Assert.Equal(256, maxLength); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index bfbe7fb..9e6a62b 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -52,10 +52,10 @@ internal void CopyMetaDataFrom(Metadata metadata) //ErrorMessage = metadata.ErrorMessage; Hidden = metadata.Hidden; - //foreach (var rule in metadata.Rules) - //{ - // AddRule(rule); - //} + foreach (var rule in metadata.Rules) + { + AddRule(rule); + } } #region properties corresponding to System.Web.Mvc.ModelMetadata From 3650e3ab1c3f404d1ac325a80b0c9e02d25594a5 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 23:03:33 +0200 Subject: [PATCH 36/56] added XML docs for Metadata.Hidden --- Source/FluentMetadata.Core/MetaData.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 9e6a62b..08d348a 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -289,6 +289,14 @@ internal void CopyMetaDataFrom(Metadata metadata) #endregion public string ErrorMessage { get; set; } + + //~System.Web.Mvc.HiddenInputAttribute + /// + /// Gets or sets a value indicating whether a property or field value should be rendered as a hidden input element. + /// + /// + /// true if the model should be rendered as a hidden input element; otherwise, false. + /// public bool? Hidden { get; set; } public IEnumerable Rules From 7ff2971ac5ed9abf9657fd9b15a2075cae562564 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 23:31:19 +0200 Subject: [PATCH 37/56] updated tasks --- Source/FluentMetadata.Core/MetaData.cs | 5 +++-- Source/FluentMetadata.Core/Rules/StringLengthRule.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 08d348a..18ee2b3 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -149,7 +149,7 @@ internal void CopyMetaDataFrom(Metadata metadata) // Returns: // A value that indicates whether the model is considered a complex type by // the MVC framework. - // TODO MVC2 [in order to complete properties corresponding to System.Web.Mvc.ModelMetadata] public virtual bool IsComplexType { get; } + // MVC2 [in order to complete properties corresponding to System.Web.Mvc.ModelMetadata] public virtual bool IsComplexType { get; } // // Summary: @@ -157,7 +157,7 @@ internal void CopyMetaDataFrom(Metadata metadata) // // Returns: // true if the type is nullable; otherwise, false. - // TODO MVC2 [in order to complete properties corresponding to System.Web.Mvc.ModelMetadata] public bool IsNullableValueType { get; } + // MVC2 [in order to complete properties corresponding to System.Web.Mvc.ModelMetadata] public bool IsNullableValueType { get; } // ~ System.Web.Mvc.ModelMetadata.IsReadOnly /// @@ -288,6 +288,7 @@ internal void CopyMetaDataFrom(Metadata metadata) #endregion + //TODO [DerAlbertCom] What kind of ErrorMessage is this? Write some XML docs and/or tests. public string ErrorMessage { get; set; } //~System.Web.Mvc.HiddenInputAttribute diff --git a/Source/FluentMetadata.Core/Rules/StringLengthRule.cs b/Source/FluentMetadata.Core/Rules/StringLengthRule.cs index bd983f1..05f0033 100644 --- a/Source/FluentMetadata.Core/Rules/StringLengthRule.cs +++ b/Source/FluentMetadata.Core/Rules/StringLengthRule.cs @@ -65,7 +65,7 @@ public override string FormatErrorMessage(string name) // TODO rule equivalent to System.ComponentModel.DataAnnotations.RegularExpressionAttribute - // TODO implement or delete: What does this rule validate? + //TODO [DerAlbertCom] implement or delete: What does this rule validate? public class EqualToRule : Rule { public EqualToRule(string errorMessageFormat) From 48495b80b9812fe3f9eadcb94dde8e854c10630f Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 23:34:05 +0200 Subject: [PATCH 38/56] tested for ContainerType being correct on copied metadata --- .../PropertyMedata_with_WebUserIndexModel.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs index d350dc8..7f2b399 100644 --- a/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs +++ b/Source/FluentMetadata.Core.Specs/PropertyMedata_with_WebUserIndexModel.cs @@ -152,5 +152,11 @@ public void Username_GetMaximumLength_is_256() Assert.True(maxLength.HasValue); Assert.Equal(256, maxLength); } + + [Fact] + public void Username_ContainerType_is_WebUserIndexModel() + { + Assert.Equal(typeof(WebUserIndexModel), username.ContainerType); + } } } \ No newline at end of file From 80f5ea5b58804be03b3baf44070fa8bf4a036fc2 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Sat, 23 Apr 2011 23:35:13 +0200 Subject: [PATCH 39/56] deleted tasks for Metadata properties that don't need to be copied --- Source/FluentMetadata.Core/MetaData.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Source/FluentMetadata.Core/MetaData.cs b/Source/FluentMetadata.Core/MetaData.cs index 18ee2b3..4429b9e 100644 --- a/Source/FluentMetadata.Core/MetaData.cs +++ b/Source/FluentMetadata.Core/MetaData.cs @@ -31,7 +31,6 @@ public Metadata(Metadata metadata, Type containerType) internal void CopyMetaDataFrom(Metadata metadata) { //TODO write tests for CopyMetaDataFrom: properties commented here have not associated tests yet - //ContainerType = metadata.ContainerType; ConvertEmptyStringToNull = metadata.ConvertEmptyStringToNull; DataTypeName = metadata.DataTypeName; Description = metadata.Description; @@ -41,10 +40,7 @@ internal void CopyMetaDataFrom(Metadata metadata) HideSurroundingHtml = metadata.HideSurroundingHtml; Readonly = metadata.Readonly; Required = metadata.Required; - //ModelType = metadata.ModelType; NullDisplayText = metadata.NullDisplayText; - //Properties = metadata.Properties; - //ModelName = metadata.ModelName; ShowDisplay = metadata.ShowDisplay; ShowEditor = metadata.ShowEditor; TemplateHint = metadata.TemplateHint; From f1d0d89cf6d47506fcdc2ac9744e6d3d1838144e Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 15:06:07 +0200 Subject: [PATCH 40/56] wrote task for mapping missing Metadata properties in FluentMetadata.MVC/MetadataMapper --- Source/FluentMetadata.MVC/MetadataMapper.cs | 22 ++++----------------- 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index 265674e..d4c10f7 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -6,10 +6,11 @@ internal static class MetadataMapper { public static void CopyMetadata(Metadata source, ModelMetadata destination) { - destination.DisplayName = source.DisplayName; - destination.ShowForDisplay = source.ShowDisplay; - destination.DataTypeName = GetDataTypeName(source); + //TODO map missing Metadata properties destination.ConvertEmptyStringToNull = source.ConvertEmptyStringToNull; + destination.DataTypeName = GetDataTypeName(source); + destination.DisplayName = source.DisplayName; + //destination.ShowForDisplay = source.ShowDisplay; } private static string GetDataTypeName(Metadata metadata) @@ -20,20 +21,5 @@ private static string GetDataTypeName(Metadata metadata) } return metadata.DataTypeName; } - - - // DisplayName = metaData.DisplayName, - // ShowForDisplay = metaData.ShowDisplay.Value, - // ShowForEdit = metaData.ShowEditor, - // TemplateHint = metaData.TemplateHint, - // IsReadOnly = metaData.Readonly, - // DataTypeName = GetDataTypeName(metaData), - // NullDisplayText = metaData.NullDisplayText, - // DisplayFormatString = metaData.DisplayFormat, - // EditFormatString = metaData.EditorFormat, - // Description = metaData.Description, - // IsRequired = metaData.Required, - // Watermark = metaData.Watermark, - // HideSurroundingHtml = metaData.HideSurroundingHtml } } \ No newline at end of file From c608d16dccbef4705d6203d72edc916618acb8ae Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 15:48:29 +0200 Subject: [PATCH 41/56] added tasks for mapping to ModelMetadata.Description in MVC3 --- .../ConcernOfComparingMetadata.cs | 13 +++++++------ Source/FluentMetadata.MVC/MetadataMapper.cs | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs index 6e74ed9..5ac25cc 100644 --- a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs +++ b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs @@ -81,12 +81,13 @@ public void Equals_DispalyFormatString() Assert.Equal(Expected.DisplayFormatString, Fluent.DisplayFormatString); } - [Observation] - public void Equals_Description() - { - Console.WriteLine(Expected.Description); - Assert.Equal(Expected.Description, Fluent.Description); - } + //TODO [MVC3] ModelMetadata.Description cannot be used with the default provider in MVC2 + //[Observation] + //public void Equals_Description() + //{ + // Console.WriteLine(Expected.Description); + // Assert.Equal(Expected.Description, Fluent.Description); + //} [Observation] public void Equals_EditFormatString() diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index d4c10f7..2b2d36c 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -10,6 +10,7 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) destination.ConvertEmptyStringToNull = source.ConvertEmptyStringToNull; destination.DataTypeName = GetDataTypeName(source); destination.DisplayName = source.DisplayName; + //TODO [MVC3] destination.Description = source.Description; //destination.ShowForDisplay = source.ShowDisplay; } From c9ad039222aa5d191bcd1799198aed2d1b9d1e2e Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 15:56:25 +0200 Subject: [PATCH 42/56] DisplayFormat is copied to ModelMetadata --- Source/FluentMetadata.MVC.Specs/ComplexModel.cs | 2 ++ Source/FluentMetadata.MVC/MetadataMapper.cs | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index 560dcbe..c3e52d6 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -10,6 +10,7 @@ public ComplexModelMetadata() Class.Display.Name("Komplex"); Property(e => e.FirstName).Display.Name("Vorname").Is.Not.ConvertEmptyStringToNull(); Property(e => e.Age).As.Custom("Years"); + Property(e => e.Amount).Display.Format("{0:c}"); } } [DisplayName("Komplex")] @@ -21,6 +22,7 @@ public class ComplexModel public string LastName { get; set; } [DataType("Years")] public int Age { get; set; } + [DisplayFormat(DataFormatString = "{0:c}")] public decimal Amount { get; set; } public char Sex { get; set; } } diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index 2b2d36c..3960bcc 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -9,8 +9,9 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) //TODO map missing Metadata properties destination.ConvertEmptyStringToNull = source.ConvertEmptyStringToNull; destination.DataTypeName = GetDataTypeName(source); - destination.DisplayName = source.DisplayName; //TODO [MVC3] destination.Description = source.Description; + destination.DisplayFormatString = source.DisplayFormat; + destination.DisplayName = source.DisplayName; //destination.ShowForDisplay = source.ShowDisplay; } From 2bdf8cb604db42107ba40708b2e8385a21ad6a69 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 16:10:59 +0200 Subject: [PATCH 43/56] EditorFormat is copied to ModelMetadata --- Source/FluentMetadata.MVC.Specs/ComplexModel.cs | 6 ++++-- Source/FluentMetadata.MVC/MetadataMapper.cs | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index c3e52d6..6289eda 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -10,7 +10,9 @@ public ComplexModelMetadata() Class.Display.Name("Komplex"); Property(e => e.FirstName).Display.Name("Vorname").Is.Not.ConvertEmptyStringToNull(); Property(e => e.Age).As.Custom("Years"); - Property(e => e.Amount).Display.Format("{0:c}"); + Property(e => e.Amount) + .Display.Format("{0:c}") + .Editor.Format("{0:c}"); } } [DisplayName("Komplex")] @@ -22,7 +24,7 @@ public class ComplexModel public string LastName { get; set; } [DataType("Years")] public int Age { get; set; } - [DisplayFormat(DataFormatString = "{0:c}")] + [DisplayFormat(DataFormatString = "{0:c}", ApplyFormatInEditMode = true)] public decimal Amount { get; set; } public char Sex { get; set; } } diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index 3960bcc..1da9ba2 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -12,6 +12,7 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) //TODO [MVC3] destination.Description = source.Description; destination.DisplayFormatString = source.DisplayFormat; destination.DisplayName = source.DisplayName; + destination.EditFormatString = source.EditorFormat; //destination.ShowForDisplay = source.ShowDisplay; } From f86ccd649c53f863040d1f4607dc4c3753d66c41 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 16:24:13 +0200 Subject: [PATCH 44/56] fixed mapping of DataTypeName to ModelMetadata --- Source/FluentMetadata.MVC.Specs/ComplexModel.cs | 5 +++++ .../MetaData_ComplexModel_Specs.cs | 9 +++++++++ Source/FluentMetadata.MVC/MetadataMapper.cs | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index 6289eda..0e1e319 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -1,5 +1,6 @@ using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using System.Web.Mvc; namespace FluentMetadata.MVC.Specs { @@ -8,6 +9,8 @@ public class ComplexModelMetadata : ClassMetadata public ComplexModelMetadata() { Class.Display.Name("Komplex"); + Property(e => e.Id) + .Should.HiddenInput(); Property(e => e.FirstName).Display.Name("Vorname").Is.Not.ConvertEmptyStringToNull(); Property(e => e.Age).As.Custom("Years"); Property(e => e.Amount) @@ -18,6 +21,8 @@ public ComplexModelMetadata() [DisplayName("Komplex")] public class ComplexModel { + [HiddenInput] + public int Id { get; set; } [DisplayName("Vorname")] [DisplayFormat(ConvertEmptyStringToNull = false)] public string FirstName { get; set; } diff --git a/Source/FluentMetadata.MVC.Specs/MetaData_ComplexModel_Specs.cs b/Source/FluentMetadata.MVC.Specs/MetaData_ComplexModel_Specs.cs index e0ceee9..d97a734 100644 --- a/Source/FluentMetadata.MVC.Specs/MetaData_ComplexModel_Specs.cs +++ b/Source/FluentMetadata.MVC.Specs/MetaData_ComplexModel_Specs.cs @@ -35,6 +35,15 @@ public override void CreateMetadata() } } + [Concern(typeof(FluentMetadataProvider))] + public class When_getting_the_Metadata_of_ComplexModel_Property_Id : ConcernOfComplexModel + { + public override void CreateMetadata() + { + CreatePropertyMetadata("Id"); + } + } + [Concern(typeof(FluentMetadataProvider))] public class When_getting_the_Metadata_of_ComplexModel_Property_FirstName : ConcernOfComplexModel { diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index 1da9ba2..68218cc 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -8,7 +8,7 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) { //TODO map missing Metadata properties destination.ConvertEmptyStringToNull = source.ConvertEmptyStringToNull; - destination.DataTypeName = GetDataTypeName(source); + destination.DataTypeName = source.DataTypeName; //TODO [MVC3] destination.Description = source.Description; destination.DisplayFormatString = source.DisplayFormat; destination.DisplayName = source.DisplayName; From 2b79b63a570b3dc36e9adda7efe3fad5027ee3e7 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 16:47:21 +0200 Subject: [PATCH 45/56] HideSurroundingHtml is copied to ModelMetadata --- Source/FluentMetadata.MVC.Specs/ComplexModel.cs | 2 +- Source/FluentMetadata.MVC/MetadataMapper.cs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index 0e1e319..072e532 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -21,7 +21,7 @@ public ComplexModelMetadata() [DisplayName("Komplex")] public class ComplexModel { - [HiddenInput] + [HiddenInput(DisplayValue = false)] public int Id { get; set; } [DisplayName("Vorname")] [DisplayFormat(ConvertEmptyStringToNull = false)] diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index 68218cc..c3bc2f0 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -13,6 +13,10 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) destination.DisplayFormatString = source.DisplayFormat; destination.DisplayName = source.DisplayName; destination.EditFormatString = source.EditorFormat; + if (source.HideSurroundingHtml.HasValue) + { + destination.HideSurroundingHtml = source.HideSurroundingHtml.Value; + } //destination.ShowForDisplay = source.ShowDisplay; } From 73d99ca10b6f93991be97070e09ba387680606c5 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 16:51:21 +0200 Subject: [PATCH 46/56] Readonly is copied to ModelMetadata --- Source/FluentMetadata.MVC.Specs/ComplexModel.cs | 4 +++- .../FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs | 6 ++++++ Source/FluentMetadata.MVC/MetadataMapper.cs | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index 072e532..d61b52c 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -10,7 +10,8 @@ public ComplexModelMetadata() { Class.Display.Name("Komplex"); Property(e => e.Id) - .Should.HiddenInput(); + .Should.HiddenInput() + .Is.ReadOnly(); Property(e => e.FirstName).Display.Name("Vorname").Is.Not.ConvertEmptyStringToNull(); Property(e => e.Age).As.Custom("Years"); Property(e => e.Amount) @@ -22,6 +23,7 @@ public ComplexModelMetadata() public class ComplexModel { [HiddenInput(DisplayValue = false)] + [ReadOnly(true)] public int Id { get; set; } [DisplayName("Vorname")] [DisplayFormat(ConvertEmptyStringToNull = false)] diff --git a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs index 5ac25cc..0547fba 100644 --- a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs +++ b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs @@ -103,5 +103,11 @@ public void Equals_HideSurroundingHtml() Assert.Equal(Expected.HideSurroundingHtml, Fluent.HideSurroundingHtml); } + [Observation] + public void Equals_IsReadOnly() + { + Console.WriteLine(Expected.IsReadOnly); + Assert.Equal(Expected.IsReadOnly, Fluent.IsReadOnly); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index c3bc2f0..c44d973 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -17,6 +17,7 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) { destination.HideSurroundingHtml = source.HideSurroundingHtml.Value; } + destination.IsReadOnly = source.Readonly; //destination.ShowForDisplay = source.ShowDisplay; } From 9cbcacf9f651137b40285f8f18cce5d92cf5b209 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 18:08:36 +0200 Subject: [PATCH 47/56] refactored validation tests to use ComplexModel --- ...ta.cs => ConcernOfValidationComplexData.cs} | 18 +++++++++--------- .../FluentMetadata.MVC.Specs.csproj | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) rename Source/FluentMetadata.MVC.Specs/{ConcernOfValidationSampleData.cs => ConcernOfValidationComplexData.cs} (57%) diff --git a/Source/FluentMetadata.MVC.Specs/ConcernOfValidationSampleData.cs b/Source/FluentMetadata.MVC.Specs/ConcernOfValidationComplexData.cs similarity index 57% rename from Source/FluentMetadata.MVC.Specs/ConcernOfValidationSampleData.cs rename to Source/FluentMetadata.MVC.Specs/ConcernOfValidationComplexData.cs index 55c434e..d227c59 100644 --- a/Source/FluentMetadata.MVC.Specs/ConcernOfValidationSampleData.cs +++ b/Source/FluentMetadata.MVC.Specs/ConcernOfValidationComplexData.cs @@ -1,13 +1,12 @@ -using System; using Xunit; namespace FluentMetadata.MVC.Specs { - [Concern(typeof(SampleModel),"Validation of SampleData")] - public abstract class ConcernOfValidationSampleData : InstanceContextSpecification + [Concern(typeof(ComplexModel), "Validation of ComplexData")] + public abstract class ConcernOfValidationComplexData : InstanceContextSpecification , IUseFixture { - protected readonly SampleModel Model = new SampleModel(); + protected readonly ComplexModel Model = new ComplexModel(); protected override DummyController CreateSut() { @@ -19,7 +18,7 @@ public void SetFixture(FluentMetadataFixture data) } } - public class When_vorname_is_required_and_not_set : ConcernOfValidationSampleData + public class When_FirstName_is_required_and_not_set : ConcernOfValidationComplexData { protected override void Because() { @@ -29,17 +28,18 @@ protected override void Because() [Observation] public void Should_one_error_vorname() { - Sut.ModelState["VornameRequired"].Errors.Count.ShouldBeEqualTo(1); + Sut.ModelState["FirstName"].Errors.Count.ShouldBeEqualTo(1); } } - public class When_vorname_is_required_and_is_set: ConcernOfValidationSampleData + public class When_FirstName_is_required_and_is_set : ConcernOfValidationComplexData { protected override void EstablishContext() { base.EstablishContext(); - Model.VornameRequired = "Albert"; + Model.FirstName = "Albert"; } + protected override void Because() { Sut.ValidateModel(Model); @@ -48,7 +48,7 @@ protected override void Because() [Observation] public void Should_no_error_on_vorname() { - Sut.ModelState["VornameRequired"].ShouldBeNull(); + Sut.ModelState["FirstName"].ShouldBeNull(); } } } \ No newline at end of file diff --git a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj index f62e069..e28d10b 100644 --- a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj +++ b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj @@ -53,7 +53,7 @@ - + From bedb704c563cf891874a6fd8c6f8b5c582a29289 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 18:09:31 +0200 Subject: [PATCH 48/56] removed unneeded tests --- .../FluentMetadata.MVC.Specs.csproj | 3 -- .../MetaData_SampleModel_Specs.cs | 43 ------------------- .../FluentMetadata.MVC.Specs/SampleModel.cs | 7 --- .../SampleModelMetaData.cs | 10 ----- 4 files changed, 63 deletions(-) delete mode 100644 Source/FluentMetadata.MVC.Specs/MetaData_SampleModel_Specs.cs delete mode 100644 Source/FluentMetadata.MVC.Specs/SampleModel.cs delete mode 100644 Source/FluentMetadata.MVC.Specs/SampleModelMetaData.cs diff --git a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj index e28d10b..d0a76a6 100644 --- a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj +++ b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj @@ -55,12 +55,9 @@ - - - diff --git a/Source/FluentMetadata.MVC.Specs/MetaData_SampleModel_Specs.cs b/Source/FluentMetadata.MVC.Specs/MetaData_SampleModel_Specs.cs deleted file mode 100644 index 38149da..0000000 --- a/Source/FluentMetadata.MVC.Specs/MetaData_SampleModel_Specs.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Xunit; - -namespace FluentMetadata.MVC.Specs -{ - [Concern(typeof (FluentMetadataProvider))] - public class When_getting_the_first_Property_Metadata_of_SampleData : ConcernOfComparingMetadata - { - private SampleModel model; - - protected override void EstablishContext() - { - base.EstablishContext(); - model = new SampleModel {VornameRequired = "Albert"}; - } - public override void CreateMetadata() - {Fluent = Sut.GetMetadataForProperties(model, model.GetType()).Single(); - - Expected = OriginalProvider.GetMetadataForProperties(model, model.GetType()).Single(); - } - } - - [Concern(typeof(FluentMetadataProvider))] - public class When_getting_the_Metadata_of_the_Type_SampleData : ConcernOfComparingMetadata - { - private SampleModel model; - - protected override void EstablishContext() - { - base.EstablishContext(); - model = new SampleModel { VornameRequired = "Albert" }; - } - public override void CreateMetadata() - { - Fluent = Sut.GetMetadataForType(()=>model, model.GetType()); - Expected = Sut.GetMetadataForType(() => model, model.GetType()); - } - } - - -} \ No newline at end of file diff --git a/Source/FluentMetadata.MVC.Specs/SampleModel.cs b/Source/FluentMetadata.MVC.Specs/SampleModel.cs deleted file mode 100644 index 2718340..0000000 --- a/Source/FluentMetadata.MVC.Specs/SampleModel.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace FluentMetadata.MVC.Specs -{ - public class SampleModel - { - public string VornameRequired { get; set; } - } -} \ No newline at end of file diff --git a/Source/FluentMetadata.MVC.Specs/SampleModelMetaData.cs b/Source/FluentMetadata.MVC.Specs/SampleModelMetaData.cs deleted file mode 100644 index 1617ef2..0000000 --- a/Source/FluentMetadata.MVC.Specs/SampleModelMetaData.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace FluentMetadata.MVC.Specs -{ - public class SampleModelMetaData : ClassMetadata - { - public SampleModelMetaData() - { - Property(s => s.VornameRequired).Is.Required(); - } - } -} \ No newline at end of file From bb2801a929c0288f639afce4da7ab1a03d52e7ee Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 18:11:26 +0200 Subject: [PATCH 49/56] Required is copied to ModelMetadata --- Source/FluentMetadata.MVC.Specs/ComplexModel.cs | 6 +++++- .../FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs | 7 +++++++ Source/FluentMetadata.MVC/MetadataMapper.cs | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index d61b52c..99f8098 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -12,7 +12,10 @@ public ComplexModelMetadata() Property(e => e.Id) .Should.HiddenInput() .Is.ReadOnly(); - Property(e => e.FirstName).Display.Name("Vorname").Is.Not.ConvertEmptyStringToNull(); + Property(e => e.FirstName) + .Display.Name("Vorname") + .Is.Not.ConvertEmptyStringToNull() + .Is.Required(); Property(e => e.Age).As.Custom("Years"); Property(e => e.Amount) .Display.Format("{0:c}") @@ -27,6 +30,7 @@ public class ComplexModel public int Id { get; set; } [DisplayName("Vorname")] [DisplayFormat(ConvertEmptyStringToNull = false)] + [Required] public string FirstName { get; set; } public string LastName { get; set; } [DataType("Years")] diff --git a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs index 0547fba..fda9f2e 100644 --- a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs +++ b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs @@ -109,5 +109,12 @@ public void Equals_IsReadOnly() Console.WriteLine(Expected.IsReadOnly); Assert.Equal(Expected.IsReadOnly, Fluent.IsReadOnly); } + + [Observation] + public void Equals_IsRequired() + { + Console.WriteLine(Expected.IsRequired); + Assert.Equal(Expected.IsRequired, Fluent.IsRequired); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index c44d973..9c58f68 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -18,6 +18,10 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) destination.HideSurroundingHtml = source.HideSurroundingHtml.Value; } destination.IsReadOnly = source.Readonly; + if (source.Required.HasValue) + { + destination.IsRequired = source.Required.Value; + } //destination.ShowForDisplay = source.ShowDisplay; } From 09b0927fd7921d136f29086d24c77d18bab901ad Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 18:15:13 +0200 Subject: [PATCH 50/56] added test for ModelType being correct on ModelMetadata --- .../ConcernOfComparingMetadata.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs index fda9f2e..21819c0 100644 --- a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs +++ b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs @@ -24,7 +24,6 @@ public void SetFixture(FluentMetadataFixture data) public abstract void CreateMetadata(); - [Observation] public void Equals_ModelMetadata_Properties_Count() { @@ -116,5 +115,12 @@ public void Equals_IsRequired() Console.WriteLine(Expected.IsRequired); Assert.Equal(Expected.IsRequired, Fluent.IsRequired); } + + [Observation] + public void Equals_ModelType() + { + Console.WriteLine(Expected.ModelType); + Assert.Equal(Expected.ModelType, Fluent.ModelType); + } } } \ No newline at end of file From d1fdd8a58ae3e14a6c552f7f8ee98c5b82a5353f Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 18:20:57 +0200 Subject: [PATCH 51/56] NullDisplayText is copied to ModelMetadata --- Source/FluentMetadata.MVC.Specs/ComplexModel.cs | 3 +++ .../FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs | 7 +++++++ Source/FluentMetadata.MVC/MetadataMapper.cs | 1 + 3 files changed, 11 insertions(+) diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index 99f8098..9534bf8 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -16,6 +16,8 @@ public ComplexModelMetadata() .Display.Name("Vorname") .Is.Not.ConvertEmptyStringToNull() .Is.Required(); + Property(e => e.LastName) + .Display.NullText("No lastname set"); Property(e => e.Age).As.Custom("Years"); Property(e => e.Amount) .Display.Format("{0:c}") @@ -32,6 +34,7 @@ public class ComplexModel [DisplayFormat(ConvertEmptyStringToNull = false)] [Required] public string FirstName { get; set; } + [DisplayFormat(NullDisplayText = "No lastname set")] public string LastName { get; set; } [DataType("Years")] public int Age { get; set; } diff --git a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs index 21819c0..df3c49d 100644 --- a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs +++ b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs @@ -122,5 +122,12 @@ public void Equals_ModelType() Console.WriteLine(Expected.ModelType); Assert.Equal(Expected.ModelType, Fluent.ModelType); } + + [Observation] + public void Equals_NullDisplayText() + { + Console.WriteLine(Expected.NullDisplayText); + Assert.Equal(Expected.NullDisplayText, Fluent.NullDisplayText); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index 9c58f68..87ea132 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -22,6 +22,7 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) { destination.IsRequired = source.Required.Value; } + destination.NullDisplayText = source.NullDisplayText; //destination.ShowForDisplay = source.ShowDisplay; } From 6280e943255be81e6b147ad62915af21800fd510 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 18:29:09 +0200 Subject: [PATCH 52/56] ShowDisplay is copied to ModelMetadata --- Source/FluentMetadata.MVC.Specs/ComplexModel.cs | 4 +++- .../FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs | 7 +++++++ Source/FluentMetadata.MVC/MetadataMapper.cs | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index 9534bf8..f10faf6 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -11,7 +11,8 @@ public ComplexModelMetadata() Class.Display.Name("Komplex"); Property(e => e.Id) .Should.HiddenInput() - .Is.ReadOnly(); + .Is.ReadOnly() + .Should.Not.ShowInDisplay(); Property(e => e.FirstName) .Display.Name("Vorname") .Is.Not.ConvertEmptyStringToNull() @@ -29,6 +30,7 @@ public class ComplexModel { [HiddenInput(DisplayValue = false)] [ReadOnly(true)] + [ScaffoldColumn(false)] public int Id { get; set; } [DisplayName("Vorname")] [DisplayFormat(ConvertEmptyStringToNull = false)] diff --git a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs index df3c49d..b50b854 100644 --- a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs +++ b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs @@ -129,5 +129,12 @@ public void Equals_NullDisplayText() Console.WriteLine(Expected.NullDisplayText); Assert.Equal(Expected.NullDisplayText, Fluent.NullDisplayText); } + + [Observation] + public void Equals_ShowForDisplay() + { + Console.WriteLine(Expected.ShowForDisplay); + Assert.Equal(Expected.ShowForDisplay, Fluent.ShowForDisplay); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index 87ea132..e1e7a15 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -23,7 +23,7 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) destination.IsRequired = source.Required.Value; } destination.NullDisplayText = source.NullDisplayText; - //destination.ShowForDisplay = source.ShowDisplay; + destination.ShowForDisplay = source.ShowDisplay; } private static string GetDataTypeName(Metadata metadata) From 751a93a1d49d909f2a9cb126d123536a3c0fe1b4 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 18:31:24 +0200 Subject: [PATCH 53/56] ShowEditor is copied to ModelMetadata --- Source/FluentMetadata.MVC.Specs/ComplexModel.cs | 3 ++- .../FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs | 7 +++++++ Source/FluentMetadata.MVC/MetadataMapper.cs | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index f10faf6..6a0b66f 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -12,7 +12,8 @@ public ComplexModelMetadata() Property(e => e.Id) .Should.HiddenInput() .Is.ReadOnly() - .Should.Not.ShowInDisplay(); + .Should.Not.ShowInDisplay() + .Should.Not.ShowInEditor(); Property(e => e.FirstName) .Display.Name("Vorname") .Is.Not.ConvertEmptyStringToNull() diff --git a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs index b50b854..7d7dadb 100644 --- a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs +++ b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs @@ -136,5 +136,12 @@ public void Equals_ShowForDisplay() Console.WriteLine(Expected.ShowForDisplay); Assert.Equal(Expected.ShowForDisplay, Fluent.ShowForDisplay); } + + [Observation] + public void Equals_ShowForEdit() + { + Console.WriteLine(Expected.ShowForEdit); + Assert.Equal(Expected.ShowForEdit, Fluent.ShowForEdit); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index e1e7a15..59fcf5d 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -24,6 +24,7 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) } destination.NullDisplayText = source.NullDisplayText; destination.ShowForDisplay = source.ShowDisplay; + destination.ShowForEdit = source.ShowEditor; } private static string GetDataTypeName(Metadata metadata) From 147605dd5577cbdc4894a91702b7643268451395 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 18:37:04 +0200 Subject: [PATCH 54/56] TemplateHint is copied to ModelMetadata respecting HiddenInput as well --- Source/FluentMetadata.MVC.Specs/ComplexModel.cs | 5 ++++- .../FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs | 7 +++++++ Source/FluentMetadata.MVC/MetadataMapper.cs | 5 +++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs index 6a0b66f..6becdd5 100644 --- a/Source/FluentMetadata.MVC.Specs/ComplexModel.cs +++ b/Source/FluentMetadata.MVC.Specs/ComplexModel.cs @@ -20,7 +20,9 @@ public ComplexModelMetadata() .Is.Required(); Property(e => e.LastName) .Display.NullText("No lastname set"); - Property(e => e.Age).As.Custom("Years"); + Property(e => e.Age) + .As.Custom("Years") + .UIHint("Spinner"); Property(e => e.Amount) .Display.Format("{0:c}") .Editor.Format("{0:c}"); @@ -40,6 +42,7 @@ public class ComplexModel [DisplayFormat(NullDisplayText = "No lastname set")] public string LastName { get; set; } [DataType("Years")] + [UIHint("Spinner")] public int Age { get; set; } [DisplayFormat(DataFormatString = "{0:c}", ApplyFormatInEditMode = true)] public decimal Amount { get; set; } diff --git a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs index 7d7dadb..be25ae3 100644 --- a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs +++ b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs @@ -143,5 +143,12 @@ public void Equals_ShowForEdit() Console.WriteLine(Expected.ShowForEdit); Assert.Equal(Expected.ShowForEdit, Fluent.ShowForEdit); } + + [Observation] + public void Equals_TemplateHint() + { + Console.WriteLine(Expected.TemplateHint); + Assert.Equal(Expected.TemplateHint, Fluent.TemplateHint); + } } } \ No newline at end of file diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index 59fcf5d..ac9ed04 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -25,15 +25,16 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) destination.NullDisplayText = source.NullDisplayText; destination.ShowForDisplay = source.ShowDisplay; destination.ShowForEdit = source.ShowEditor; + destination.TemplateHint = GetTemplateHint(source); } - private static string GetDataTypeName(Metadata metadata) + private static string GetTemplateHint(Metadata metadata) { if (metadata.Hidden.HasValue && metadata.Hidden.Value) { return "HiddenInput"; } - return metadata.DataTypeName; + return metadata.TemplateHint; } } } \ No newline at end of file From 97ec385fd3d9b17dba8135c42bd70eb7859461f4 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Mon, 25 Apr 2011 18:46:30 +0200 Subject: [PATCH 55/56] added task for mapping ModelMetadata.Watermark in MVC3 --- .../ConcernOfComparingMetadata.cs | 8 ++++++++ Source/FluentMetadata.MVC/MetadataMapper.cs | 1 + 2 files changed, 9 insertions(+) diff --git a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs index be25ae3..10817af 100644 --- a/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs +++ b/Source/FluentMetadata.MVC.Specs/ConcernOfComparingMetadata.cs @@ -150,5 +150,13 @@ public void Equals_TemplateHint() Console.WriteLine(Expected.TemplateHint); Assert.Equal(Expected.TemplateHint, Fluent.TemplateHint); } + + //TODO [MVC3] ModelMetadata.Watermark cannot be used with the default provider in MVC2 + //[Observation] + //public void Equals_Watermark() + //{ + // Console.WriteLine(Expected.Watermark); + // Assert.Equal(Expected.Watermark, Fluent.Watermark); + //} } } \ No newline at end of file diff --git a/Source/FluentMetadata.MVC/MetadataMapper.cs b/Source/FluentMetadata.MVC/MetadataMapper.cs index ac9ed04..45477d2 100644 --- a/Source/FluentMetadata.MVC/MetadataMapper.cs +++ b/Source/FluentMetadata.MVC/MetadataMapper.cs @@ -26,6 +26,7 @@ public static void CopyMetadata(Metadata source, ModelMetadata destination) destination.ShowForDisplay = source.ShowDisplay; destination.ShowForEdit = source.ShowEditor; destination.TemplateHint = GetTemplateHint(source); + //TODO [MVC3] destination.Watermark = source.Watermark; } private static string GetTemplateHint(Metadata metadata) From f9eded149fc06bfa70d2fcf669a0bef4b9640241 Mon Sep 17 00:00:00 2001 From: Holger Schmidt Date: Tue, 29 Mar 2011 15:46:41 +0200 Subject: [PATCH 56/56] added a class diagram giving an overview over the inheritance of the test classes in the MVC.Specs project --- .../FluentMetadata.MVC.Specs.csproj | 3 + .../TestCaseInheritance.cd | 112 ++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 Source/FluentMetadata.MVC.Specs/TestCaseInheritance.cd diff --git a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj index d0a76a6..6815364 100644 --- a/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj +++ b/Source/FluentMetadata.MVC.Specs/FluentMetadata.MVC.Specs.csproj @@ -70,6 +70,9 @@ FluentMetadata.MVC + + +