• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16type FormatToPartsResult = [string | undefined, Intl.DateTimeFormatOptions | undefined, Intl.DateTimeRangeFormatPart[]]
17
18const FORMAT_RESULTS = new Array<FormatToPartsResult>()
19
20function addFormatRangeToPartsResult(locale: string | undefined, options: Intl.DateTimeFormatOptions | undefined, result: Intl.DateTimeRangeFormatPart[]): void {
21    const res: [string | undefined, Intl.DateTimeFormatOptions | undefined, Intl.DateTimeRangeFormatPart[]] = [locale, options, result]
22    FORMAT_RESULTS.push(res)
23}
24
25const RANGE_START = new Date("2024-10-11T10:20:30.444Z")
26const RANGE_END = new Date("2024-10-12T20:30:50.444Z")
27
28class RPart implements Intl.DateTimeRangeFormatPart {
29    private _type: Intl.DateTimeFormatPartTypes
30    private _value: string
31    private _source: Intl.DateTimeRangeFormatPartSource
32
33    constructor() {
34        this._type = "literal"
35        this._value = ""
36        this._source = "shared"
37    }
38
39    constructor(type: Intl.DateTimeFormatPartTypes, value: string, source: Intl.DateTimeRangeFormatPartSource) {
40        this._type = type
41        this._value = value
42        this._source = source
43    }
44
45    get type(): Intl.DateTimeFormatPartTypes {
46        return this._type
47    }
48
49    set type(value: Intl.DateTimeFormatPartTypes) {
50        this._type = value
51    }
52
53    get value(): string {
54        return this._value
55    }
56
57    set value(value: string) {
58        this._value = value
59    }
60
61    get source(): Intl.DateTimeRangeFormatPartSource {
62        return this._source
63    }
64
65    set source(source: Intl.DateTimeRangeFormatPartSource) {
66        this._source = source
67    }
68
69    static $_invoke(type: Intl.DateTimeFormatPartTypes, value: string, source: Intl.DateTimeRangeFormatPartSource): RPart {
70        return new RPart(type, value, source)
71    }
72}
73
74function initFormatResults(): void {
75    if (FORMAT_RESULTS.length > 0) {
76        return
77    }
78
79    const resultUS:Intl.DateTimeRangeFormatPart[] = [
80        RPart("month", "10", "startRange"), RPart("literal", "/", "startRange"),
81        RPart("day", "11", "startRange"), RPart("literal", "/", "startRange"),
82        RPart("year", "2024", "startRange"), RPart("literal", " – ", "shared"),
83        RPart("month", "10", "endRange"), RPart("literal", "/", "endRange"),
84        RPart("day", "12", "endRange"), RPart("literal", "/", "endRange"),
85        RPart("year", "2024", "endRange")
86    ]
87
88    addFormatRangeToPartsResult("en-US", { year: "numeric", month: "2-digit", day: "2-digit", timeZone: "UTC" }, resultUS)
89
90    const resultCN:Intl.DateTimeRangeFormatPart[] = [
91        RPart("year", "2024", "startRange"), RPart("literal", "/", "startRange"),
92        RPart("month", "10", "startRange"), RPart("literal", "/", "startRange"),
93        RPart("day", "11", "startRange"), RPart("literal", " – ", "shared"),
94        RPart("year", "2024", "endRange"), RPart("literal", "/", "endRange"),
95        RPart("month", "10", "endRange"), RPart("literal", "/", "endRange"),
96        RPart("day", "12", "endRange")
97    ]
98
99    addFormatRangeToPartsResult("zh-CN", { year: "numeric", month: "2-digit", day: "2-digit", timeZone: "UTC" }, resultCN)
100}
101
102function verifyResults(actual: Intl.DateTimeRangeFormatPart[], expected: Intl.DateTimeRangeFormatPart[]): boolean {
103    if (actual.length != expected.length) {
104        return false
105    }
106
107    for (let i = 0; i < actual.length; i++) {
108        const valid = actual[i].type == expected[i].type
109                && actual[i].value == expected[i].value
110                && actual[i].source == expected[i].source
111
112        if (!valid) {
113            return false
114        }
115    }
116
117    return true
118}
119
120function dateFormatToPartsWithOptions(): void {
121    FORMAT_RESULTS.forEach((res: FormatToPartsResult) => {
122        const locale = res[0]
123        const options = res[1]
124
125        const formatter = new Intl.DateTimeFormat(locale, options)
126        const actualResult = formatter.formatRangeToParts(RANGE_START, RANGE_END)
127        const expectedResult = res[2]
128
129        const resultIsValid = verifyResults(actualResult, expectedResult);
130        if (!resultIsValid) {
131            const range = `${RANGE_START}, ${RANGE_END}`
132            const failMsg = `Unexpected DateTimeFormat(${locale}, ${options}).formatRangeToParts(${range}) result`
133            assertTrue(false, failMsg)
134        }
135    })
136}
137
138function main(): int {
139    initFormatResults()
140
141    const suite = new ArkTestsuite("Intl.DateTimeFormat.formatToParts()")
142    suite.addTest("with formatting options", dateFormatToPartsWithOptions)
143    return suite.run()
144}
145