r2486 - in trunk/nuiton-utils/src: main/java/org/nuiton/util test/java/org/nuiton/util
Author: bpoussin Date: 2013-01-30 18:30:41 +0100 (Wed, 30 Jan 2013) New Revision: 2486 Url: http://nuiton.org/projects/nuiton-utils/repository/revisions/2486 Log: fixes #2517: [Nuiton-utils] add Java implementation of semver.org Added: trunk/nuiton-utils/src/main/java/org/nuiton/util/SemVer.java trunk/nuiton-utils/src/test/java/org/nuiton/util/SemVerTest.java Added: trunk/nuiton-utils/src/main/java/org/nuiton/util/SemVer.java =================================================================== --- trunk/nuiton-utils/src/main/java/org/nuiton/util/SemVer.java (rev 0) +++ trunk/nuiton-utils/src/main/java/org/nuiton/util/SemVer.java 2013-01-30 17:30:41 UTC (rev 2486) @@ -0,0 +1,610 @@ +package org.nuiton.util; + + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Implantation de http://semver.org/. + * + * Cette objet est immutable, Il faut utiliser {@link #getCreator()} + * pour modifier un de ses elements + * + * Quelques changement par rapport au site: + * <li> le numero de version peut avoir entre 1 et N element, et non pas 3 obligatoirement + * <li> on peut avoir un -SNAPSHOT ajoute en toute fin de la version + * + * Un SemVer est en plusieurs elements dont chaque element peut avoir plusieurs + * composant. Les composants sont utilise le meme separateur '.'. + * + * <li> version: 1 à N composant numerique, les 3 premiers sont nomme + * <ul> + * <li> major + * <li> minor + * <li> patch + * </ul> + * <li> prerelease: 0 à N composant alphanumerique, le prefix est '-' + * <li> build: 0 à N composant alphanumerique, le prefix est '+' + * <li> SNAPSHOT: 0 ou 1 composant dont le nom est fixe le prefix est '-' + * + * Le mieux pour construire ou modifier un SemVer est d'utilise une methode + * creator: + * <li> SemVer.creator(1,2,3).done() => "1.2.3" + * <li> SemVer.creator("1.2.3","rc2").done() => "1.2.3-rc2" + * <li> SemVer.creator().setVersion(2.3.4).setBuild("r223").done() => "2.3.4+r223" + * <li> SemVer.creator().setVersion(2.3.4).setSnapshot(true).done() => "2.3.4-SNAPSHOT" + * <li> SemVer.creator(new SemVer("1.2.3")).incMajor().done() => "2.2.2" + * <li> new SemVer("1.2.3").getCreator().incMinor().setPrerelease(beta).done() => "1.3.3-beta" + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + * @since 2.7 + */ +public class SemVer implements Comparable<SemVer> { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(SemVer.class); + + /** Separateur utiliser entre chaque element d'une partie */ + final static public String SERIES_SEPARATOR = "."; // le separateur + /** Seperateur entre la version et l'element prerelease */ + final static public String PRERELEASE_SEPARATOR = "-"; // le separateur de Prerelease + /** Separateur utiliser devant l'element build */ + final static public String BUILD_SEPARATOR = "+"; // le separateur de build + + /** pattern pour une partie de l'element version */ + final static public String PATTERN_VERSION = "[0-9]+"; // le version ne sont que des nombres + /** pattern pour une partie de l'element prerelease */ + final static public String PATTERN_PRERELEASE = "[0-9A-Za-z-]+"; // les Prerelease sont des chiffre, lettre ou '-' + /** pattern pour une partir de l'element build */ + final static public String PATTERN_BUILD = "[0-9A-Za-z-]+";// les Build sont des chiffre, lettre ou '-' + + /** Separateur de SNAPSHOT */ + final static public String SNAPSHOT_SEPARATOR = "-"; + /** la chaine de caractere representant le SNAPSHOT */ + final static public String SNAPSHOT = "SNAPSHOT"; + + // "(1.20.300)(-alpha-1.20)?(+r123.20130126)?" + // version prerelease build + /** pattern qui permet de separer les 3 constituante d'une version, ne + * supporte pas le SNAPSHOT, il faut donc que le SNAPSHOT ait ete retirer + * avant d'appliquer le pattern + */ + final static Pattern PATTERN_ALL = Pattern.compile( + "("+PATTERN_VERSION+"(?:"+Pattern.quote(SERIES_SEPARATOR)+PATTERN_VERSION+")*)" + + "("+Pattern.quote(PRERELEASE_SEPARATOR)+ PATTERN_PRERELEASE+"(?:"+Pattern.quote(SERIES_SEPARATOR)+PATTERN_PRERELEASE+")*)?" + + "("+Pattern.quote(BUILD_SEPARATOR)+ PATTERN_BUILD+"(?:"+Pattern.quote(SERIES_SEPARATOR)+PATTERN_BUILD+")*)?"); + + protected String version; + protected String prerelease; + protected String build; + protected String snapshot; + + /** + * Create new Version object, strip is done on argument to remove extra space + * @param versionString + * @exception IllegalArgumentException if argument isn't valid version string + */ + public SemVer(String versionString) { + String v = StringUtils.strip(versionString); // on conserve versionString intact pour le message d'erreur + if (StringUtils.endsWithIgnoreCase(v, SNAPSHOT_SEPARATOR + SNAPSHOT)) { + snapshot = SNAPSHOT; + v = StringUtils.substringBeforeLast(v, SNAPSHOT_SEPARATOR); + } + Matcher matcher = PATTERN_ALL.matcher(v); + boolean match = matcher.matches(); + if (match) { + version = matcher.group(1); + prerelease = StringUtils.removeStart(matcher.group(2), PRERELEASE_SEPARATOR); + build = StringUtils.removeStart(matcher.group(3), BUILD_SEPARATOR); + } else { + throw new IllegalArgumentException(String.format("Bad version string: '%s'", versionString)); + } + } + + /** + * @param o the other version to test + * @return <code>true</code> if current version is before the given one + */ + public boolean before(SemVer o) { + int result = compareTo(o); + return result < 0; + } + + /** + * @param o the other version to test + * @return <code>true</code> if current version is after the given one + */ + public boolean after(SemVer o) { + int result = compareTo(o); + return result > 0; + } + + public int compareTo(SemVer other) { + int result = compare(this.getVersion(), other.getVersion(), false); + if (result == 0) { + result = compare(this.getPrerelease(), other.getPrerelease(), true); + if (result == 0) { + result = compare(this.getBuild(), other.getBuild(), false); + if (result == 0) { + result = compare(this.getSnapshot(), other.getSnapshot(), true); + } + } + } + return result; + } + + /** + * Compare deux elements de meme semantique (version, prerelease, build, snapshot) + * sinon le comportement est non predictible + * @param a + * @param b + * @param nullIsHigh indique si un des elements est null, s'il est plus + * grand ou plus petit que l'autre + * @return negatif si a inferieur b, 0 si a == b, positif si a superieur a b + */ + protected int compare(String a, String b, boolean nullIsHigh) { + int result; + if (nullIsHigh) { + result = nullIsHigh(a, b); + } else { + result = nullIsLow(a, b); + } + + if (result == 0 && a != null && b != null) { + // on decoupe suivant le '.' + String[] aSeries = StringUtils.split(a, SERIES_SEPARATOR); + String[] bSeries = StringUtils.split(b, SERIES_SEPARATOR); + + int length = Math.max(aSeries.length, bSeries.length); + for (int i=0; result==0 & i<length; i++) { + // s'il y en a un qui est plus court, on prend par defaut "" + String va = i < aSeries.length ? aSeries[i] : ""; + String vb = i < bSeries.length ? bSeries[i] : ""; + + // s'il n'y a que des nombres pour une valeur on ajoute des espaces + // devant pour qu'il est la meme longueur que l'autre et ainsi + // pouvoir les comparer lexicographiquement + int pad = Math.max(va.length(), vb.length()); + if (StringUtils.isNumeric(va)) { + va = StringUtils.leftPad(va, pad); + } + if (StringUtils.isNumeric(vb)) { + vb = StringUtils.leftPad(vb, pad); + } + + // on compare les deux valeurs + result = va.compareTo(vb); + } + } + return result; + } + + /** + * Ne compare par le chaine, seulement la nullite, si un des arguments + * est null, alors il est plus grand que l'autre. + * + * 1.0 est plus grand que 1.0-Beta + * + * @param a + * @param b + * @return + */ + protected int nullIsHigh(String a, String b) { + int result = 0; + if (a == null ^ b == null) { + if (a == null) { + result = 1; + } else { + result = -1; + } + } + return result; + } + + /** + * Ne compare par le chaine, seulement la nullite, si un des arguments + * est null, alors il est plus petit que l'autre. + * + * 1.0+r123 est plus grand que 1.0 + * + * @param a + * @param b + * @return + */ + protected int nullIsLow(String a, String b) { + int result = 0; + if (a == null ^ b == null) { + if (a == null) { + result = -1; + } else { + result = 1; + } + } + return result; + } + + /** + * Donne le nombre de composante de l'element + * <li>1.2.3 retourne 3 + * <li>99.100 retourne 2 + * + * @return + */ + protected int getComposantCount(String element) { + int result = 0; + if (StringUtils.isNotBlank(element)) { + result = 1 + StringUtils.countMatches(element, SERIES_SEPARATOR); + } + return result; + } + + /** + * Retourne un des composants de l'element version + * @param i + * @return + */ + protected String getComposant(String element, int i) { + String[] v = StringUtils.split(element, SERIES_SEPARATOR); + Validate.validIndex(v, i, + "Ask '%s', element '%s' don't have enought composant", i, element); + + String s = v[i]; + return s; + } + + + + public String getVersion() { + return version; + } + + /** + * Donne le nombre de composante de la version + * <li>1.2.3 retourne 3 + * <li>99.100 retourne 2 + * + * @return + */ + public int getVersionCount() { + int result = getComposantCount(getVersion()); + return result; + } + + /** + * Retourne un des composants de l'element version + * @param i + * @return + */ + public String getVersion(int i) { + String s = getComposant(getVersion(), i); + return s; + } + + public String getMajor() { + String result = getVersion(0); + return result; + } + + public String getMinor() { + String result = getVersion(1); + return result; + } + + public String getPatch() { + String result = getVersion(2); + return result; + } + + public String getPrerelease() { + return prerelease; + } + + /** + * Donne le nombre de composante de la Prerelease + * <li>1.2.3 retourne 3 + * <li>99.100 retourne 2 + * + * @return + */ + public int getPrereleaseCount() { + int result = getComposantCount(getPrerelease()); + return result; + } + + /** + * Retourne un des composants de l'element version + * @param i + * @return + */ + public String getPrerelease(int i) { + String s = getComposant(getPrerelease(), i); + return s; + } + + public String getBuild() { + return build; + } + + /** + * Donne le nombre de composante de la Prerelease + * <li>1.2.3 retourne 3 + * <li>99.100 retourne 2 + * + * @return + */ + public int getBuildCount() { + int result = getComposantCount(getBuild()); + return result; + } + + /** + * Retourne un des composants de l'element version + * @param i + * @return + */ + public String getBuild(int i) { + String s = getComposant(getBuild(), i); + return s; + } + + public String getSnapshot() { + return snapshot; + } + + public boolean isSnapshot() { + return StringUtils.isNotBlank(snapshot); + } + + static protected String ifNotNull(String prefix, String s) { + String result = ""; + if (StringUtils.isNotBlank(s)) { + result = prefix + s; + } + return result; + } + + @Override + public boolean equals(Object o) { + boolean result = o instanceof SemVer && this.compareTo((SemVer)o) == 0; + return result; + } + + @Override + public int hashCode() { + return toString().hashCode(); + } + + /** + * Convertit la representation textuelle de la version en identifiant java valide : + * - en java : "-" "." "+" interdit + * + * @return la valeur ou les carateres interdits sont remplaces par '_' + */ + public String toJavaIdentifier() { + String result = toString(); + + // attention dans les crochets le '-' a une signification, il faut donc le mettre en 1er + result = result.replaceAll("[-+.]", "_"); + + return result; + } + + @Override + public String toString() { + return getVersion() + + ifNotNull(PRERELEASE_SEPARATOR, getPrerelease()) + + ifNotNull(BUILD_SEPARATOR, getBuild()) + + ifNotNull(SNAPSHOT_SEPARATOR, getSnapshot()); + } + + /** + * Retourne un objet creator initialise avec les donnees de ce SemVer + * ce qui permet de creer un nouveau SemVer en modifiant un des elements + * @return + */ + public SemVerCreator getCreator() { + return creator(this); + } + + /** + * Indique si la chaine represente bien une version au format SemVer + * @param version + * @return + */ + static public boolean isSemVer(String version) { + if (StringUtils.endsWithIgnoreCase(version, SNAPSHOT)) { + version = StringUtils.substringBeforeLast(version, SNAPSHOT); + } + Matcher matcher = PATTERN_ALL.matcher(version); + boolean result = matcher.matches(); + return result; + } + + /** + * Permet de creer un objet version. Si des arguments sont passer en parametre + * ils sont pris dans l'ordre pour: la version, la prerelease, le build, le snapshot + * <pre> + * SemVer v = SemVer.creator().setVersion("1.2").setPrerelease("beta.1").setBuild("r123").done(); + * SemVer v = SemVer.creator("1.2", "beta.1","r123", SemVer.SNAPSHOT).done(); + * </pre> + * @return + */ + static public SemVerCreator creator(String ... v) { + SemVerCreator result = new SemVerCreator(); + if (v != null) { + if (v.length > 0) { + result.setVersion(v[0]); + if (v.length > 1) { + result.setPrerelease(v[1]); + if (v.length > 2) { + result.setBuild(v[2]); + if (v.length > 3) { + if (v[3] == null) { + result.setSnapshot(false); + } else if (StringUtils.equalsIgnoreCase(SNAPSHOT, v[3])) { + result.setSnapshot(true); + } else { + throw new IllegalArgumentException(String.format( + "Illegal SNAPSHOT string '%s'", + v[3])); + } + if (v.length > 4) { + throw new IllegalArgumentException(String.format( + "too many string arguments '%s' maximum 4", + v.length)); + } + } + } + } + } + } + return result; + } + + /** + * Createur qui permet de passer en parametre les different composante de + * l'element version + * @param v + * @return + */ + static public SemVerCreator creator(int ... v) { + SemVerCreator result = creator(StringUtils.join(v, SERIES_SEPARATOR)); + return result; + } + + /** + * Create creator initialized with SemVer value, you can change some Element + * by puting null value. + * + * SemVer n = SemVer.creator(v).setBuild("r123").setSnapshot(false).done(); + * + * @param v + * @return + */ + static public SemVerCreator creator(SemVer v) { + SemVerCreator result = creator( + v.getVersion(), v.getPrerelease(), v.getBuild(), v.getSnapshot()); + return result; + } + + /** + * Retourne un Createur sans aucune information. Cette methode permet + * aussi de desambiguise les deux autres methode creator qui si elle + * n'ont pas de parametre sont semblable + * + * @return + */ + static public SemVerCreator creator() { + SemVerCreator result = new SemVerCreator(); + return result; + } + + /** + * Construit un objet version, la verification de la coherence est faite lors + * de l'appel du create. + */ + static public class SemVerCreator { + protected String version; + protected String prerelease; + protected String build; + protected String snapshot; + + public SemVerCreator setVersion(Integer... v) { + // l'argument est bien Integer, car join ne travail qu'avec des objets :( + version = StringUtils.join(v, SERIES_SEPARATOR); + return this; + } + + public SemVerCreator setVersion(String v) { + version = v; + return this; + } + + public SemVerCreator setPrerelease(String v) { + prerelease = v; + return this; + } + + public SemVerCreator setBuild(String v) { + build = v; + return this; + } + + public SemVerCreator setSnapshot(boolean b) { + if (b) { + snapshot = SNAPSHOT; + } else { + snapshot = null; + } + return this; + } + + /** + * Incremente la composante 'indice' de l'element version de 'inc', la composante + * doit representer un entier sinon une exception est leve + * + * @param indice la composante de la version a incrementer + * @param inc le nombre a lui ajouter + * @return new instance, this SemVer is not modified + */ + public SemVerCreator incVersion(int indice, int inc) { + String[] v = StringUtils.split(version, SERIES_SEPARATOR); + Validate.validIndex(v, indice, "Version don't have enought composant"); + + String s = v[indice]; + + Validate.isTrue(StringUtils.isNumeric(s), "String '%s' must be numeric", s); + int i = Integer.parseInt(s); + i += inc; + s = String.valueOf(i); + + v[indice] = s; + version = StringUtils.join(v, SERIES_SEPARATOR); + + return this; + } + + /** + * Return new instance, this SemVer is not modified + * @return new instance where major version number is incremented by 1 + */ + public SemVerCreator incMajor() { + return incVersion(0, 1); + } + + /** + * Return new instance, this SemVer is not modified + * @return new instance where major version number is incremented by 1 + */ + public SemVerCreator incMinor() { + return incVersion(1, 1); + } + + /** + * Return new instance, this SemVer is not modified + * @return new instance where major version number is incremented by 1 + */ + public SemVerCreator incPatch() { + return incVersion(2, 1); + } + + public SemVer done() { + SemVer result = new SemVer( + StringUtils.defaultString(version) + + ifNotNull(PRERELEASE_SEPARATOR, prerelease) + + ifNotNull(BUILD_SEPARATOR, build) + + ifNotNull(SNAPSHOT_SEPARATOR, snapshot) + ); + return result; + } + } + +} Added: trunk/nuiton-utils/src/test/java/org/nuiton/util/SemVerTest.java =================================================================== --- trunk/nuiton-utils/src/test/java/org/nuiton/util/SemVerTest.java (rev 0) +++ trunk/nuiton-utils/src/test/java/org/nuiton/util/SemVerTest.java 2013-01-30 17:30:41 UTC (rev 2486) @@ -0,0 +1,208 @@ +package org.nuiton.util; + + +import java.util.Arrays; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.Test; + +/** + * + * @author poussin + * @version $Revision$ + * + * Last update: $Date$ + * by : $Author$ + */ +public class SemVerTest { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(SemVerTest.class); + + /** + * Liste de toutes les versions a tester, de la plus petite a la plus grande + */ + String[] versions = { + "0", + "0.0.0-SNAPSHOT", + "0.0.0", + "1.0.0-alpha-SNAPSHOT", + "1.0.0-alpha", + "1.0.0-alpha.1", + "1.0.0-beta.2 ", + " 1.0.0-beta.11 ", + " 1.0.0-rc.1 ", + " 1.0.0-rc.1+build.1-SNAPSHOT ", + " 1.0.0-rc.1+build.1 ", + " 1.0.0 ", + " 1.0.0+0.3.7 ", + " 1.0.0.23 ", + " 1.3.7+build ", + " 1.3.7+build.2.b8f12d7 ", + " 1.3.7+build.11.e0f985a", + "99.100-20130127+r123", + }; + + // on doit avoir ici les memes entrees que versions dans le meme ordre + String[][] versionSplits = { + {"0", null, null, null}, + {"0.0.0", null, null, "SNAPSHOT"}, + {"0.0.0", null, null, null}, + {"1.0.0", "alpha", null, "SNAPSHOT"}, + {"1.0.0", "alpha", null, null}, + {"1.0.0", "alpha.1", null, null}, + {"1.0.0", "beta.2", null, null}, + {"1.0.0", "beta.11", null, null}, + {"1.0.0", "rc.1", null, null}, + {"1.0.0", "rc.1", "build.1", "SNAPSHOT"}, + {"1.0.0", "rc.1", "build.1", null}, + {"1.0.0", null, null, null}, + {"1.0.0", null, "0.3.7", null}, + {"1.0.0.23", null, null, null}, + {"1.3.7", null, "build", null}, + {"1.3.7", null, "build.2.b8f12d7", null}, + {"1.3.7", null, "build.11.e0f985a", null}, + {"99.100", "20130127", "r123", null}, + }; + + @Test + public void testCreation() { + for(int i=0; i<versions.length; i++) { + SemVer v = new SemVer(versions[i]); + SemVer vs = SemVer.creator(versionSplits[i]).done(); + Assert.assertEquals(v, vs); + + Assert.assertEquals(versionSplits[i][0], v.getVersion()); + Assert.assertEquals(versionSplits[i][1], v.getPrerelease()); + Assert.assertEquals(versionSplits[i][2], v.getBuild()); + Assert.assertEquals(versionSplits[i][3], v.getSnapshot()); + } + } + + @Test + public void testCreator() { + SemVer v = new SemVer(" 1.0.0-rc.1+build.1-SNAPSHOT "); + SemVer n = SemVer.creator(v).setVersion(1,1,3).setPrerelease("rc.2").setBuild("r123").setSnapshot(false).done(); + Assert.assertEquals("1.1.3-rc.2+r123", n.toString()); + } + + @Test + public void testInc() { + + String[][] testIncValue = { + {"0", "1"}, + {"0.0.0-SNAPSHOT", "1.0.0-SNAPSHOT", "0.1.0-SNAPSHOT", "0.0.1-SNAPSHOT"}, + {"0.0.0", "1.0.0", "0.1.0", "0.0.1"}, + {"1.0.0-alpha-SNAPSHOT", "2.0.0-alpha-SNAPSHOT", "1.1.0-alpha-SNAPSHOT", "1.0.1-alpha-SNAPSHOT"}, + {"1.0.0-alpha", "2.0.0-alpha", "1.1.0-alpha", "1.0.1-alpha"}, + {"1.0.0-alpha.1", "2.0.0-alpha.1", "1.1.0-alpha.1", "1.0.1-alpha.1"}, + {" 1.0.0.23 ", " 2.0.0.23 ", " 1.1.0.23 ", " 1.0.1.23 ", " 1.0.0.24 "}, + {"99.100-20130127+r123", "100.100-20130127+r123", "99.101-20130127+r123"}, + }; + + for (int i=1; i<testIncValue.length; i++) { + SemVer version = new SemVer(testIncValue[i][0]); + Assert.assertEquals(String.format( + "Le nombre de composante doit correspondre au nombre de test a faire %s", + Arrays.toString(testIncValue[i])), + testIncValue[i].length-1, version.getVersionCount()); + for (int x=1; x<testIncValue[i].length; x++) { + SemVer expected = new SemVer(testIncValue[i][x]); + SemVer inc = SemVer.creator(version).incVersion(x-1, 1).done(); + Assert.assertEquals(expected, inc); + } + } + } + + @Test + public void testIncMajorMinorPatch() { + // on test seulement sur un exemple, les autres cas sont gere par le testInc + SemVer version = new SemVer(" 1.0.0.23 "); + + SemVer incMajor = SemVer.creator(version).incMajor().done(); + Assert.assertEquals(new SemVer(" 2.0.0.23 "), incMajor); + + SemVer incMinor = SemVer.creator(version).incMinor().done(); + Assert.assertEquals(new SemVer(" 1.1.0.23 "), incMinor); + + SemVer incPatch = SemVer.creator(version).incPatch().done(); + Assert.assertEquals(new SemVer(" 1.0.1.23 "), incPatch); + } + + @Test + public void testGetComposant() { + SemVer v = new SemVer(" 1.0.3-rc.1+build.1-SNAPSHOT "); + Assert.assertEquals("1", v.getMajor()); + Assert.assertEquals("0", v.getMinor()); + Assert.assertEquals("3", v.getPatch()); + + Assert.assertEquals("rc", v.getPrerelease(0)); + Assert.assertEquals("1", v.getPrerelease(1)); + + Assert.assertEquals("build", v.getBuild(0)); + Assert.assertEquals("1", v.getBuild(1)); + + Assert.assertEquals("SNAPSHOT", v.getSnapshot()); + + } + + @Test + public void testToJavaIdentifier() { + SemVer v = new SemVer(" 1.0.3-rc.1+build.1-SNAPSHOT "); + Assert.assertEquals("1_0_3_rc_1_build_1_SNAPSHOT", v.toJavaIdentifier()); + } + + /** + * Ce test ne sert pas vraiment en temps normale, mais lorsqu'il y a un + * test qui fail dans testAll, il est pratique de remettre le test qui + * echoue plus specifiquement ici pour le debug + */ + @Test + public void testOne() { + SemVer vi = new SemVer(" 1.0.0+0.3.7 "); + SemVer vj = new SemVer(" 1.0.0.23 "); + + int result = normalize(vi.compareTo(vj)); + int expected = -1; + + Assert.assertTrue(String.format( + "Bad compare: Compare(%s, %s) = %s, expected %s", + vi, vj, result, expected), + expected == result); +// System.out.println(String.format( +// "Good compare: Compare(%s, %s) = %s, expected %s", +// vi, vj, result, expected)); + } + + @Test + public void testAll() { + for (int i=0; i<versions.length; i++) { + for (int j=0; j<versions.length; j++) { + SemVer vi = new SemVer(versions[i]); + SemVer vj = new SemVer(versions[j]); + + int result = normalize(vi.compareTo(vj)); + int expected = Integer.compare(i, j); + + Assert.assertTrue(String.format( + "Bad compare: Compare(%s, %s) = %s, expected %s", + vi, vj, result, expected), + expected == result); + } + } + } + + /** + * Si le comparator ne renvoi pas -1, 0, 1 on normalize pour avoir -1, 0, 1 + * @param v + * @return + */ + protected int normalize(int v) { + int result = v; + if (v != 0) { + result = v / Math.abs(v); + } + return result; + } +}
participants (1)
-
bpoussin@users.nuiton.org