Skip to content

Commit

Permalink
GH-1532: Some Fix/Enhancement about Version class
Browse files Browse the repository at this point in the history
  • Loading branch information
gcx-seb authored and sbernard31 committed Nov 8, 2023
1 parent 7829f0a commit cb204b2
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 36 deletions.
73 changes: 38 additions & 35 deletions leshan-core/src/main/java/org/eclipse/leshan/core/LwM2m.java
Expand Up @@ -22,9 +22,9 @@ public interface LwM2m {
*/
public class LwM2mVersion extends Version {

public static LwM2mVersion V1_0 = new LwM2mVersion("1.0", true);
public static LwM2mVersion V1_1 = new LwM2mVersion("1.1", true);
private static LwM2mVersion[] supportedVersions = new LwM2mVersion[] { V1_0, V1_1 };
public static final LwM2mVersion V1_0 = new LwM2mVersion("1.0", true);
public static final LwM2mVersion V1_1 = new LwM2mVersion("1.1", true);
private static final LwM2mVersion[] supportedVersions = new LwM2mVersion[] { V1_0, V1_1 };

private final boolean supported;

Expand Down Expand Up @@ -91,35 +91,45 @@ public boolean equals(Object obj) {
*/
public class Version implements Comparable<Version> {

public static Version V1_0 = new Version("1.0");
public static final Version MAX = new Version(Short.MAX_VALUE, Short.MIN_VALUE);
public static final Version V1_0 = new Version("1.0");
public static final Version MAX = new Version(Short.MAX_VALUE, Short.MAX_VALUE);

protected final Short major;
protected final Short minor;
private static short toShortExact(int value, String format, Object... args) {
if ((short) value != value) {
throw new IllegalArgumentException(String.format(format, args));
}
return (short) value;
}

protected final short major;
protected final short minor;

public Version(int major, int minor) {
this.major = (short) major;
this.minor = (short) minor;
this(toShortExact(major, "version (%d.%d) major part (%d) is not a valid short", major, minor, major),
toShortExact(minor, "version (%d.%d) minor part (%d) is not a valid short", major, minor, minor));
}

public Version(Short major, Short minor) {
public Version(short major, short minor) {
this.major = major;
if (this.major < 0) {
throw new IllegalArgumentException(
String.format("version (%d.%d) major part (%d) must not be negative", major, minor, major));
}
this.minor = minor;
if (this.minor < 0) {
throw new IllegalArgumentException(
String.format("version (%d.%d) minor part (%d) must not be negative", major, minor, minor));
}
}

public Version(String version) {
try {
String[] versionPart = version.split("\\.");
this.major = Short.parseShort(versionPart[0]);
this.minor = Short.parseShort(versionPart[1]);
} catch (RuntimeException e) {
String err = Version.validate(version);
if (err != null) {
throw new IllegalArgumentException(err);
} else {
throw e;
}
String err = Version.validate(version);
if (err != null) {
throw new IllegalArgumentException(err);
}
String[] versionPart = version.split("\\.");
this.major = Short.parseShort(versionPart[0]);
this.minor = Short.parseShort(versionPart[1]);
}

@Override
Expand All @@ -133,16 +143,16 @@ public static Version getDefault() {

public static String validate(String version) {
if (version == null || version.isEmpty())
return "version MUST NOT be null or empty";
return "version MUST NOT be null or empty";
String[] versionPart = version.split("\\.");
if (versionPart.length != 2) {
return String.format("version (%s) MUST be composed of 2 parts", version);
}
for (int i = 0; i < 2; i++) {
try {
Short parsedShort = Short.parseShort(versionPart[i]);
short parsedShort = Short.parseShort(versionPart[i]);
if (parsedShort < 0) {
return String.format("version (%s) part %d (%s) is not a valid short", version, i + 1,
return String.format("version (%s) part %d (%s) must not be negative", version, i + 1,
versionPart[i]);
}
} catch (Exception e) {
Expand All @@ -157,8 +167,8 @@ public static String validate(String version) {
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((major == null) ? 0 : major.hashCode());
result = prime * result + ((minor == null) ? 0 : minor.hashCode());
result = prime * result + major;
result = prime * result + minor;
return result;
}

Expand All @@ -171,15 +181,9 @@ public boolean equals(Object obj) {
if (getClass() != obj.getClass())
return false;
Version other = (Version) obj;
if (major == null) {
if (other.major != null)
return false;
} else if (!major.equals(other.major))
if (major != other.major)
return false;
if (minor == null) {
if (other.minor != null)
return false;
} else if (!minor.equals(other.minor))
if (minor != other.minor)
return false;
return true;
}
Expand All @@ -188,7 +192,6 @@ public boolean equals(Object obj) {
public int compareTo(Version other) {
if (major != other.major)
return major - other.major;

return minor - other.minor;
}

Expand Down
Expand Up @@ -15,12 +15,22 @@
*******************************************************************************/
package org.eclipse.leshan.core;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.stream.Stream;

import org.eclipse.leshan.core.LwM2m.LwM2mVersion;
import org.eclipse.leshan.core.LwM2m.Version;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import nl.jqno.equalsverifier.EqualsVerifier;

public class VersionTest {
@Test
Expand All @@ -33,11 +43,67 @@ public void is_supported_tests() {
}

@Test
public void compare_tests() {
public void compare_to_tests() {
assertTrue(new Version("1.0").compareTo(new Version("1.2")) < 0);
assertTrue(new Version("0.9").compareTo(new Version("1.2")) < 0);
assertTrue(new Version("128.0").compareTo(new Version("128.2")) < 0);
assertTrue(new Version("1.2").compareTo(new Version("1.2")) == 0);
assertTrue(new Version("128.0").compareTo(new Version("128.0")) == 0);
assertTrue(new Version("1.3").compareTo(new Version("1.2")) > 0);
assertTrue(new Version("2.0").compareTo(new Version("1.2")) > 0);
assertTrue(new Version("128.2").compareTo(new Version("128.0")) > 0);
}

@Test
public void assertEqualsHashcode() {
// TODO we should not use EqualsVerifier.simple()
// but implement a right hashcode/equals way
// see : https://github.com/eclipse-leshan/leshan/issues/1504
EqualsVerifier.simple().forClass(Version.class).verify();
}

@Test
public void older_than_tests() {
assertTrue(new Version("1.0").olderThan(new Version("1.1")));
assertTrue(new Version("0.9").olderThan(new Version("1.1")));
}

@Test
public void newer_than_tests() {
assertTrue(new Version("1.1").newerThan(new Version("1.0")));
assertTrue(new Version("1.0").newerThan(new Version("0.9")));
}

@ParameterizedTest
@MethodSource("illegal_arguments")
public void illegal_argument_tests(Executable executable, String expectedMessage) {
IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
assertEquals(expectedMessage, e.getMessage());
}

private static Stream<Arguments> illegal_arguments() {
return Stream.of(args(() -> new Version(null), "version MUST NOT be null or empty"),
args(() -> new Version(""), "version MUST NOT be null or empty"),
args(() -> new Version("foo"), "version (foo) MUST be composed of 2 parts"),
args(() -> new Version("1.0.0"), "version (1.0.0) MUST be composed of 2 parts"),
args(() -> new Version("-1.0"), "version (-1.0) part 1 (-1) must not be negative"),
args(() -> new Version("1.-1"), "version (1.-1) part 2 (-1) must not be negative"),
args(() -> new Version("a.0"), "version (a.0) part 1 (a) is not a valid short"),
args(() -> new Version("32768.32767"), "version (32768.32767) part 1 (32768) is not a valid short"),
args(() -> new Version("32767.32768"), "version (32767.32768) part 2 (32768) is not a valid short"),
args(() -> new Version(-32769, -32768),
"version (-32769.-32768) major part (-32769) is not a valid short"),
args(() -> new Version(-32768, -32769),
"version (-32768.-32769) minor part (-32769) is not a valid short"),
args(() -> new Version(32768, 32767), "version (32768.32767) major part (32768) is not a valid short"),
args(() -> new Version(32767, 32768), "version (32767.32768) minor part (32768) is not a valid short"),
args(() -> new Version(-1, 0), "version (-1.0) major part (-1) must not be negative"),
args(() -> new Version(1, -1), "version (1.-1) minor part (-1) must not be negative"),
args(() -> new Version((short) -1, (short) 0), "version (-1.0) major part (-1) must not be negative"),
args(() -> new Version((short) 1, (short) -1), "version (1.-1) minor part (-1) must not be negative"));
}

private static Arguments args(Executable executable, String expectedMessage) {
return Arguments.of(executable, expectedMessage);
}
}

0 comments on commit cb204b2

Please sign in to comment.