View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.util.version;
20  
21  import java.util.ArrayList;
22  import java.util.Collections;
23  import java.util.Locale;
24  import java.util.UUID;
25  import java.util.stream.Collectors;
26  import java.util.stream.Stream;
27  
28  import org.eclipse.aether.version.Version;
29  import org.junit.Test;
30  
31  import static java.util.stream.Collectors.toList;
32  import static org.junit.Assert.fail;
33  
34  /**
35   */
36  public class GenericVersionTest extends AbstractVersionTest {
37  
38      protected Version newVersion(String version) {
39          return new GenericVersion(version);
40      }
41  
42      @Test
43      public void testEmptyVersion() {
44          assertOrder(X_EQ_Y, "0", "");
45      }
46  
47      @Test
48      public void testNumericOrdering() {
49          assertOrder(X_LT_Y, "2", "10");
50          assertOrder(X_LT_Y, "1.2", "1.10");
51          assertOrder(X_LT_Y, "1.0.2", "1.0.10");
52          assertOrder(X_LT_Y, "1.0.0.2", "1.0.0.10");
53          assertOrder(X_LT_Y, "1.0.20101206.111434.1", "1.0.20101206.111435.1");
54          assertOrder(X_LT_Y, "1.0.20101206.111434.2", "1.0.20101206.111434.10");
55      }
56  
57      @Test
58      public void testDelimiters() {
59          assertOrder(X_EQ_Y, "1.0", "1-0");
60          assertOrder(X_EQ_Y, "1.0", "1_0");
61          assertOrder(X_EQ_Y, "1.a", "1a");
62      }
63  
64      @Test
65      public void testLeadingZerosAreSemanticallyIrrelevant() {
66          assertOrder(X_EQ_Y, "1", "01");
67          assertOrder(X_EQ_Y, "1.2", "1.002");
68          assertOrder(X_EQ_Y, "1.2.3", "1.2.0003");
69          assertOrder(X_EQ_Y, "1.2.3.4", "1.2.3.00004");
70      }
71  
72      @Test
73      public void testTrailingZerosAreSemanticallyIrrelevant() {
74          assertOrder(X_EQ_Y, "1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0");
75          assertOrder(X_EQ_Y, "1", "1-0-0-0-0-0-0-0-0-0-0-0-0-0");
76          assertOrder(X_EQ_Y, "1", "1.0-0.0-0.0-0.0-0.0-0.0-0.0");
77          assertOrder(X_EQ_Y, "1", "1.0000000000000");
78          assertOrder(X_EQ_Y, "1.0", "1.0.0");
79      }
80  
81      @Test
82      public void testTrailingZerosBeforeQualifierAreSemanticallyIrrelevant() {
83          assertOrder(X_EQ_Y, "1.0-ga", "1.0.0-ga");
84          assertOrder(X_EQ_Y, "1.0.ga", "1.0.0.ga");
85          assertOrder(X_EQ_Y, "1.0ga", "1.0.0ga");
86  
87          assertOrder(X_EQ_Y, "1.0-alpha", "1.0.0-alpha");
88          assertOrder(X_EQ_Y, "1.0.alpha", "1.0.0.alpha");
89          assertOrder(X_EQ_Y, "1.0alpha", "1.0.0alpha");
90          assertOrder(X_EQ_Y, "1.0-alpha-snapshot", "1.0.0-alpha-snapshot");
91          assertOrder(X_EQ_Y, "1.0.alpha.snapshot", "1.0.0.alpha.snapshot");
92  
93          assertOrder(X_EQ_Y, "1.x.0-alpha", "1.x.0.0-alpha");
94          assertOrder(X_EQ_Y, "1.x.0.alpha", "1.x.0.0.alpha");
95          assertOrder(X_EQ_Y, "1.x.0-alpha-snapshot", "1.x.0.0-alpha-snapshot");
96          assertOrder(X_EQ_Y, "1.x.0.alpha.snapshot", "1.x.0.0.alpha.snapshot");
97      }
98  
99      @Test
100     public void testTrailingDelimitersAreSemanticallyIrrelevant() {
101         assertOrder(X_EQ_Y, "1", "1.............");
102         assertOrder(X_EQ_Y, "1", "1-------------");
103         assertOrder(X_EQ_Y, "1.0", "1.............");
104         assertOrder(X_EQ_Y, "1.0", "1-------------");
105     }
106 
107     @Test
108     public void testInitialDelimiters() {
109         assertOrder(X_EQ_Y, "0.1", ".1");
110         assertOrder(X_EQ_Y, "0.0.1", "..1");
111         assertOrder(X_EQ_Y, "0.1", "-1");
112         assertOrder(X_EQ_Y, "0.0.1", "--1");
113     }
114 
115     @Test
116     public void testConsecutiveDelimiters() {
117         assertOrder(X_EQ_Y, "1.0.1", "1..1");
118         assertOrder(X_EQ_Y, "1.0.0.1", "1...1");
119         assertOrder(X_EQ_Y, "1.0.1", "1--1");
120         assertOrder(X_EQ_Y, "1.0.0.1", "1---1");
121     }
122 
123     @Test
124     public void testUnlimitedNumberOfVersionComponents() {
125         assertOrder(X_GT_Y, "1.0.1.2.3.4.5.6.7.8.9.0.1.2.10", "1.0.1.2.3.4.5.6.7.8.9.0.1.2.3");
126     }
127 
128     @Test
129     public void testUnlimitedNumberOfDigitsInNumericComponent() {
130         assertOrder(X_GT_Y, "1.1234567890123456789012345678901", "1.123456789012345678901234567891");
131     }
132 
133     @Test
134     public void testTransitionFromDigitToLetterAndViceVersaIsEqualivantToDelimiter() {
135         assertOrder(X_EQ_Y, "1alpha10", "1.alpha.10");
136         assertOrder(X_EQ_Y, "1alpha10", "1-alpha-10");
137 
138         assertOrder(X_GT_Y, "1.alpha10", "1.alpha2");
139         assertOrder(X_GT_Y, "10alpha", "1alpha");
140     }
141 
142     @Test
143     public void testWellKnownQualifierOrdering() {
144         assertOrder(X_EQ_Y, "1-alpha1", "1-a1");
145         assertOrder(X_LT_Y, "1-alpha", "1-beta");
146         assertOrder(X_EQ_Y, "1-beta1", "1-b1");
147         assertOrder(X_LT_Y, "1-beta", "1-milestone");
148         assertOrder(X_EQ_Y, "1-milestone1", "1-m1");
149         assertOrder(X_LT_Y, "1-milestone", "1-rc");
150         assertOrder(X_EQ_Y, "1-rc", "1-cr");
151         assertOrder(X_LT_Y, "1-rc", "1-snapshot");
152         assertOrder(X_LT_Y, "1-snapshot", "1");
153         assertOrder(X_EQ_Y, "1", "1-ga");
154         assertOrder(X_EQ_Y, "1", "1.ga.0.ga");
155         assertOrder(X_EQ_Y, "1.0", "1-ga");
156         assertOrder(X_EQ_Y, "1", "1-ga.ga");
157         assertOrder(X_EQ_Y, "1", "1-ga-ga");
158         assertOrder(X_EQ_Y, "A", "A.ga.ga");
159         assertOrder(X_EQ_Y, "A", "A-ga-ga");
160         assertOrder(X_EQ_Y, "1", "1-final");
161         assertOrder(X_EQ_Y, "1", "1-release");
162         assertOrder(X_LT_Y, "1", "1-sp");
163 
164         assertOrder(X_LT_Y, "A.rc.1", "A.ga.1");
165         assertOrder(X_GT_Y, "A.sp.1", "A.ga.1");
166         assertOrder(X_LT_Y, "A.rc.x", "A.ga.x");
167         assertOrder(X_GT_Y, "A.sp.x", "A.ga.x");
168     }
169 
170     @Test
171     public void testWellKnownQualifierVersusUnknownQualifierOrdering() {
172         assertOrder(X_GT_Y, "1-abc", "1-alpha");
173         assertOrder(X_GT_Y, "1-abc", "1-beta");
174         assertOrder(X_GT_Y, "1-abc", "1-milestone");
175         assertOrder(X_GT_Y, "1-abc", "1-rc");
176         assertOrder(X_GT_Y, "1-abc", "1-snapshot");
177         assertOrder(X_GT_Y, "1-abc", "1");
178         assertOrder(X_GT_Y, "1-abc", "1-sp");
179     }
180 
181     @Test
182     public void testWellKnownSingleCharQualifiersOnlyRecognizedIfImmediatelyFollowedByNumber() {
183         assertOrder(X_GT_Y, "1.0a", "1.0");
184         assertOrder(X_GT_Y, "1.0-a", "1.0");
185         assertOrder(X_GT_Y, "1.0.a", "1.0");
186         assertOrder(X_GT_Y, "1.0b", "1.0");
187         assertOrder(X_GT_Y, "1.0-b", "1.0");
188         assertOrder(X_GT_Y, "1.0.b", "1.0");
189         assertOrder(X_GT_Y, "1.0m", "1.0");
190         assertOrder(X_GT_Y, "1.0-m", "1.0");
191         assertOrder(X_GT_Y, "1.0.m", "1.0");
192 
193         assertOrder(X_LT_Y, "1.0a1", "1.0");
194         assertOrder(X_LT_Y, "1.0-a1", "1.0");
195         assertOrder(X_LT_Y, "1.0.a1", "1.0");
196         assertOrder(X_LT_Y, "1.0b1", "1.0");
197         assertOrder(X_LT_Y, "1.0-b1", "1.0");
198         assertOrder(X_LT_Y, "1.0.b1", "1.0");
199         assertOrder(X_LT_Y, "1.0m1", "1.0");
200         assertOrder(X_LT_Y, "1.0-m1", "1.0");
201         assertOrder(X_LT_Y, "1.0.m1", "1.0");
202 
203         assertOrder(X_GT_Y, "1.0a.1", "1.0");
204         assertOrder(X_GT_Y, "1.0a-1", "1.0");
205         assertOrder(X_GT_Y, "1.0b.1", "1.0");
206         assertOrder(X_GT_Y, "1.0b-1", "1.0");
207         assertOrder(X_GT_Y, "1.0m.1", "1.0");
208         assertOrder(X_GT_Y, "1.0m-1", "1.0");
209     }
210 
211     @Test
212     public void testUnknownQualifierOrdering() {
213         assertOrder(X_LT_Y, "1-abc", "1-abcd");
214         assertOrder(X_LT_Y, "1-abc", "1-bcd");
215         assertOrder(X_GT_Y, "1-abc", "1-aac");
216     }
217 
218     @Test
219     public void testCaseInsensitiveOrderingOfQualifiers() {
220         assertOrder(X_EQ_Y, "1.alpha", "1.ALPHA");
221         assertOrder(X_EQ_Y, "1.alpha", "1.Alpha");
222 
223         assertOrder(X_EQ_Y, "1.beta", "1.BETA");
224         assertOrder(X_EQ_Y, "1.beta", "1.Beta");
225 
226         assertOrder(X_EQ_Y, "1.milestone", "1.MILESTONE");
227         assertOrder(X_EQ_Y, "1.milestone", "1.Milestone");
228 
229         assertOrder(X_EQ_Y, "1.rc", "1.RC");
230         assertOrder(X_EQ_Y, "1.rc", "1.Rc");
231         assertOrder(X_EQ_Y, "1.cr", "1.CR");
232         assertOrder(X_EQ_Y, "1.cr", "1.Cr");
233 
234         assertOrder(X_EQ_Y, "1.snapshot", "1.SNAPSHOT");
235         assertOrder(X_EQ_Y, "1.snapshot", "1.Snapshot");
236 
237         assertOrder(X_EQ_Y, "1.ga", "1.GA");
238         assertOrder(X_EQ_Y, "1.ga", "1.Ga");
239         assertOrder(X_EQ_Y, "1.final", "1.FINAL");
240         assertOrder(X_EQ_Y, "1.final", "1.Final");
241         assertOrder(X_EQ_Y, "1.release", "1.RELEASE");
242         assertOrder(X_EQ_Y, "1.release", "1.Release");
243 
244         assertOrder(X_EQ_Y, "1.sp", "1.SP");
245         assertOrder(X_EQ_Y, "1.sp", "1.Sp");
246 
247         assertOrder(X_EQ_Y, "1.unknown", "1.UNKNOWN");
248         assertOrder(X_EQ_Y, "1.unknown", "1.Unknown");
249     }
250 
251     @Test
252     public void testCaseInsensitiveOrderingOfQualifiersIsLocaleIndependent() {
253         Locale orig = Locale.getDefault();
254         try {
255             Locale[] locales = {Locale.ENGLISH, new Locale("tr")};
256             for (Locale locale : locales) {
257                 Locale.setDefault(locale);
258                 assertOrder(X_EQ_Y, "1-abcdefghijklmnopqrstuvwxyz", "1-ABCDEFGHIJKLMNOPQRSTUVWXYZ");
259             }
260         } finally {
261             Locale.setDefault(orig);
262         }
263     }
264 
265     @Test
266     public void testQualifierVersusNumberOrdering() {
267         assertOrder(X_LT_Y, "1-ga", "1-1");
268         assertOrder(X_LT_Y, "1.ga", "1.1");
269         assertOrder(X_EQ_Y, "1-ga", "1.0");
270         assertOrder(X_EQ_Y, "1.ga", "1.0");
271 
272         assertOrder(X_LT_Y, "1-ga-1", "1-0-1");
273         assertOrder(X_LT_Y, "1.ga.1", "1.0.1");
274 
275         assertOrder(X_GT_Y, "1.sp", "1.0");
276         assertOrder(X_LT_Y, "1.sp", "1.1");
277 
278         assertOrder(X_LT_Y, "1-abc", "1-1");
279         assertOrder(X_LT_Y, "1.abc", "1.1");
280 
281         assertOrder(X_LT_Y, "1-xyz", "1-1");
282         assertOrder(X_LT_Y, "1.xyz", "1.1");
283     }
284 
285     @Test
286     public void testVersionEvolution() {
287         assertSequence(
288                 "0.9.9-SNAPSHOT",
289                 "0.9.9",
290                 "0.9.10-SNAPSHOT",
291                 "0.9.10",
292                 "1.0-alpha-2-SNAPSHOT",
293                 "1.0-alpha-2",
294                 "1.0-alpha-10-SNAPSHOT",
295                 "1.0-alpha-10",
296                 "1.0-beta-1-SNAPSHOT",
297                 "1.0-beta-1",
298                 "1.0-rc-1-SNAPSHOT",
299                 "1.0-rc-1",
300                 "1.0-SNAPSHOT",
301                 "1.0",
302                 "1.0-sp-1-SNAPSHOT",
303                 "1.0-sp-1",
304                 "1.0.1-alpha-1-SNAPSHOT",
305                 "1.0.1-alpha-1",
306                 "1.0.1-beta-1-SNAPSHOT",
307                 "1.0.1-beta-1",
308                 "1.0.1-rc-1-SNAPSHOT",
309                 "1.0.1-rc-1",
310                 "1.0.1-SNAPSHOT",
311                 "1.0.1",
312                 "1.1-SNAPSHOT",
313                 "1.1");
314 
315         assertSequence("1.0-alpha", "1.0", "1.0-1");
316         assertSequence("1.0.alpha", "1.0", "1.0-1");
317         assertSequence("1.0-alpha", "1.0", "1.0.1");
318         assertSequence("1.0.alpha", "1.0", "1.0.1");
319     }
320 
321     @Test
322     public void testMinimumSegment() {
323         assertOrder(X_LT_Y, "1.min", "1.0-alpha-1");
324         assertOrder(X_LT_Y, "1.min", "1.0-SNAPSHOT");
325         assertOrder(X_LT_Y, "1.min", "1.0");
326         assertOrder(X_LT_Y, "1.min", "1.9999999999");
327 
328         assertOrder(X_EQ_Y, "1.min", "1.MIN");
329 
330         assertOrder(X_GT_Y, "1.min", "0.99999");
331         assertOrder(X_GT_Y, "1.min", "0.max");
332     }
333 
334     @Test
335     public void testMaximumSegment() {
336         assertOrder(X_GT_Y, "1.max", "1.0-alpha-1");
337         assertOrder(X_GT_Y, "1.max", "1.0-SNAPSHOT");
338         assertOrder(X_GT_Y, "1.max", "1.0");
339         assertOrder(X_GT_Y, "1.max", "1.9999999999");
340 
341         assertOrder(X_EQ_Y, "1.max", "1.MAX");
342 
343         assertOrder(X_LT_Y, "1.max", "2.0-alpha-1");
344         assertOrder(X_LT_Y, "1.max", "2.min");
345     }
346 
347     /**
348      * UT for <a href="https://issues.apache.org/jira/browse/MRESOLVER-314">MRESOLVER-314</a>.
349      *
350      * Generates random UUID string based versions and tries to sort them. While this test is not as reliable
351      * as {@link #testCompareUuidVersionStringStream()}, it covers broader range and in case it fails it records
352      * the failed array, so we can investigate more.
353      */
354     @Test
355     public void testCompareUuidRandom() {
356         for (int j = 0; j < 32; j++) {
357             ArrayList<Version> versions = new ArrayList<>();
358             for (int i = 0; i < 64; i++) {
359                 versions.add(newVersion(UUID.randomUUID().toString()));
360             }
361             try {
362                 Collections.sort(versions);
363             } catch (Exception e) {
364                 e.printStackTrace(System.err);
365                 System.err.println("The UUIDs used");
366                 System.err.println(versions.stream().map(Version::toString).collect(Collectors.joining("\n")));
367                 fail("unexpected exception");
368             }
369         }
370     }
371 
372     /**
373      * UT for <a href="https://issues.apache.org/jira/browse/MRESOLVER-314">MRESOLVER-314</a>.
374      *
375      * Works on known set that failed before fix, provided by {@link #uuidVersionStringStream()}.
376      */
377     @Test
378     public void testCompareUuidVersionStringStream() {
379         // this operation below fails with IAEx if comparison is unstable
380         uuidVersionStringStream().map(this::newVersion).sorted().collect(toList());
381     }
382 
383     private Stream<String> uuidVersionStringStream() {
384         return Stream.of(
385                 "e3f6b227-e09d-4461-a030-b8c1755834f7",
386                 "dfdf5e15-b047-4fee-94e5-3ddf6fe90a0c",
387                 "bcc15412-6817-4b64-acef-169d048626f6",
388                 "76093f07-ab1c-4cdd-ae92-9bb500ceed84",
389                 "7ca8dc9f-4e73-459b-8f30-06aa7972f486",
390                 "93fee46b-2715-4abd-877a-4197eb8601aa",
391                 "0379da36-84ee-4d06-9388-83d3aa6536b5",
392                 "4bb2c7a8-cf68-4ca5-8024-72dc93506da9",
393                 "9dcc4cd1-34d2-4499-8dab-3ef8bca9680d",
394                 "ea53d552-83ab-4f7d-852d-98951201083d",
395                 "0bc420d2-4089-468b-bc54-0a4e2835feed",
396                 "318d2433-fe40-4f28-9f3a-4e3d66d9b5fb",
397                 "447b456c-81a4-4f24-9d2e-e5091c39cd19",
398                 "85741f6e-26fe-40d0-a73a-283315409ab2",
399                 "3165b9b2-9f8e-4117-ac70-87056eb45745",
400                 "9d534bf3-a3b0-4a19-9809-670934c10752",
401                 "86d78bba-d84e-4349-aea6-850721e78188",
402                 "06392b8c-e26c-4a83-8ec2-085415bc513d",
403                 "1fb13754-90be-42cb-bc7f-9b9211494e92",
404                 "3018965c-3330-402a-8075-caa7613ec4fa",
405                 "7ecc912b-4938-4411-895e-8ca7cf22ce02",
406                 "6580ada2-4764-45a2-9789-98217d7cf5b6",
407                 "be9d0de4-4ba7-4fdd-8f76-cb579168c549",
408                 "7a8236d6-6bec-4176-b6a1-f869c02183c3",
409                 "089f4195-881c-4f9e-8bc1-124531dee977",
410                 "46ffda62-768a-4864-9581-cc75eafe1a67",
411                 "1d6226f6-dacc-42a9-bd88-7aab1f59df74",
412                 "0948ed55-c25e-4319-9801-5f817bac09b5",
413                 "2fd52f5e-b856-47ad-9e58-45c1d0ba437b",
414                 "6c325bd0-ac6b-4391-a5c5-caa160972fa2",
415                 "d213f6be-f56b-42d2-abda-4300742e0add",
416                 "efaae115-cc21-4b2e-a150-fb4e0d807736",
417                 "30f872e8-9cb5-4b22-b65c-6819ca7a14ba",
418                 "d8e5fb54-6e90-4f74-adb3-451abfbe76a8",
419                 "b47d62b8-9256-47a1-8e21-21ba9639c212",
420                 "b25da555-e1f7-4bc5-92fe-4c895d9c70d8",
421                 "088f0de7-5973-4c10-a7ff-9f3cd7718572",
422                 "b161de76-e5d5-4224-883b-a749b147d63d",
423                 "19b7de96-09fa-4276-843d-c0fbdaf07767",
424                 "e0503f73-33fd-4f9c-812f-8cae3a128c28",
425                 "b8c57488-a42c-43ed-bfb9-acd112d6b68f",
426                 "25997299-0825-4c9b-b0ed-75f935c63fd7",
427                 "2b2e2fcd-3988-45af-855b-7646c0cdbfb5",
428                 "4e6e16b9-2ae4-4593-b907-1febaf3988dc",
429                 "ac8bd519-7fd4-4b85-8154-9dbb87f6cd4f",
430                 "61473b39-b620-468b-abcf-16fe6adfd5cb",
431                 "18e7a548-3f0b-492b-bc19-dce3eec736fa",
432                 "c4d82839-3c46-4eff-b10c-ec0b5bcc600b",
433                 "48f6e90f-924b-4859-9763-3ffe661f5af6",
434                 "48852d79-ba23-475e-b675-a413b989a2a7",
435                 "f7ee0915-ff00-4404-9e9a-6e753d5ff767",
436                 "d6462359-a4e2-45ab-aedc-3b1849b0e6ca",
437                 "e66228de-d1ed-4973-a108-c181d5059fdb",
438                 "d49672a7-177d-475d-aad0-aab0ff4a11b7",
439                 "bfa9337a-0489-4cba-b2db-e0d9d2424e4f",
440                 "dc9bbe34-3c54-4c0f-a3cd-00e96604ae23",
441                 "a8119cf1-9694-4b24-923a-3fc729b5f809",
442                 "5d29cf45-3b9c-4697-85b8-86c81c6ec0c9",
443                 "e3dcb4c2-a867-40f7-a3b1-fb1058a041e5",
444                 "ae240754-2ea2-409a-a92c-648fc7a7b70b",
445                 "8c187383-d59b-4e49-8dfd-98aa5f01925a",
446                 "9b100ee6-71ed-4746-92c2-b5fb02af7ebd",
447                 "f95e94f7-2443-4b2f-a10d-059d8d224dd9",
448                 "b558af80-78bc-43c7-b916-d635a23cc4b5");
449     }
450 }