shell.js (4233B)
1 function GenericPartCreator(type) { 2 return str => ({ type, value: str }); 3 } 4 5 const DateTimeFormatParts = { 6 Weekday: GenericPartCreator("weekday"), 7 Era: GenericPartCreator("era"), 8 Year: GenericPartCreator("year"), 9 YearName: GenericPartCreator("yearName"), 10 RelatedYear: GenericPartCreator("relatedYear"), 11 Month: GenericPartCreator("month"), 12 Day: GenericPartCreator("day"), 13 DayPeriod: GenericPartCreator("dayPeriod"), 14 Hour: GenericPartCreator("hour"), 15 Minute: GenericPartCreator("minute"), 16 Second: GenericPartCreator("second"), 17 FractionalSecond: GenericPartCreator("fractionalSecond"), 18 TimeZoneName: GenericPartCreator("timeZoneName"), 19 Unknown: GenericPartCreator("unknown"), 20 Literal: GenericPartCreator("literal"), 21 }; 22 23 function assertParts(df, x, expected) { 24 var parts = df.formatToParts(x); 25 assertEq(parts.map(part => part.value).join(""), df.format(x), 26 "formatToParts and format must agree"); 27 28 var len = parts.length; 29 assertEq(len, expected.length, "parts count mismatch"); 30 for (var i = 0; i < len; i++) { 31 assertEq(parts[i].type, expected[i].type, "type mismatch at " + i); 32 assertEq(parts[i].value, expected[i].value, "value mismatch at " + i); 33 } 34 35 // Formatted parts must be consistent with the resolved options. 36 var resolvedOptions = df.resolvedOptions(); 37 38 assertEq("dateStyle" in resolvedOptions, false, "dateStyle isn't yet supported here"); 39 assertEq("timeStyle" in resolvedOptions, false, "timeStyle isn't yet supported here"); 40 41 // Every formatted part must be in the resolved options. 42 for (var {type} of expected) { 43 switch (type) { 44 case "weekday": 45 case "era": 46 case "month": 47 case "day": 48 case "hour": 49 case "minute": 50 case "second": 51 case "timeZoneName": 52 assertEq(type in resolvedOptions, true, JSON.stringify(resolvedOptions)); 53 break; 54 55 case "year": 56 case "yearName": 57 case "relatedYear": 58 assertEq("year" in resolvedOptions, true); 59 break; 60 61 case "dayPeriod": 62 assertEq("dayPeriod" in resolvedOptions || resolvedOptions.hour12 === true, true); 63 break; 64 65 case "fractionalSecond": 66 assertEq("fractionalSecondDigits" in resolvedOptions, true); 67 break; 68 69 case "unknown": 70 case "literal": 71 break; 72 73 default: 74 assertEq(true, false, `invalid part: ${type}`); 75 } 76 } 77 78 function includesType(...types) { 79 return parts.some(({type}) => types.includes(type)); 80 } 81 82 // Every resolved option must be in the formatted parts. 83 for (var key of Object.keys(resolvedOptions)) { 84 switch (key) { 85 case "locale": 86 case "calendar": 87 case "numberingSystem": 88 case "timeZone": 89 case "hourCycle": 90 // Skip over non-pattern keys. 91 break; 92 93 case "hour12": 94 if (resolvedOptions.hour12) { 95 assertEq(includesType("dayPeriod"), true); 96 } 97 break; 98 99 case "weekday": 100 case "era": 101 case "month": 102 case "day": 103 case "dayPeriod": 104 case "hour": 105 case "minute": 106 case "second": 107 case "timeZoneName": 108 assertEq(includesType(key), true); 109 break; 110 111 case "year": 112 assertEq(includesType("year", "yearName", "relatedYear"), true); 113 break; 114 115 case "fractionalSecondDigits": 116 assertEq(includesType("fractionalSecond"), true); 117 break; 118 119 default: 120 assertEq(true, false, `invalid key: ${key}`); 121 } 122 } 123 } 124 125 function assertRangeParts(df, start, end, expected) { 126 var parts = df.formatRangeToParts(start, end); 127 assertEq(parts.map(part => part.value).join(""), df.formatRange(start, end), 128 "formatRangeToParts and formatRange must agree"); 129 130 var len = parts.length; 131 assertEq(len, expected.length, "parts count mismatch"); 132 for (var i = 0; i < len; i++) { 133 assertEq(parts[i].type, expected[i].type, "type mismatch at " + i); 134 assertEq(parts[i].value, expected[i].value, "value mismatch at " + i); 135 } 136 }