From 7214646a9d3c9c675444f365c6f14b3a76890347 Mon Sep 17 00:00:00 2001 From: cheng-wei Date: Wed, 27 Nov 2019 08:10:09 +0800 Subject: [PATCH 1/2] Enhance setting renaming --- src/GUI/RevEng.Shared/TableRenamer.cs | 2 + .../ReverseEngineer/InflectorPluralizer.cs | 25 ++++++++++++ .../ReplacingCandidateNamingService.cs | 40 ++----------------- .../ReverseEngineer/StringExtension.cs | 39 ++++++++++++++++++ .../ReverseEngineer20.csproj | 1 + .../ServiceProviderBuilder.cs | 3 +- 6 files changed, 73 insertions(+), 37 deletions(-) create mode 100644 src/GUI/ReverseEngineer20/ReverseEngineer/StringExtension.cs diff --git a/src/GUI/RevEng.Shared/TableRenamer.cs b/src/GUI/RevEng.Shared/TableRenamer.cs index 7b1f1cf15..31a3a7398 100644 --- a/src/GUI/RevEng.Shared/TableRenamer.cs +++ b/src/GUI/RevEng.Shared/TableRenamer.cs @@ -8,6 +8,8 @@ public class TableRenamer public string NewName { get; set; } + public string VariableName { get; set; } + public List Columns { get; set; } } } diff --git a/src/GUI/ReverseEngineer20/ReverseEngineer/InflectorPluralizer.cs b/src/GUI/ReverseEngineer20/ReverseEngineer/InflectorPluralizer.cs index 8a40b12b6..a27cf1662 100644 --- a/src/GUI/ReverseEngineer20/ReverseEngineer/InflectorPluralizer.cs +++ b/src/GUI/ReverseEngineer20/ReverseEngineer/InflectorPluralizer.cs @@ -1,14 +1,36 @@ using Humanizer; using Microsoft.EntityFrameworkCore.Design; +using System.Collections.Generic; +using System.Linq; namespace ReverseEngineer20.ReverseEngineer { public class InflectorPluralizer : IPluralizer { + private readonly Dictionary _customerCharacterPluralize; + private readonly Dictionary _customerCharacterSingularize; + + public InflectorPluralizer(List customReplacers) + { + _customerCharacterPluralize = customReplacers + .SelectMany(x => x.Tables) + .Where(x => !string.IsNullOrWhiteSpace(x.VariableName)) + .ToDictionary(key => key.Name.ToPascalCase(), value => value.VariableName); + + _customerCharacterSingularize = customReplacers + .SelectMany(x => x.Tables) + .Where(x => !string.IsNullOrWhiteSpace(x.NewName)) + .ToDictionary(key => key.Name.ToPascalCase(), value => value.NewName); + + } + public string Pluralize(string name) { if (name != null) { + if (_customerCharacterPluralize.ContainsKey(name)) + return _customerCharacterPluralize[name]; + return name.Pluralize(inputIsKnownToBeSingular: false); } return name; @@ -18,6 +40,9 @@ public string Singularize(string name) { if (name != null) { + if (_customerCharacterSingularize.ContainsKey(name)) + return _customerCharacterSingularize[name]; + return name.Singularize(inputIsKnownToBePlural: false); } return name; diff --git a/src/GUI/ReverseEngineer20/ReverseEngineer/ReplacingCandidateNamingService.cs b/src/GUI/ReverseEngineer20/ReverseEngineer/ReplacingCandidateNamingService.cs index bdf224723..533bf87e4 100644 --- a/src/GUI/ReverseEngineer20/ReverseEngineer/ReplacingCandidateNamingService.cs +++ b/src/GUI/ReverseEngineer20/ReverseEngineer/ReplacingCandidateNamingService.cs @@ -36,8 +36,8 @@ public override string GenerateCandidateIdentifier(DatabaseTable originalTable) if (schema.UseSchemaName) { - candidateStringBuilder.Append(ToPascalCase(originalTable.Schema)); - candidateStringBuilder.Append(ToPascalCase(originalTable.Name)); + candidateStringBuilder.Append(originalTable.Schema.ToPascalCase()); + candidateStringBuilder.Append(originalTable.Name.ToPascalCase()); return candidateStringBuilder.ToString(); } @@ -50,7 +50,7 @@ public override string GenerateCandidateIdentifier(DatabaseTable originalTable) if (string.IsNullOrWhiteSpace(newTableName)) { - candidateStringBuilder.Append(ToPascalCase(originalTable.Name)); + candidateStringBuilder.Append(originalTable.Name.ToPascalCase()); return candidateStringBuilder.ToString(); } @@ -120,7 +120,7 @@ public override string GetDependentEndCandidateNavigationPropertyName(IForeignKe { if (schema.UseSchemaName) { - return ToPascalCase(schema.SchemaName) + baseName; + return schema.SchemaName.ToPascalCase() + baseName; } return baseName; } @@ -133,37 +133,5 @@ public override string GetDependentEndCandidateNavigationPropertyName(IForeignKe private Schema GetSchema(string originalSchema) => _customNameOptions? .FirstOrDefault(x => x.SchemaName == originalSchema); - - private static string ToPascalCase(string value) - { - var candidateStringBuilder = new StringBuilder(); - var previousLetterCharInWordIsLowerCase = false; - var isFirstCharacterInWord = true; - - foreach (var c in value) - { - var isNotLetterOrDigit = !char.IsLetterOrDigit(c); - if (isNotLetterOrDigit - || (previousLetterCharInWordIsLowerCase && char.IsUpper(c))) - { - isFirstCharacterInWord = true; - previousLetterCharInWordIsLowerCase = false; - if (isNotLetterOrDigit) - { - continue; - } - } - - candidateStringBuilder.Append( - isFirstCharacterInWord ? char.ToUpperInvariant(c) : char.ToLowerInvariant(c)); - isFirstCharacterInWord = false; - if (char.IsLower(c)) - { - previousLetterCharInWordIsLowerCase = true; - } - } - - return candidateStringBuilder.ToString(); - } } } diff --git a/src/GUI/ReverseEngineer20/ReverseEngineer/StringExtension.cs b/src/GUI/ReverseEngineer20/ReverseEngineer/StringExtension.cs new file mode 100644 index 000000000..9a3d6081a --- /dev/null +++ b/src/GUI/ReverseEngineer20/ReverseEngineer/StringExtension.cs @@ -0,0 +1,39 @@ +using System.Text; + +namespace ReverseEngineer20.ReverseEngineer +{ + public static class StringExtension + { + public static string ToPascalCase(this string value) + { + var candidateStringBuilder = new StringBuilder(); + var previousLetterCharInWordIsLowerCase = false; + var isFirstCharacterInWord = true; + + foreach (var c in value) + { + var isNotLetterOrDigit = !char.IsLetterOrDigit(c); + if (isNotLetterOrDigit + || (previousLetterCharInWordIsLowerCase && char.IsUpper(c))) + { + isFirstCharacterInWord = true; + previousLetterCharInWordIsLowerCase = false; + if (isNotLetterOrDigit) + { + continue; + } + } + + candidateStringBuilder.Append( + isFirstCharacterInWord ? char.ToUpperInvariant(c) : char.ToLowerInvariant(c)); + isFirstCharacterInWord = false; + if (char.IsLower(c)) + { + previousLetterCharInWordIsLowerCase = true; + } + } + + return candidateStringBuilder.ToString(); + } + } +} diff --git a/src/GUI/ReverseEngineer20/ReverseEngineer20.csproj b/src/GUI/ReverseEngineer20/ReverseEngineer20.csproj index 6afb3ff60..8d57d5c19 100644 --- a/src/GUI/ReverseEngineer20/ReverseEngineer20.csproj +++ b/src/GUI/ReverseEngineer20/ReverseEngineer20.csproj @@ -283,6 +283,7 @@ + diff --git a/src/GUI/ReverseEngineer20/ServiceProviderBuilder.cs b/src/GUI/ReverseEngineer20/ServiceProviderBuilder.cs index c9fd983c3..f9d93515b 100644 --- a/src/GUI/ReverseEngineer20/ServiceProviderBuilder.cs +++ b/src/GUI/ReverseEngineer20/ServiceProviderBuilder.cs @@ -37,7 +37,8 @@ public static ServiceProvider Build(ReverseEngineerOptions options) if (options.CustomReplacers != null) { - serviceCollection.AddSingleton(provider => new ReplacingCandidateNamingService(options.CustomReplacers)); + serviceCollection.AddSingleton(options.CustomReplacers) + .AddSingleton(); } if (options.UseInflector) From b4dfc228237e36fef5667b39620bcaad33e15649 Mon Sep 17 00:00:00 2001 From: cheng-wei Date: Thu, 28 Nov 2019 08:41:24 +0800 Subject: [PATCH 2/2] Add enahance setting name unit tests --- .../ReverseEngineer/InflectorPluralizer.cs | 36 +++---- src/GUI/UnitTests/PluralizerTest.cs | 93 +++++++++++++++++++ 2 files changed, 112 insertions(+), 17 deletions(-) diff --git a/src/GUI/ReverseEngineer20/ReverseEngineer/InflectorPluralizer.cs b/src/GUI/ReverseEngineer20/ReverseEngineer/InflectorPluralizer.cs index a27cf1662..2dc577a4b 100644 --- a/src/GUI/ReverseEngineer20/ReverseEngineer/InflectorPluralizer.cs +++ b/src/GUI/ReverseEngineer20/ReverseEngineer/InflectorPluralizer.cs @@ -7,29 +7,31 @@ namespace ReverseEngineer20.ReverseEngineer { public class InflectorPluralizer : IPluralizer { - private readonly Dictionary _customerCharacterPluralize; - private readonly Dictionary _customerCharacterSingularize; + private readonly Dictionary _customCharacterPluralize; + private readonly Dictionary _customCharacterSingularize; - public InflectorPluralizer(List customReplacers) + public InflectorPluralizer(List customReplacers = null) { - _customerCharacterPluralize = customReplacers - .SelectMany(x => x.Tables) - .Where(x => !string.IsNullOrWhiteSpace(x.VariableName)) - .ToDictionary(key => key.Name.ToPascalCase(), value => value.VariableName); - - _customerCharacterSingularize = customReplacers - .SelectMany(x => x.Tables) - .Where(x => !string.IsNullOrWhiteSpace(x.NewName)) - .ToDictionary(key => key.Name.ToPascalCase(), value => value.NewName); - + if(customReplacers != null) + { + _customCharacterPluralize = customReplacers + .SelectMany(x => x.Tables) + .Where(x => !string.IsNullOrWhiteSpace(x.VariableName)) + .ToDictionary(key => key.Name.ToPascalCase(), value => value.VariableName); + + _customCharacterSingularize = customReplacers + .SelectMany(x => x.Tables) + .Where(x => !string.IsNullOrWhiteSpace(x.NewName)) + .ToDictionary(key => key.Name.ToPascalCase(), value => value.NewName); + } } public string Pluralize(string name) { if (name != null) { - if (_customerCharacterPluralize.ContainsKey(name)) - return _customerCharacterPluralize[name]; + if (_customCharacterPluralize?.ContainsKey(name) ?? false) + return _customCharacterPluralize[name]; return name.Pluralize(inputIsKnownToBeSingular: false); } @@ -40,8 +42,8 @@ public string Singularize(string name) { if (name != null) { - if (_customerCharacterSingularize.ContainsKey(name)) - return _customerCharacterSingularize[name]; + if (_customCharacterSingularize?.ContainsKey(name) ?? false) + return _customCharacterSingularize[name]; return name.Singularize(inputIsKnownToBePlural: false); } diff --git a/src/GUI/UnitTests/PluralizerTest.cs b/src/GUI/UnitTests/PluralizerTest.cs index 524616de4..7ab96026d 100644 --- a/src/GUI/UnitTests/PluralizerTest.cs +++ b/src/GUI/UnitTests/PluralizerTest.cs @@ -1,5 +1,7 @@ using NUnit.Framework; using Humanizer; +using System.Collections.Generic; +using ReverseEngineer20.ReverseEngineer; namespace UnitTests { @@ -405,5 +407,96 @@ public void Issue221(string word, string expectedResult) // Assert Assert.That(result, Is.EqualTo(expectedResult)); } + + [Test] + public void InflectorPluralizerVariables() + { + var expectedResult = "AndroidOtas"; + + var exampleOption = new List + { + new Schema + { + SchemaName = "machine", + UseSchemaName = false, + Tables = new List + { + new TableRenamer + { + Name = "android_ota", + VariableName = "AndroidOtas", + } + } + } + }; + + var sut = new InflectorPluralizer(exampleOption); + + //Act + var result = sut.Pluralize("AndroidOta"); + + //Assert + Assert.That(result, Is.EqualTo(expectedResult)); + } + + [Test] + public void InflectorOriginalPluralizerVariables() + { + var expectedResult = "AndroidOtas"; + + + var sut = new InflectorPluralizer(); + + //Act + var result = sut.Pluralize("AndroidOta");//output is AndroidOta + + //Assert + Assert.That(result, Is.Not.EqualTo(expectedResult)); + } + + [Test] + public void InflectorSingularizeNewName() + { + var expectedResult = "WeatherData"; + + var exampleOption = new List + { + new Schema + { + SchemaName = "machine", + UseSchemaName = false, + Tables = new List + { + new TableRenamer + { + Name = "weather_data", + NewName = "WeatherData", + } + } + } + }; + + var sut = new InflectorPluralizer(exampleOption); + + //Act + var result = sut.Singularize("WeatherData"); + + //Assert + Assert.That(result, Is.EqualTo(expectedResult)); + } + + [Test] + public void InflectorOriginalSingularizeNewName() + { + var expectedResult = "WeatherData"; + + var sut = new InflectorPluralizer(); + + //Act + var result = sut.Singularize("WeatherData"); // Output is WeatherDatum + + //Assert + Assert.That(result, Is.Not.EqualTo(expectedResult)); + } } }