Skip to content

Commit 61f42fc

Browse files
committed
Added Additional tests for Semantic Versioning
1 parent 856bc65 commit 61f42fc

File tree

2 files changed

+221
-12
lines changed

2 files changed

+221
-12
lines changed

core-api/src/main/java/com/optimizely/ab/config/audience/match/SemanticVersion.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.text.ParseException;
2020
import java.util.ArrayList;
21+
import java.util.Objects;
2122

2223
import static com.optimizely.ab.internal.AttributesUtil.parseNumeric;
2324

@@ -79,12 +80,12 @@ public SemanticVersion(String version) throws ParseException {
7980
public String toString() {
8081
StringBuilder ret = new StringBuilder();
8182
ret.append(major);
82-
ret.append('.');
8383
if (minor != null) {
84-
ret.append(minor);
8584
ret.append('.');
85+
ret.append(minor);
8686
}
8787
if (patch != null) {
88+
ret.append('.');
8889
ret.append(patch);
8990
}
9091
if (preRelease.length > 0) {
@@ -122,9 +123,9 @@ public boolean equals(Object other) {
122123
return false;
123124
}
124125
SemanticVersion ov = (SemanticVersion) other;
125-
if (!ov.major.equals(major) ||
126-
!ov.minor.equals(minor) ||
127-
!ov.patch.equals(patch)) {
126+
if (!Objects.equals(major, ov.major) ||
127+
!Objects.equals(minor, ov.minor) ||
128+
!Objects.equals(patch, ov.patch)) {
128129
return false;
129130
}
130131
if (ov.preRelease.length != preRelease.length) {
@@ -166,7 +167,7 @@ public int compareTo(SemanticVersion targetVersion) {
166167
}
167168
if (preRelease.length > 0 && targetVersion.preRelease.length > 0) {
168169
int len = Math.min(preRelease.length, targetVersion.preRelease.length);
169-
int count = 0;
170+
int count;
170171
for (count = 0; count < len; count++) {
171172
result = comparePreReleaseTag(count, targetVersion);
172173
if (result != 0) {
@@ -209,10 +210,11 @@ private int comparePreReleaseTag(int pos, SemanticVersion ov) {
209210

210211
// Parser implementation below
211212

212-
private Integer[] vParts;
213-
private ArrayList<String> preParts, metaParts;
213+
private final Integer[] vParts;
214+
private final ArrayList<String> preParts;
215+
private final ArrayList<String> metaParts;
214216
private int errPos;
215-
private char[] input;
217+
private final char[] input;
216218

217219
private boolean stateMajor() {
218220
int pos = 0;
@@ -226,7 +228,7 @@ private boolean stateMajor() {
226228
return false;
227229
}
228230

229-
vParts[0] = Integer.parseInt(new String(input, 0, pos), 10);
231+
vParts[0] = parseNumeric(new String(input, 0, pos));
230232

231233
if (input.length > pos && input[pos] == '.') {
232234
return stateMinor(pos + 1);
@@ -250,7 +252,7 @@ private boolean stateMinor(int index) {
250252
errPos = index;
251253
return false;
252254
}
253-
vParts[1] = Integer.parseInt(new String(input, index, pos - index), 10);
255+
vParts[1] = parseNumeric(new String(input, index, pos - index));
254256

255257
if (input.length > pos && input[pos] == '.') {
256258
return statePatch(pos + 1);
@@ -274,7 +276,7 @@ private boolean statePatch(int index) {
274276
return false;
275277
}
276278

277-
vParts[2] = Integer.parseInt(new String(input, index, pos - index), 10);
279+
vParts[2] = parseNumeric(new String(input, index, pos - index));
278280

279281
if (pos >= input.length) { // We have a clean version string
280282
return true;
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
/**
2+
*
3+
* Copyright 2020, Optimizely and contributors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.optimizely.ab.config.audience;
18+
19+
import com.optimizely.ab.config.audience.match.SemanticVersion;
20+
import org.junit.Rule;
21+
import org.junit.Test;
22+
import org.junit.rules.ExpectedException;
23+
24+
import java.text.ParseException;
25+
26+
import static org.junit.Assert.*;
27+
28+
public class SemanticVersionTest {
29+
@Rule
30+
public ExpectedException thrown = ExpectedException.none();
31+
32+
@Test
33+
public void semanticVersionEmptyStringThrowsException() throws ParseException {
34+
thrown.expect(ParseException.class);
35+
// Semantic version must not be empty
36+
new SemanticVersion("");
37+
}
38+
39+
@Test
40+
public void semanticVersionInvalidLeadingZerosThrowsException() throws ParseException {
41+
thrown.expect(ParseException.class);
42+
// Semantic version must not contain leading zeros
43+
new SemanticVersion("03.7.1");
44+
}
45+
46+
@Test
47+
public void semanticVersionInvalidMajorShouldBeNumberOnly() throws ParseException {
48+
thrown.expect(ParseException.class);
49+
new SemanticVersion("a.2.1");
50+
}
51+
52+
53+
@Test
54+
public void semanticVersionInvalidMinorShouldBeNumberOnly() throws ParseException {
55+
thrown.expect(ParseException.class);
56+
new SemanticVersion("1.b.1");
57+
}
58+
59+
@Test
60+
public void semanticVersionInvalidPatchShouldBeNumberOnly() throws ParseException {
61+
thrown.expect(ParseException.class);
62+
new SemanticVersion("1.2.c");
63+
}
64+
65+
@Test
66+
public void semanticVersionEqualsTrue() throws ParseException {
67+
SemanticVersion targetSV = new SemanticVersion("3.7.0");
68+
SemanticVersion actualSV = new SemanticVersion("3.7.0");
69+
assertTrue(actualSV.equals(targetSV));
70+
}
71+
72+
@Test
73+
public void semanticVersionEqualsWithPreReleaseAndMetaTrue() throws ParseException {
74+
SemanticVersion targetSV = new SemanticVersion("3.7.0-beta+2.3");
75+
SemanticVersion actualSV = new SemanticVersion("3.7.0-beta+2.3");
76+
assertTrue(actualSV.equals(targetSV));
77+
}
78+
79+
@Test
80+
public void semanticVersionEqualsWithPreReleaseAndMetaFalse() throws ParseException {
81+
SemanticVersion targetSV = new SemanticVersion("3.7.0-beta+2.3");
82+
SemanticVersion actualSV = new SemanticVersion("3.7.0-beta+3");
83+
assertFalse(actualSV.equals(targetSV));
84+
}
85+
86+
@Test
87+
public void semanticVersionEqualsSameObjectTrue() throws ParseException {
88+
SemanticVersion targetSV = new SemanticVersion("3.7.0");
89+
assertTrue(targetSV.equals(targetSV));
90+
}
91+
92+
@Test
93+
public void semanticVersionSame() throws ParseException {
94+
SemanticVersion targetSV = new SemanticVersion("3.7");
95+
SemanticVersion actualSV = new SemanticVersion("3.7");
96+
assertTrue(actualSV.equals(targetSV));
97+
}
98+
99+
@Test
100+
public void semanticVersionEqualsComparesPreRelease() throws ParseException {
101+
SemanticVersion targetSV = new SemanticVersion("3.7.1-beta");
102+
SemanticVersion actualSV = new SemanticVersion("3.7.1-alpha");
103+
assertFalse(actualSV.equals(targetSV));
104+
}
105+
106+
@Test
107+
public void semanticVersionEqualsComparesMeta() throws ParseException {
108+
SemanticVersion targetSV = new SemanticVersion("3.7.1+beta");
109+
SemanticVersion actualSV = new SemanticVersion("3.7.1+alpha");
110+
assertFalse(actualSV.equals(targetSV));
111+
}
112+
113+
@Test
114+
public void semanticVersionTargetIsNotSemanticVersionObject() throws ParseException {
115+
SemanticVersion actualSV = new SemanticVersion("3.7.0");
116+
assertFalse(actualSV.equals(3.7));
117+
}
118+
119+
@Test
120+
public void semanticVersionTargetToString() throws ParseException {
121+
SemanticVersion targetSV = new SemanticVersion("3.7");
122+
assertEquals(targetSV.toString(), "3.7");
123+
}
124+
125+
@Test
126+
public void semanticVersionTargetToStringComplete() throws ParseException {
127+
SemanticVersion targetSV = new SemanticVersion("3.7.1-2.2.e+b.d2");
128+
assertEquals(targetSV.toString(), "3.7.1-2.2.e+b.d2");
129+
}
130+
131+
@Test
132+
public void semanticVersionTargetHashCode() throws ParseException {
133+
String str = "3.7.1";
134+
SemanticVersion targetSV = new SemanticVersion("3.7.1");
135+
assertEquals(targetSV.hashCode(), str.hashCode());
136+
}
137+
138+
@Test
139+
public void semanticVersionCompareTo() throws ParseException {
140+
SemanticVersion targetSV = new SemanticVersion("3.7.1");
141+
SemanticVersion actualSV = new SemanticVersion("3.7.1");
142+
assertTrue(actualSV.compareTo(targetSV) == 0);
143+
}
144+
145+
@Test
146+
public void semanticVersionCompareToActualLess() throws ParseException {
147+
SemanticVersion targetSV = new SemanticVersion("3.7.1");
148+
SemanticVersion actualSV = new SemanticVersion("3.7.0");
149+
assertTrue(actualSV.compareTo(targetSV) < 0);
150+
}
151+
152+
@Test
153+
public void semanticVersionCompareToActualGreater() throws ParseException {
154+
SemanticVersion targetSV = new SemanticVersion("3.7.1");
155+
SemanticVersion actualSV = new SemanticVersion("3.7.2");
156+
assertTrue(actualSV.compareTo(targetSV) > 0);
157+
}
158+
159+
@Test
160+
public void semanticVersionCompareToPatchMissing() throws ParseException {
161+
SemanticVersion targetSV = new SemanticVersion("3.7");
162+
SemanticVersion actualSV = new SemanticVersion("3.7.1");
163+
assertTrue(actualSV.compareTo(targetSV) == 0);
164+
}
165+
166+
@Test
167+
public void semanticVersionCompareToActualPatchMissing() throws ParseException {
168+
SemanticVersion targetSV = new SemanticVersion("3.7.1");
169+
SemanticVersion actualSV = new SemanticVersion("3.7");
170+
assertTrue(actualSV.compareTo(targetSV) < 0);
171+
}
172+
173+
@Test
174+
public void semanticVersionCompareToActualPreReleaseMissing() throws ParseException {
175+
SemanticVersion targetSV = new SemanticVersion("3.7.1-beta");
176+
SemanticVersion actualSV = new SemanticVersion("3.7.1");
177+
assertTrue(actualSV.compareTo(targetSV) > 0);
178+
}
179+
180+
@Test
181+
public void semanticVersionCompareToAlphaBetaAsciiComparision() throws ParseException {
182+
SemanticVersion targetSV = new SemanticVersion("3.7.1-alpha");
183+
SemanticVersion actualSV = new SemanticVersion("3.7.1-beta");
184+
assertTrue(actualSV.compareTo(targetSV) > 0);
185+
}
186+
187+
@Test
188+
public void semanticVersionCompareToIgnoreMetaComparision() throws ParseException {
189+
SemanticVersion targetSV = new SemanticVersion("3.7.1-beta.1+2.3");
190+
SemanticVersion actualSV = new SemanticVersion("3.7.1-beta.1+3.45");
191+
assertTrue(actualSV.compareTo(targetSV) == 0);
192+
}
193+
194+
@Test
195+
public void semanticVersionCompareToPreReleaseComparision() throws ParseException {
196+
SemanticVersion targetSV = new SemanticVersion("3.7.1-beta.1");
197+
SemanticVersion actualSV = new SemanticVersion("3.7.1-beta.2");
198+
assertTrue(actualSV.compareTo(targetSV) > 0);
199+
}
200+
201+
@Test
202+
public void semanticVersionCompareToDoNotCompareBuildVersionComparision() throws ParseException {
203+
SemanticVersion targetSV = new SemanticVersion("3.7.1+beta.1");
204+
SemanticVersion actualSV = new SemanticVersion("3.7.1+beta.2");
205+
assertTrue(actualSV.compareTo(targetSV) == 0);
206+
}
207+
}

0 commit comments

Comments
 (0)