Skip to content

Commit

Permalink
Merge pull request #797 from Humanizr/pr/712-sort-ignoring-article-pr…
Browse files Browse the repository at this point in the history
…efixes-fixes-694

Rebase of #712
  • Loading branch information
Oren Novotny committed Mar 13, 2019
2 parents f4e9aa5 + da9ed1e commit 81c6dbe
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 15 deletions.
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Expand Up @@ -16,7 +16,7 @@ variables:
steps:
- task: DotNetCoreInstaller@0
inputs:
version: '2.1.500'
version: '2.2.105'

- task: DotNetCoreCLI@2
inputs:
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.build.props
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Version="2.1.23" PrivateAssets="all" />
<PackageReference Include="Nerdbank.GitVersioning" Version="2.3.125" PrivateAssets="all" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta-62925-02" PrivateAssets="All"/>
</ItemGroup>

Expand Down
23 changes: 23 additions & 0 deletions src/Humanizer.Tests.Shared/ArticlePrefixSortTests.cs
@@ -0,0 +1,23 @@
using System;
using Xunit;

namespace Humanizer.Tests
{
public class ArticlePrefixSortTests
{
[Theory]
[InlineData(new[] { "Ant", "The Theater", "The apple", "Fox", "Bear" }, new[] { "Ant", "The apple", "Bear", "Fox", "The Theater" })]
public void SortStringArrayIgnoringArticlePrefixes(string[] input, string[] expectedOutput)
{
Assert.Equal(expectedOutput, EnglishArticle.PrependArticleSuffix(EnglishArticle.AppendArticlePrefix(input)));
}

[Fact]
public void An_Empty_String_Array_Throws_ArgumentOutOfRangeException()
{
string[] items = { };
void action() => EnglishArticle.AppendArticlePrefix(items);
Assert.Throws<ArgumentOutOfRangeException>(action);
}
}
}
Expand Up @@ -59,6 +59,16 @@ namespace Humanizer.Bytes
public static Humanizer.Bytes.ByteSize FromMegabytes(double value) { }
public static Humanizer.Bytes.ByteSize FromTerabytes(double value) { }
public override int GetHashCode() { }
public static Humanizer.Bytes.ByteSize +(Humanizer.Bytes.ByteSize b1, Humanizer.Bytes.ByteSize b2) { }
public static Humanizer.Bytes.ByteSize --(Humanizer.Bytes.ByteSize b) { }
public static bool ==(Humanizer.Bytes.ByteSize b1, Humanizer.Bytes.ByteSize b2) { }
public static bool >(Humanizer.Bytes.ByteSize b1, Humanizer.Bytes.ByteSize b2) { }
public static bool >=(Humanizer.Bytes.ByteSize b1, Humanizer.Bytes.ByteSize b2) { }
public static Humanizer.Bytes.ByteSize ++(Humanizer.Bytes.ByteSize b) { }
public static bool !=(Humanizer.Bytes.ByteSize b1, Humanizer.Bytes.ByteSize b2) { }
public static bool <(Humanizer.Bytes.ByteSize b1, Humanizer.Bytes.ByteSize b2) { }
public static bool <=(Humanizer.Bytes.ByteSize b1, Humanizer.Bytes.ByteSize b2) { }
public static Humanizer.Bytes.ByteSize -(Humanizer.Bytes.ByteSize b) { }
public static Humanizer.Bytes.ByteSize Parse(string s) { }
public Humanizer.Bytes.ByteSize Subtract(Humanizer.Bytes.ByteSize bs) { }
public string ToFullWords() { }
Expand Down Expand Up @@ -150,6 +160,17 @@ namespace Humanizer
public static string ToOrdinalWords(this System.DateTime input) { }
public static string ToOrdinalWords(this System.DateTime input, Humanizer.GrammaticalCase grammaticalCase) { }
}
public class static EnglishArticle
{
public static string[] AppendArticlePrefix(string[] items) { }
public static string[] PrependArticleSuffix(string[] appended) { }
}
public enum EnglishArticles
{
A = 0,
An = 1,
The = 2,
}
public class static EnumDehumanizeExtensions
{
public static TTargetEnum DehumanizeTo<TTargetEnum>(this string input)
Expand Down
12 changes: 6 additions & 6 deletions src/Humanizer.Tests/Humanizer.Tests.csproj
Expand Up @@ -7,16 +7,16 @@
<DefineConstants>$(DefineConstants);NETFX_CORE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="xunit" Version="2.4.0-beta.2.build4010" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0-beta.2.build4010" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0-preview-20180610-02" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<ProjectReference Include="..\Humanizer\Humanizer.csproj" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net46' ">
<Reference Include="System.ComponentModel.DataAnnotations" />
<PackageReference Include="PublicApiGenerator" Version="7.0.1" />
<PackageReference Include="ApiApprover" Version="7.0.1" />
<PackageReference Include="DiffPlex" Version="1.4.1" />
<PackageReference Include="PublicApiGenerator" Version="8.1.0" />
<PackageReference Include="ApiApprover" Version="8.1.0" />
<PackageReference Include="DiffPlex" Version="1.4.3" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Humanizer.Tests.Shared\**\*.cs">
Expand Down
10 changes: 5 additions & 5 deletions src/Humanizer.sln
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2010
# Visual Studio Version 16
VisualStudioVersion = 16.0.28711.165
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Humanizer.Tests", "Humanizer.Tests\Humanizer.Tests.csproj", "{F886A8DA-3EFC-4A89-91DD-06FAF13DA172}"
EndProject
Expand All @@ -12,18 +12,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
..\.editorconfig = ..\.editorconfig
..\.gitattributes = ..\.gitattributes
..\.gitignore = ..\.gitignore
Directory.build.props = Directory.build.props
..\NuSpecs\Humanizer.Core.nuspec = ..\NuSpecs\Humanizer.Core.nuspec
..\NuSpecs\Humanizer.nuspec = ..\NuSpecs\Humanizer.nuspec
..\LICENSE = ..\LICENSE
..\readme.md = ..\readme.md
..\release_notes.md = ..\release_notes.md
..\version.json = ..\version.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{97AAE24D-0488-42AE-A585-86D882F23D5F}"
ProjectSection(SolutionItems) = preProject
..\.vsts-ci.yml = ..\.vsts-ci.yml
..\.vsts-pr.yml = ..\.vsts-pr.yml
..\.vsts-shared.yml = ..\.vsts-shared.yml
..\azure-pipelines.yml = ..\azure-pipelines.yml
..\build.cmd = ..\build.cmd
Humanizer.ruleset = Humanizer.ruleset
EndProjectSection
Expand Down
108 changes: 108 additions & 0 deletions src/Humanizer/ArticlePrefixSort.cs
@@ -0,0 +1,108 @@
using System;
using System.Text.RegularExpressions;

namespace Humanizer
{
/// <summary>
/// Contains methods for removing, appending and prepending article prefixes for sorting strings ignoring the article.
/// </summary>
public static class EnglishArticle
{
/// <summary>
/// Removes the prefixed article and appends it to the same string.
/// </summary>
/// <param name="items">The input array of strings</param>
/// <returns>Sorted string array</returns>
public static string[] AppendArticlePrefix(string[] items)
{
if (items.Length == 0)
{
throw new ArgumentOutOfRangeException(nameof(items));
}

var regex = new Regex("^((The)|(the)|(a)|(A)|(An)|(an))\\s\\w+");
var transformed = new string[items.Length];

for (var i = 0; i < items.Length; i++)
{
if (regex.IsMatch(items[i]))
{
var article = items[i].Substring(0, items[i].IndexOf(" ", StringComparison.CurrentCulture));
var removed = items[i].Remove(0, items[i].IndexOf(" ", StringComparison.CurrentCulture));
var appended = $"{removed} {article}";
transformed[i] = appended.Trim();
}
else
{
transformed[i] = items[i].Trim();
}
}
Array.Sort(transformed);
return transformed;
}

/// <summary>
/// Removes the previously appended article and prepends it to the same string.
/// </summary>
/// <param name="appended">Sorted string array</param>
/// <returns>String array</returns>
public static string[] PrependArticleSuffix(string[] appended)
{
var inserted = new string[appended.Length];

for (var i = 0; i < appended.Length; i++)
{
string suffix;
string original;
if (appended[i].EndsWith(EnglishArticles.The.ToString()))
{
suffix = appended[i].Substring(appended[i].IndexOf(" The", StringComparison.CurrentCulture));
original = ToOriginalFormat(appended, suffix, i);
inserted[i] = original;
}
else if (appended[i].EndsWith(EnglishArticles.A.ToString()))
{
suffix = appended[i].Substring(appended[i].IndexOf(" A", StringComparison.CurrentCulture));
original = ToOriginalFormat(appended, suffix, i);
inserted[i] = original;
}
else if (appended[i].EndsWith(EnglishArticles.An.ToString()))
{
suffix = appended[i].Substring(appended[i].IndexOf(" An", StringComparison.CurrentCulture));
original = ToOriginalFormat(appended, suffix, i);
inserted[i] = original;
}
else if (appended[i].EndsWith(EnglishArticles.A.ToString().ToLowerInvariant()))
{
suffix = appended[i].Substring(appended[i].IndexOf(" a", StringComparison.CurrentCulture));
original = ToOriginalFormat(appended, suffix, i);
inserted[i] = original;
}
else if (appended[i].EndsWith(EnglishArticles.An.ToString().ToLowerInvariant()))
{
suffix = appended[i].Substring(appended[i].IndexOf(" an", StringComparison.CurrentCulture));
original = ToOriginalFormat(appended, suffix, i);
inserted[i] = original;
}
else if (appended[i].EndsWith(EnglishArticles.The.ToString().ToLowerInvariant()))
{
suffix = appended[i].Substring(appended[i].IndexOf(" the", StringComparison.CurrentCulture));
original = ToOriginalFormat(appended, suffix, i);
inserted[i] = original;
}
else
{
inserted[i] = appended[i];
}
}
return inserted;
}

private static string ToOriginalFormat(string[] appended, string suffix, int i)
{
var insertion = appended[i].Remove(appended[i].IndexOf(suffix, StringComparison.CurrentCulture));
var original = $"{suffix} {insertion}";
return original.Trim();
}
}
}
21 changes: 21 additions & 0 deletions src/Humanizer/Articles.cs
@@ -0,0 +1,21 @@
namespace Humanizer
{
/// <summary>
/// Definite and Indefinite English Articles
/// </summary>
public enum EnglishArticles
{
/// <summary>
/// A
/// </summary>
A,
/// <summary>
/// An
/// </summary>
An,
/// <summary>
/// The
/// </summary>
The
}
}
2 changes: 1 addition & 1 deletion src/Humanizer/Humanizer.csproj
Expand Up @@ -6,7 +6,7 @@
<PackageProjectUrl>https://github.com/Humanizr/Humanizer</PackageProjectUrl>
<MinClientVersion>2.12</MinClientVersion>
<Description>A micro-framework that turns your normal strings, type names, enum fields, date fields ETC into a human friendly format</Description>
<Copyright>Copyright © 2012-2018 Mehdi Khalili</Copyright>
<Copyright>Copyright © 2012-2019 .NET Foundation and Contributors</Copyright>
<Product>Humanizer ($(TargetFramework))</Product>
<GenerateDocumentationFile Condition=" '$(Configuration)' == 'Release' ">true</GenerateDocumentationFile>
<SignAssembly>true</SignAssembly>
Expand Down
2 changes: 1 addition & 1 deletion version.json
@@ -1,5 +1,5 @@
{
"version": "2.5",
"version": "2.6",
"publicReleaseRefSpec": [
"^refs/heads/master$", // we release out of master
"^refs/heads/rel/v\\d+\\.\\d+" // we also release branches starting with rel/vN.N
Expand Down

0 comments on commit 81c6dbe

Please sign in to comment.