1+ package org .cloudfoundry .multiapps .mta .model ;
2+
3+ import java .util .stream .Stream ;
4+
5+ import org .junit .jupiter .api .DisplayName ;
6+ import org .junit .jupiter .api .Nested ;
7+ import org .junit .jupiter .api .Test ;
8+ import org .junit .jupiter .params .ParameterizedTest ;
9+ import org .junit .jupiter .params .provider .Arguments ;
10+ import org .junit .jupiter .params .provider .MethodSource ;
11+
12+ import static org .junit .jupiter .api .Assertions .assertEquals ;
13+ import static org .junit .jupiter .api .Assertions .assertFalse ;
14+ import static org .junit .jupiter .api .Assertions .assertNotEquals ;
15+ import static org .junit .jupiter .api .Assertions .assertNotNull ;
16+ import static org .junit .jupiter .api .Assertions .assertThrows ;
17+ import static org .junit .jupiter .api .Assertions .assertTrue ;
18+
19+ class VersionTest {
20+
21+ private static final String UNABLE_TO_PARSE_VERSION = "Unable to parse version" ;
22+
23+ // ---------------------------------------------------------------------------------------------
24+ // PARSING AND NORMALIZATION TESTS
25+ // ---------------------------------------------------------------------------------------------
26+ @ Nested
27+ @ DisplayName ("parseVersion() and normalization behavior" )
28+ class ParseVersionTests {
29+
30+ @ Test
31+ @ DisplayName ("should parse complex versions with build metadata and timestamps" )
32+ void testParseComplexVersions () {
33+ Version v1 = Version .parseVersion ("0.0.1-20251105063220+e303076b5d51da7f0f3a10cd69de018ac0a3853d" );
34+ Version v2 = Version .parseVersion ("1.2.0-20251105043948+cb754700fb069b3367c869938ac6beb396c800e4" );
35+ Version v3 = Version .parseVersion ("1.0.0-SNAPSHOT-20240116224612+200df4832787863cc2f94d998c6cbcd711518933" );
36+
37+ assertNotNull (v1 );
38+ assertNotNull (v2 );
39+ assertNotNull (v3 );
40+
41+ assertVersionParts (v1 , 0 , 0 , 1 );
42+ assertVersionParts (v2 , 1 , 2 , 0 );
43+ assertVersionParts (v3 , 1 , 0 , 0 );
44+ }
45+
46+ private void assertVersionParts (Version version , int major , int minor , int patch ) {
47+ assertEquals (major , version .getMajor ());
48+ assertEquals (minor , version .getMinor ());
49+ assertEquals (patch , version .getPatch ());
50+ }
51+
52+ @ ParameterizedTest (name = "Partial version \" {0}\" should normalize to \" {1}\" " )
53+ @ MethodSource
54+ void testNormalizePartialVersions (String input , String expected ) {
55+ Version version = Version .parseVersion (input );
56+ assertEquals (expected , version .toString ());
57+ }
58+
59+ static Stream <Arguments > testNormalizePartialVersions () {
60+ return Stream .of (
61+ Arguments .of ("1.0.0" , "1.0.0" ),
62+ Arguments .of ("2.1" , "2.1.0" ),
63+ Arguments .of ("2" , "2.0.0" ),
64+ Arguments .of ("1.9.0-SNAPSHOT" , "1.9.0-SNAPSHOT" ),
65+ Arguments .of ("1.9-SNAPSHOT" , "1.9.0" ),
66+ Arguments .of ("1-SNAPSHOT" , "1.0.0" ),
67+ Arguments .of ("1.2.0-beta+exp.sha.5114f85" , "1.2.0-beta+exp.sha.5114f85" ),
68+ Arguments .of ("1.2-beta+exp.sha.5114f85" , "1.2.0" ),
69+ Arguments .of ("1-beta+exp.sha.5114f85" , "1.0.0" ),
70+ Arguments .of ("v1.2.3" , "1.2.3" )
71+ );
72+ }
73+
74+ @ ParameterizedTest (name = "Invalid version \" {0}\" should throw SemverException or ParsingException" )
75+ @ MethodSource
76+ void testInvalidVersions (String invalid , String expectedMessage ) {
77+ Exception ex = assertThrows (Exception .class , () -> Version .parseVersion (invalid ));
78+ assertTrue (ex .getMessage ()
79+ .contains (expectedMessage ));
80+ }
81+
82+ static Stream <Arguments > testInvalidVersions () {
83+ return Stream .of (
84+ Arguments .of ("a.b.c" , UNABLE_TO_PARSE_VERSION ),
85+ Arguments .of ("" , UNABLE_TO_PARSE_VERSION ),
86+ Arguments .of ("null" , UNABLE_TO_PARSE_VERSION ),
87+ Arguments .of ("not-a-version" , UNABLE_TO_PARSE_VERSION )
88+ );
89+ }
90+ }
91+
92+ // ---------------------------------------------------------------------------------------------
93+ // COMPARISON AND EQUALITY TESTS
94+ // ---------------------------------------------------------------------------------------------
95+ @ Nested
96+ @ DisplayName ("compareTo() and equality behavior" )
97+ class CompareTests {
98+
99+ @ Test
100+ void testVersionComparison () {
101+ Version v1 = Version .parseVersion ("1.2.3" );
102+ Version v2 = Version .parseVersion ("1.3.0" );
103+ Version v3 = Version .parseVersion ("1.2.3" );
104+
105+ assertTrue (v1 .compareTo (v2 ) < 0 );
106+ assertTrue (v2 .compareTo (v1 ) > 0 );
107+ assertEquals (0 , v1 .compareTo (v3 ));
108+ }
109+
110+ @ Test
111+ void testEqualsAndHashCode () {
112+ Version v1 = Version .parseVersion ("2.0.0" );
113+ Version v2 = Version .parseVersion ("2.0.0" );
114+ Version v3 = Version .parseVersion ("2.0.1" );
115+
116+ assertEquals (v1 , v2 );
117+ assertNotEquals (v1 , v3 );
118+ assertEquals (v1 .hashCode (), v2 .hashCode ());
119+ assertNotEquals (v1 .hashCode (), v3 .hashCode ());
120+ }
121+ }
122+
123+ // ---------------------------------------------------------------------------------------------
124+ // TO STRING & EDGE CASE TESTS
125+ // ---------------------------------------------------------------------------------------------
126+ @ Nested
127+ class ToStringAndEdgeCases {
128+
129+ @ Test
130+ void testToStringRepresentation () {
131+ String raw = "3.4.5-alpha+build" ;
132+ Version version = Version .parseVersion (raw );
133+ assertEquals (raw , version .toString ());
134+ }
135+
136+ @ Test
137+ void testLargeVersionNumbers () {
138+ Version version = Version .parseVersion ("9999.9999.9999" );
139+ assertEquals (9999 , version .getMajor ());
140+ }
141+
142+ @ Test
143+ void testPreReleaseVersion () {
144+ Version version = Version .parseVersion ("1.0.0-alpha" );
145+ assertTrue (version .toString ()
146+ .contains ("alpha" ));
147+ }
148+ }
149+
150+ // ---------------------------------------------------------------------------------------------
151+ // SATISFIES() RANGE CHECK TESTS
152+ // ---------------------------------------------------------------------------------------------
153+ @ Nested
154+ class SatisfiesBehavior {
155+
156+ @ Test
157+ void testSimpleComparisons () {
158+ Version v = Version .parseVersion ("3.1.4" );
159+
160+ assertTrue (v .satisfies (">3.0.0" ));
161+ assertTrue (v .satisfies (">=3.1.4" ));
162+ assertFalse (v .satisfies ("<3.0.0" ));
163+ assertFalse (v .satisfies ("<=3.1.3" ));
164+ }
165+
166+ @ Test
167+ void testCompositeRanges () {
168+ Version v = Version .parseVersion ("3.1.4" );
169+ assertTrue (v .satisfies (">=3.1.4 <4.0.0" ));
170+ assertTrue (v .satisfies (">=3.0.0 <=3.1.4" ));
171+ assertFalse (v .satisfies (">=3.2.0 <4.0.0" ));
172+ }
173+
174+ @ Test
175+ void testCaretAndTilde () {
176+ Version v = Version .parseVersion ("1.3.5" );
177+ assertTrue (v .satisfies ("^1.3.0" ));
178+ assertTrue (v .satisfies ("~1.3.0" ));
179+ assertFalse (v .satisfies ("^2.0.0" ));
180+ }
181+
182+ @ Test
183+ void testMalformedRequirementsReturnFalse () {
184+ Version v = Version .parseVersion ("3.1.4" );
185+ assertFalse (v .satisfies ("not-a-requirement" ));
186+ assertFalse (v .satisfies ("pesho3.1.4" ));
187+ assertFalse (v .satisfies ("3.1.4.2.3.4.5" ));
188+ }
189+
190+ @ Test
191+ void testNullRequirement () {
192+ Version v = Version .parseVersion ("3.1.4" );
193+ assertThrows (NullPointerException .class , () -> v .satisfies (null ));
194+ }
195+
196+ @ Test
197+ void testSatisfiesWithComplexVersions () {
198+ Version v = Version .parseVersion ("1.2.3-20251105063220+e303076b5d51da7f0f3a10cd69de018ac0a3853d" );
199+ assertTrue (v .satisfies (">=1.2.0" ));
200+ assertFalse (v .satisfies (">1.2.3" ));
201+ assertTrue (v .satisfies (">=1.2.0 <2.0.0" ));
202+ assertFalse (v .satisfies (">1.2.3 <2.0.0" ));
203+ }
204+ }
205+ }
0 commit comments