1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package dev.metaschema.core.metapath.item.function;
7   
8   import static dev.metaschema.core.metapath.TestUtils.date;
9   import static dev.metaschema.core.metapath.TestUtils.dateTime;
10  import static dev.metaschema.core.metapath.TestUtils.decimal;
11  import static dev.metaschema.core.metapath.TestUtils.string;
12  import static dev.metaschema.core.metapath.TestUtils.time;
13  import static dev.metaschema.core.metapath.TestUtils.uri;
14  import static dev.metaschema.core.metapath.TestUtils.uuid;
15  import static org.junit.jupiter.api.Assertions.assertAll;
16  import static org.junit.jupiter.api.Assertions.assertEquals;
17  import static org.junit.jupiter.api.Assertions.assertNotEquals;
18  
19  import org.junit.jupiter.params.ParameterizedTest;
20  import org.junit.jupiter.params.provider.Arguments;
21  import org.junit.jupiter.params.provider.MethodSource;
22  
23  import java.util.stream.Stream;
24  
25  import dev.metaschema.core.metapath.item.atomic.IAnyAtomicItem;
26  import dev.metaschema.core.metapath.item.atomic.IDateTimeItem;
27  import edu.umd.cs.findbugs.annotations.NonNull;
28  
29  class IMapKeyTest {
30    private static Stream<Arguments> keyValues() {
31      return Stream.of(
32          // =================
33          // binary-based keys
34          // =================
35          // TODO: generate some test cases
36  
37          // ===================
38          // temporal-based keys
39          // ===================
40          // same keys
41          Arguments.of(
42              true,
43              date("2025-01-13Z"),
44              date("2025-01-13Z")),
45          Arguments.of(
46              true,
47              date("2025-01-13"),
48              date("2025-01-13")),
49          Arguments.of(
50              true,
51              IDateTimeItem.valueOf(date("2025-01-13Z")),
52              dateTime("2025-01-13T00:00:00Z")),
53          Arguments.of(
54              true,
55              dateTime("2025-01-12T23:00:00-01:00"),
56              dateTime("2025-01-13T00:00:00Z")),
57          Arguments.of(
58              true,
59              dateTime("2025-01-12T23:00:00"),
60              dateTime("2025-01-12T23:00:00")),
61          Arguments.of(
62              true,
63              time("23:00:00"),
64              time("23:00:00")),
65          Arguments.of(
66              true,
67              time("24:00:00"),
68              time("24:00:00")),
69          Arguments.of(
70              true,
71              time("00:00:00"),
72              time("00:00:00")),
73          // different keys
74          Arguments.of(
75              false,
76              date("2025-01-13Z"),
77              date("2025-01-13")),
78          Arguments.of(
79              false,
80              date("2025-01-13Z"),
81              dateTime("2025-01-13T00:00:00Z")),
82          Arguments.of(
83              false,
84              date("2025-01-13Z"),
85              time("00:00:00Z")),
86          Arguments.of(
87              false,
88              time("00:00:00Z"),
89              dateTime("2025-01-13T00:00:00Z")),
90          // ==================
91          // decimal-based keys
92          // ==================
93          Arguments.of(
94              true,
95              decimal("0.0"),
96              decimal("0.00")),
97          Arguments.of(
98              true,
99              decimal("10.0"),
100             decimal("10.00")),
101         Arguments.of(
102             true,
103             decimal("-1.0"),
104             decimal("-1.00")),
105         // string-based keys
106         Arguments.of(
107             true,
108             string("https://example.com/resource"),
109             string("https://example.com/resource")),
110         Arguments.of(
111             true,
112             string("https://example.com/resource"),
113             uri("https://example.com/resource")),
114         Arguments.of(
115             false,
116             string("https://example.com/resource"),
117             uri("https://example.com/other-resource")),
118         Arguments.of(
119             true,
120             string("8eb2fb0f-47ac-40be-adb0-1a70fe7fad76"),
121             uuid("8eb2fb0f-47ac-40be-adb0-1a70fe7fad76")),
122         Arguments.of(
123             false,
124             uuid("0889bbb3-e3d3-41d3-bc98-07c18534462a"),
125             uuid("8eb2fb0f-47ac-40be-adb0-1a70fe7fad76")));
126   }
127 
128   @ParameterizedTest
129   @MethodSource("keyValues")
130   void testStringKeys(boolean expectedEquality, @NonNull IAnyAtomicItem item1, @NonNull IAnyAtomicItem item2) {
131     IMapKey key1 = item1.asMapKey();
132     IMapKey key2 = item2.asMapKey();
133 
134     if (expectedEquality) {
135       assertAll(
136           () -> assertEquals(key1, key2, "keys are equivalent"),
137           () -> assertEquals(key2, key1, "keys are reflexively equivalent"),
138           () -> assertEquals(key1.hashCode(), key2.hashCode(), "keys have the same hash code"));
139     } else {
140       assertAll(
141           () -> assertNotEquals(key1, key2, "keys are different"),
142           () -> assertNotEquals(key2, key1, "keys are reflexively different"),
143           () -> assertNotEquals(key1.hashCode(), key2.hashCode(), "keys have different hash codes"));
144     }
145   }
146 }