Skip to content

Commit f9c60c7

Browse files
committed
merge from igitur:unit-tests-for-dateformat-parser #106 into development
2 parents bbfb593 + 5b81cd6 commit f9c60c7

File tree

7 files changed

+140
-24
lines changed

7 files changed

+140
-24
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using NUnit.Framework;
2+
using System;
3+
using System.Globalization;
4+
using System.Linq;
5+
6+
namespace LogExpert.Tests
7+
{
8+
[TestFixture]
9+
public class DateFormatParserTest
10+
{
11+
[Test]
12+
public void CanParseAllCultures()
13+
{
14+
var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
15+
16+
foreach (var culture in cultures)
17+
{
18+
if (culture.Name == "dz" || culture.Name.StartsWith("dz-"))
19+
{
20+
Console.WriteLine("The dz (Dzongkha) time format is not supported yet.");
21+
continue;
22+
}
23+
24+
var datePattern = GetDateAndTimeFormat(culture);
25+
var message = $"Culture: {culture.Name} ({culture.EnglishName} {datePattern})";
26+
var sections = Parser.ParseSections(datePattern, out bool syntaxError);
27+
28+
Assert.IsFalse(syntaxError, message);
29+
30+
var dateSection = sections.FirstOrDefault();
31+
Assert.IsNotNull(dateSection, message);
32+
33+
var now = DateTime.Now;
34+
var expectedFormattedDate = now.ToString(datePattern);
35+
var actualFormattedDate = now.ToString(string.Join("", dateSection.GeneralTextDateDurationParts));
36+
Assert.AreEqual(expectedFormattedDate, actualFormattedDate, message);
37+
}
38+
}
39+
40+
[Test]
41+
[TestCase("en-US", "MM", "dd", "yyyy", "hh", "mm", "ss", "tt")]
42+
[TestCase("en-ZA", "yyyy", "MM", "dd", "hh", "mm", "ss", "tt")]
43+
[TestCase("fr-FR", "dd", "MM", "yyyy", "HH", "mm", "ss")]
44+
[TestCase("de-DE", "dd", "MM", "yyyy", "HH", "mm", "ss")]
45+
[TestCase("ar-TN", "dd", "MM", "yyyy", "HH", "mm", "ss")]
46+
[TestCase("as", "dd", "MM", "yyyy", "tt", "hh", "mm", "ss")]
47+
[TestCase("bg", "dd", "MM", "yyyy", "HH", "mm", "ss")]
48+
public void TestDateFormatParserFromCulture(string cultureInfoName, params string[] expectedDateParts)
49+
{
50+
var culture = CultureInfo.GetCultureInfo(cultureInfoName);
51+
52+
var datePattern = GetDateAndTimeFormat(culture);
53+
54+
var sections = Parser.ParseSections(datePattern, out bool syntaxError);
55+
56+
var message = $"Culture: {culture.EnglishName}, Actual date pattern: {datePattern}";
57+
58+
Assert.IsFalse(syntaxError, message);
59+
60+
var dateSection = sections.FirstOrDefault();
61+
Assert.IsNotNull(dateSection);
62+
63+
var dateParts = dateSection
64+
.GeneralTextDateDurationParts
65+
.Where(Token.IsDatePart)
66+
.Select(p => DateFormatPartAdjuster.AdjustDateTimeFormatPart(p))
67+
.ToArray();
68+
69+
Assert.AreEqual(expectedDateParts.Length, dateParts.Length, message);
70+
71+
for (var i = 0; i < expectedDateParts.Length; i++)
72+
{
73+
var expected = expectedDateParts[i];
74+
var actual = dateParts[i];
75+
Assert.AreEqual(expected, actual, message);
76+
}
77+
}
78+
79+
private string GetDateAndTimeFormat(CultureInfo culture)
80+
{
81+
return string.Concat(
82+
culture.DateTimeFormat.ShortDatePattern,
83+
" ",
84+
culture.DateTimeFormat.LongTimePattern
85+
);
86+
}
87+
}
88+
}

src/LogExpert.Tests/LogExpert.Tests.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,18 @@
3939
<ErrorReport>prompt</ErrorReport>
4040
<WarningLevel>4</WarningLevel>
4141
</PropertyGroup>
42+
<PropertyGroup>
43+
<SignAssembly>true</SignAssembly>
44+
</PropertyGroup>
45+
<PropertyGroup>
46+
<AssemblyOriginatorKeyFile>..\Solution Items\Key.snk</AssemblyOriginatorKeyFile>
47+
</PropertyGroup>
4248
<ItemGroup>
4349
<Reference Include="System" />
4450
<Reference Include="System.Core" />
4551
</ItemGroup>
4652
<ItemGroup>
53+
<Compile Include="DateFormatParserTest.cs" />
4754
<Compile Include="Extensions\EnumerableTests.cs" />
4855
<Compile Include="JsonCompactColumnizerTest.cs" />
4956
<Compile Include="JsonColumnizerTest.cs" />
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace LogExpert
5+
{
6+
// Ensures we have constant width (number of characters) date formats
7+
internal static class DateFormatPartAdjuster
8+
{
9+
private static readonly IDictionary<string, string> _dateTimePartReplacements = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
10+
{
11+
["y"] = "yyy",
12+
["yyy"] = "yyyy",
13+
["m"] = "mm",
14+
["d"] = "dd",
15+
["h"] = "hh",
16+
["s"] = "ss"
17+
};
18+
19+
public static string AdjustDateTimeFormatPart(string part)
20+
{
21+
if (!_dateTimePartReplacements.TryGetValue(part, out string adjustedPart))
22+
{
23+
return part;
24+
}
25+
26+
if (char.IsUpper(part[0]))
27+
{
28+
return adjustedPart.ToUpper();
29+
}
30+
else
31+
{
32+
return adjustedPart.ToLower();
33+
}
34+
}
35+
}
36+
}

src/LogExpert/Classes/DateTimeParser/Parser.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ private static bool ReadLiteral(Tokenizer reader)
143143
{
144144
return true;
145145
}
146+
else if (reader.ReadEnclosed('\'', '\''))
147+
{
148+
return true;
149+
}
146150

147151
return false;
148152
}

src/LogExpert/Dialogs/DateTimeDragControl.cs

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ private void InitCustomRects(Section dateSection)
198198
{
199199
this.dateParts = dateSection
200200
.GeneralTextDateDurationParts
201-
.Select(p => AdjustDateTimeFormatPart(p))
201+
.Select(p => DateFormatPartAdjuster.AdjustDateTimeFormatPart(p))
202202
.ToArray();
203203

204204
Rectangle rect = this.ClientRectangle;
@@ -238,28 +238,6 @@ private void InitDigiRects()
238238
InitCustomRects(dateSection);
239239
}
240240

241-
private static IDictionary<string, string> dateTimePartReplacements = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
242-
{
243-
["y"] = "yyy",
244-
["yyy"] = "yyyy",
245-
["m"] = "mm",
246-
["d"] = "dd",
247-
["h"] = "hh",
248-
["s"] = "ss"
249-
};
250-
251-
private static string AdjustDateTimeFormatPart(string part)
252-
{
253-
if (!dateTimePartReplacements.TryGetValue(part, out string adjustedPart))
254-
return part;
255-
256-
257-
if (char.IsUpper(part[0]))
258-
return adjustedPart.ToUpper();
259-
else
260-
return adjustedPart.ToLower();
261-
}
262-
263241
#endregion
264242

265243
#region Events handler

src/LogExpert/LogExpert.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
</Compile>
6161
<Compile Include="Classes\Columnizer\SquareBracketColumnizer.cs" />
6262
<Compile Include="Classes\Columnizer\TimeFormatDeterminer.cs" />
63+
<Compile Include="Classes\DateTimeParser\DateFormatPartAdjuster.cs" />
6364
<Compile Include="Classes\DateTimeParser\Parser.cs" />
6465
<Compile Include="Classes\DateTimeParser\Section.cs" />
6566
<Compile Include="Classes\DateTimeParser\Token.cs" />

src/LogExpert/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@
99
[assembly: AssemblyDescription("Log file viewing for the Pros")]
1010

1111
// The following GUID is for the ID of the typelib if this project is exposed to COM
12-
[assembly: Guid("02f6ebc2-5450-4750-85ec-61d4bd8d6baa")]
12+
[assembly: Guid("02f6ebc2-5450-4750-85ec-61d4bd8d6baa")]
13+
14+
[assembly: InternalsVisibleTo("LogExpert.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100619e9beea345a3bb5e15f55b29ddf40d96e9bb473ae58304fc63dfb3e9c94d8944bb7e45324ee0bef3e345dccba79b0bf64b85a128a7f261861899add639218ddaeb2acc6fcc746d6acb5bb212d375a0967756af192cfdb6cf0bff666a0fe535600abda860d3eafaff4ef1c9b5710181f72d996ca9c29ed64bae4a5fd916dea5")]

0 commit comments

Comments
 (0)