Skip to content

Commit e072e43

Browse files
committed
Added the PluralLocalizationPlugin, which implements proper "Grammatical Number" rules for most common languages.
1 parent 61f91ef commit e072e43

6 files changed

Lines changed: 526 additions & 124 deletions

File tree

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using NUnit.Framework;
6+
7+
namespace SmartFormat.Tests
8+
{
9+
[TestFixture]
10+
public class PluralLocalizationPluginTests
11+
{
12+
private object[] GetArgs()
13+
{
14+
return new object[] {
15+
0,1,2,3,-1,-2, // {4},{5}
16+
TestFactory.GetPerson(), // {6}
17+
false,true, // {7},{8}
18+
new DateTime(1111,1,1,1,1,1),DateTime.Now,new DateTime(5555,5,5,5,5,5), // {9},{10},{11}
19+
new TimeSpan(-1,-1,-1,-1,-1), TimeSpan.Zero,new TimeSpan(5,5,5,5,5), // {12},{13},{14}
20+
"Hello", "", // {15},{16}
21+
new {NotNull = true}, null, // {17},{18}
22+
};
23+
}
24+
25+
[Test]
26+
public void Test_Numbers()
27+
{
28+
var formats = new[] {
29+
"{0:One|Many} {1:One|Many} {2:One|Many} {3:One|Many} {4:One|Many} {5:One|Many}",
30+
"{0:Zero|One|Many} {1:Zero|One|Many} {2:Zero|One|Many} {3:Zero|One|Many} {4:Zero|One|Many} {5:Zero|One|Many}",
31+
"{0:Neg|Zero|One|Many} {1:Neg|Zero|One|Many} {2:Neg|Zero|One|Many} {3:Neg|Zero|One|Many} {4:Neg|Zero|One|Many} {5:Neg|Zero|One|Many}",
32+
};
33+
var expected = new[] {
34+
"Many One Many Many Many Many",
35+
"Zero One Many Many Many Many",
36+
"Zero One Many Many Neg Neg",
37+
};
38+
39+
var args = GetArgs();
40+
Smart.Default.Test(formats, args, expected);
41+
}
42+
[Test]
43+
public void Test_Enum()
44+
{
45+
var formats = new[] {
46+
"{6.Friends.0:{FirstName} is a {Sex:man|woman}.}",
47+
"{6.Friends.1:{FirstName} is a {Sex:man|woman}.}",
48+
"{9.DayOfWeek:Sunday|Monday|Some other day} / {11.DayOfWeek:Sunday|Monday|Some other day}",
49+
};
50+
var expected = new[] {
51+
"Jim is a man.",
52+
"Pam is a woman.",
53+
"Sunday / Some other day",
54+
};
55+
56+
var args = GetArgs();
57+
Smart.Default.Test(formats, args, expected);
58+
}
59+
[Test]
60+
public void Test_Bool()
61+
{
62+
var formats = new[] {
63+
"{7:Yes|No}",
64+
"{8:Yes|No}",
65+
};
66+
var expected = new[] {
67+
"No",
68+
"Yes",
69+
};
70+
71+
var args = GetArgs();
72+
Smart.Default.Test(formats, args, expected);
73+
}
74+
[Test]
75+
public void Test_Dates()
76+
{
77+
var formats = new[] {
78+
"{9:Past|Future} {10:Past|Future} {11:Past|Future}",
79+
"{9:Past|Present|Future} {10:Past|Present|Future} {11:Past|Present|Future}",
80+
};
81+
var expected = new[] {
82+
"Past Past Future",
83+
"Past Present Future",
84+
};
85+
86+
var args = GetArgs();
87+
Smart.Default.Test(formats, args, expected);
88+
}
89+
[Test]
90+
public void Test_TimeSpan()
91+
{
92+
var formats = new[] {
93+
"{12:Past|Future} {13:Past|Future} {14:Past|Future}",
94+
"{12:Past|Zero|Future} {13:Past|Zero|Future} {14:Past|Zero|Future}",
95+
};
96+
var expected = new[] {
97+
"Past Past Future",
98+
"Past Zero Future",
99+
};
100+
101+
var args = GetArgs();
102+
Smart.Default.Test(formats, args, expected);
103+
}
104+
[Test]
105+
public void Test_Strings()
106+
{
107+
var formats = new[] {
108+
"{15:{}|Empty} {16:{}|Empty} {18:{}|Null}",
109+
};
110+
var expected = new[] {
111+
"Hello Empty Null",
112+
};
113+
114+
var args = GetArgs();
115+
Smart.Default.Test(formats, args, expected);
116+
}
117+
[Test]
118+
public void Test_Object()
119+
{
120+
var formats = new[] {
121+
"{17:{}|Null}; {18:{}|Null}",
122+
};
123+
var expected = new[] {
124+
"{ NotNull = True }; Null",
125+
};
126+
127+
var args = GetArgs();
128+
Smart.Default.Test(formats, args, expected);
129+
}
130+
131+
[Test]
132+
public void Test_ComplexCondition()
133+
{
134+
var args = new object[] {-5, 0, 0.5, 1.0, 1.5, 5.0, 11.0M, 14.0f, 18, 22, 45, 60, 101};
135+
var formats = new[] {
136+
"{0:>0?Positive|<0?Negative|=0?Zero}, {1:>0?Positive|<0?Negative|=0?Zero}, {2:>0?Positive|<0?Negative|=0?Zero}",
137+
"{1:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
138+
"{2:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
139+
"{3:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
140+
"{4:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
141+
"{5:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
142+
"{6:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
143+
"{7:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
144+
"{8:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
145+
"{9:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
146+
"{10:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
147+
"{11:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
148+
"{12:<1?Baby|>=1&<4?Toddler|>=4&<=9?Child|=10/=11/=12?Pre-Teen|<18?Teenager|<20?Young Adult|<20/<=24&<25?Early Twenties|>55&<100?Senior Citizen|>100?Crazy Old|Adult}",
149+
};
150+
var expected = new[] {
151+
"Negative, Zero, Positive",
152+
"Baby",
153+
"Baby",
154+
"Toddler",
155+
"Toddler",
156+
"Child",
157+
"Pre-Teen",
158+
"Teenager",
159+
"Young Adult",
160+
"Early Twenties",
161+
"Adult",
162+
"Senior Citizen",
163+
"Crazy Old",
164+
};
165+
166+
Smart.Default.Test(formats, args, expected);
167+
}
168+
169+
}
170+
}

src/SmartFormat.Tests/SmartFormat.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
<Compile Include="Common\EnumerableExtensions.cs" />
4545
<Compile Include="Common\ExceptionCollection.cs" />
4646
<Compile Include="ConditionalPluginTests.cs" />
47+
<Compile Include="PluralLocalizationPluginTests.cs" />
4748
<Compile Include="GeneralTests.cs" />
4849
<Compile Include="PerformanceTests.cs" />
4950
<Compile Include="ReflectionPluginTests.cs" />

src/SmartFormat/Plugins/LocalizationForPluralsPlugin.cs

Lines changed: 0 additions & 122 deletions
This file was deleted.

0 commit comments

Comments
 (0)