• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // © 2019 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 package org.unicode.icu.tool.cldrtoicu.mapper;
4 
5 import static org.unicode.icu.tool.cldrtoicu.mapper.DayPeriodsMapperTest.RuleType.AFTERNOON1;
6 import static org.unicode.icu.tool.cldrtoicu.mapper.DayPeriodsMapperTest.RuleType.EVENING1;
7 import static org.unicode.icu.tool.cldrtoicu.mapper.DayPeriodsMapperTest.RuleType.MIDNIGHT;
8 import static org.unicode.icu.tool.cldrtoicu.mapper.DayPeriodsMapperTest.RuleType.MORNING1;
9 import static org.unicode.icu.tool.cldrtoicu.mapper.DayPeriodsMapperTest.RuleType.NIGHT1;
10 import static org.unicode.icu.tool.cldrtoicu.mapper.DayPeriodsMapperTest.RuleType.NOON;
11 import static org.unicode.icu.tool.cldrtoicu.testing.IcuDataSubjectFactory.assertThat;
12 
13 import java.util.Arrays;
14 import java.util.Map;
15 import java.util.Set;
16 
17 import org.junit.Test;
18 import org.junit.runner.RunWith;
19 import org.junit.runners.JUnit4;
20 import org.unicode.cldr.api.CldrData;
21 import org.unicode.cldr.api.CldrDataSupplier;
22 import org.unicode.cldr.api.CldrValue;
23 import org.unicode.icu.tool.cldrtoicu.IcuData;
24 
25 import com.google.common.base.Ascii;
26 import com.google.common.base.Joiner;
27 import com.google.common.collect.ImmutableMap;
28 import com.google.common.collect.ImmutableSet;
29 
30 @RunWith(JUnit4.class)
31 public class DayPeriodsMapperTest {
32     // A subset of rule types for testing.
33     enum RuleType {
34         MORNING1, NOON, AFTERNOON1, EVENING1, NIGHT1, MIDNIGHT;
35 
toString()36         @Override public String toString() {
37             return Ascii.toLowerCase(name());
38         }
39     }
40 
41     // Possible rule names (these are the value attributes).
42     enum RuleName {
43         AT, BEFORE, FROM;
44 
toString()45         @Override public String toString() {
46             return Ascii.toLowerCase(name());
47         }
48     }
49 
50     @Test
testSimple()51     public void testSimple() {
52         Set<String> locales = ImmutableSet.of("en_GB", "en_AU", "en_NZ");
53         CldrData cldrData = cldrData(
54             dayPeriodRule(locales, MORNING1, isBetween("04:00", "12:00")),
55             dayPeriodRule(locales, NOON, isAt("12:00")),
56             dayPeriodRule(locales, AFTERNOON1, isBetween("12:00", "18:00")),
57             dayPeriodRule(locales, EVENING1, isBetween("18:00", "21:00")),
58             dayPeriodRule(locales, NIGHT1, isBetween("21:00", "04:00")),
59             dayPeriodRule(locales, MIDNIGHT, isAt("00:00")));
60 
61         IcuData icuData = DayPeriodsMapper.process(cldrData);
62 
63         assertThat(icuData).hasName("dayPeriods");
64         assertThat(icuData).hasFallback(false);
65         assertThat(icuData).hasValuesFor("/locales/en_AU", "set1");
66         assertThat(icuData).hasValuesFor("/locales/en_GB", "set1");
67         assertThat(icuData).hasValuesFor("/locales/en_NZ", "set1");
68 
69         assertThat(icuData).hasValuesFor("/rules/set1/morning1/from", "04:00");
70         assertThat(icuData).hasValuesFor("/rules/set1/morning1/before", "12:00");
71         assertThat(icuData).hasValuesFor("/rules/set1/noon/at", "12:00");
72         assertThat(icuData).hasValuesFor("/rules/set1/afternoon1/from", "12:00");
73         assertThat(icuData).hasValuesFor("/rules/set1/afternoon1/before", "18:00");
74         assertThat(icuData).hasValuesFor("/rules/set1/evening1/from", "18:00");
75         assertThat(icuData).hasValuesFor("/rules/set1/evening1/before", "21:00");
76         assertThat(icuData).hasValuesFor("/rules/set1/night1/from", "21:00");
77         assertThat(icuData).hasValuesFor("/rules/set1/night1/before", "04:00");
78         assertThat(icuData).hasValuesFor("/rules/set1/midnight/at", "00:00");
79     }
80 
81     @Test
testMultipleRuleSets()82     public void testMultipleRuleSets() {
83         Set<String> locales1 = ImmutableSet.of("en_GB");
84         Set<String> locales2 = ImmutableSet.of("en_AU", "en_NZ");
85         CldrData cldrData = cldrData(
86             dayPeriodRule(locales1, MORNING1, isBetween("04:00", "12:00")),
87             dayPeriodRule(locales1, NOON, isAt("12:00")),
88             dayPeriodRule(locales2, MORNING1, isBetween("06:00", "13:00")),
89             dayPeriodRule(locales2, NOON, isAt("13:00")));
90 
91         IcuData icuData = DayPeriodsMapper.process(cldrData);
92 
93         // This reversal of the set ordering (as compared to the order of the input paths) is
94         // because visitation requires nested path ordering, which is achieved by lexicographical
95         // ordering of path strings ("en_AU" < "en_GB"). This is an implementation detail however
96         // and might one day change. If this were switched to use DTD order, then it would be
97         // stable (but also affect the ordering of paths in the released ICU data).
98         assertThat(icuData).hasValuesFor("/locales/en_AU", "set1");
99         assertThat(icuData).hasValuesFor("/locales/en_NZ", "set1");
100         assertThat(icuData).hasValuesFor("/rules/set1/morning1/from", "06:00");
101         assertThat(icuData).hasValuesFor("/rules/set1/morning1/before", "13:00");
102         assertThat(icuData).hasValuesFor("/rules/set1/noon/at", "13:00");
103 
104         assertThat(icuData).hasValuesFor("/locales/en_GB", "set2");
105         assertThat(icuData).hasValuesFor("/rules/set2/morning1/from", "04:00");
106         assertThat(icuData).hasValuesFor("/rules/set2/morning1/before", "12:00");
107         assertThat(icuData).hasValuesFor("/rules/set2/noon/at", "12:00");
108     }
109 
110     @Test
testRulesetLabels()111     public void testRulesetLabels() {
112         Set<String> locales = ImmutableSet.of("en_GB");
113         // Note that there's an implicit assumption in the mapper that the ruleset label is the
114         // same for all of the rules of any given locale (since it comes from the parent element).
115         CldrData cldrData = cldrData(
116             dayPeriodRule(locales, MORNING1, isBetween("04:00", "12:00"), "foo"),
117             dayPeriodRule(locales, NOON, isAt("12:00"), "foo"));
118 
119         IcuData icuData = DayPeriodsMapper.process(cldrData);
120 
121         assertThat(icuData).hasValuesFor("/locales_foo/en_GB", "set1");
122         assertThat(icuData).hasValuesFor("/rules/set1/morning1/from", "04:00");
123         assertThat(icuData).hasValuesFor("/rules/set1/morning1/before", "12:00");
124         assertThat(icuData).hasValuesFor("/rules/set1/noon/at", "12:00");
125     }
126 
127     // Just demonstrating that the mapper does no data validation.
128     @Test
testNoDataValidation()129     public void testNoDataValidation() {
130         Set<String> locales = ImmutableSet.of("foo", "bar");
131         CldrData cldrData = cldrData(
132             dayPeriodRule(locales, MORNING1, isBetween("start", "end")),
133             dayPeriodRule(locales, NOON, isAt("moment")));
134 
135         IcuData icuData = DayPeriodsMapper.process(cldrData);
136 
137         // This reversal of the set ordering (as compared to the order of the input paths) is
138         // because visitation requires nested path ordering, which is achieved by lexicographical
139         // ordering of path strings. This is an implementation detail however and might one day
140         // change. If this were switched to use DTD order, then it would be stable (but also
141         // affect the ordering of paths in the released ICU data).
142         assertThat(icuData).hasValuesFor("/locales/foo", "set1");
143         assertThat(icuData).hasValuesFor("/locales/bar", "set1");
144         assertThat(icuData).hasValuesFor("/rules/set1/morning1/from", "start");
145         assertThat(icuData).hasValuesFor("/rules/set1/morning1/before", "end");
146         assertThat(icuData).hasValuesFor("/rules/set1/noon/at", "moment");
147     }
148 
cldrData(CldrValue... values)149     private static CldrData cldrData(CldrValue... values) {
150         return CldrDataSupplier.forValues(Arrays.asList(values));
151     }
152 
dayPeriodRule( Set<String> locales, RuleType type, Map<RuleName, String> rules)153     private static CldrValue dayPeriodRule(
154         Set<String> locales, RuleType type, Map<RuleName, String> rules) {
155 
156         return dayPeriodRule(locales, type, rules, null);
157     }
158 
dayPeriodRule( Set<String> locales, RuleType type, Map<RuleName, String> rules, String label)159     private static CldrValue dayPeriodRule(
160         Set<String> locales, RuleType type, Map<RuleName, String> rules, String label) {
161 
162         StringBuilder cldrPath = new StringBuilder("//supplementalData/dayPeriodRuleSet");
163         if (label != null) {
164             appendAttribute(cldrPath, "type", label);
165         }
166         appendAttribute(cldrPath.append("/dayPeriodRules"), "locales", Joiner.on(' ').join(locales));
167         appendAttribute(cldrPath.append("/dayPeriodRule"), "type", type);
168         rules.forEach((k, v) -> cldrPath.append(String.format("[@%s=\"%s\"]", k, v)));
169         return CldrValue.parseValue(cldrPath.toString(), "");
170     }
171 
isAt(String time)172     private static Map<RuleName, String> isAt(String time) {
173         return ImmutableMap.of(RuleName.AT, time);
174     }
175 
isBetween(String from, String to)176     private static Map<RuleName, String> isBetween(String from, String to) {
177         return ImmutableMap.of(RuleName.FROM, from, RuleName.BEFORE, to);
178     }
179 
appendAttribute(StringBuilder out, String k, Object v)180     private static void appendAttribute(StringBuilder out, String k, Object v) {
181         out.append(String.format("[@%s=\"%s\"]", k, v));
182     }
183 }