mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SemVer: support for prerelease segment - post review fixes and additional tests
GitOrigin-RevId: 076ccaae4af5f6fbb1d8c4dbb6111579ccc54be5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
fb74085e49
commit
f2b1839a7d
@@ -2850,18 +2850,13 @@ public class StringUtil extends StringUtilRt {
|
||||
int length1 = s1.length();
|
||||
int length2 = s2.length();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
for (; i < length1 && j < length2; i++, j++) {
|
||||
int diff = compare(s1.charAt(i), s2.charAt(j), ignoreCase);
|
||||
for (; i < length1 && i < length2; i++) {
|
||||
int diff = compare(s1.charAt(i), s2.charAt(i), ignoreCase);
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
}
|
||||
}
|
||||
if (i < length1) return +1;
|
||||
if (j < length2) return -1;
|
||||
if (length1 != length2) return length1 - length2;
|
||||
|
||||
return ignoreCase ? compare(s1, s2, false) : 0;
|
||||
return length1 - length2;
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
|
||||
@@ -21,6 +21,8 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static com.intellij.openapi.util.text.StringUtil.isNotNegativeNumber;
|
||||
|
||||
/**
|
||||
* Holds <a href="http://semver.org">Semantic Version</a>.
|
||||
*/
|
||||
@@ -151,13 +153,15 @@ public final class SemVer implements Comparable<SemVer> {
|
||||
|
||||
CharSequence segment1 = new CharSequenceSubSequence(pre1, start1, end1);
|
||||
CharSequence segment2 = new CharSequenceSubSequence(pre2, start2, end2);
|
||||
if (isNumeric(segment1)) {
|
||||
if (!isNumeric(segment2)) {
|
||||
if (isNotNegativeNumber(segment1)) {
|
||||
if (!isNotNegativeNumber(segment2)) {
|
||||
// According to SemVer specification numeric segments has lower precedence
|
||||
// than non-numeric segments
|
||||
return -1;
|
||||
}
|
||||
diff = compareNumeric(segment1, segment2);
|
||||
}
|
||||
else if (isNumeric(segment2)) {
|
||||
else if (isNotNegativeNumber(segment2)) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
@@ -184,23 +188,12 @@ public final class SemVer implements Comparable<SemVer> {
|
||||
int length1 = segment1.length();
|
||||
int length2 = segment2.length();
|
||||
int diff = Integer.compare(length1, length2);
|
||||
for (int i = 0; i <= length1 && diff == 0; i++) {
|
||||
for (int i = 0; i < length1 && diff == 0; i++) {
|
||||
diff = segment1.charAt(i) - segment2.charAt(i);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
private static boolean isNumeric(CharSequence segment) {
|
||||
int length = segment.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
int ch = segment.charAt(i);
|
||||
if (ch < '0' || ch > '9') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static SemVer parseFromText(@Nullable String text) {
|
||||
if (text != null) {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.util.text;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
@@ -50,27 +51,37 @@ public class SemVerTest {
|
||||
assertThat(parse("11.123.0-a.b.c-1")).isEqualByComparingTo(parse("11.123.0-a.b.c-1"));
|
||||
|
||||
assertPrecedence("0.10.0", "1.0.0");
|
||||
assertPrecedence("1.0.0","2.10.0");
|
||||
assertPrecedence("1.0.0", "2.10.0");
|
||||
assertPrecedence("0.5.1000", "0.30.0");
|
||||
assertPrecedence("0.30.10","0.100.0");
|
||||
assertPrecedence("0.30.10", "0.100.0");
|
||||
|
||||
assertPrecedence("2.9.100", "2.9.123-test");
|
||||
assertPrecedence("2.9.123-test","2.9.124");
|
||||
assertPrecedence("2.9.123","2.9.124-test");
|
||||
assertPrecedence("2.9.123-test", "2.9.124");
|
||||
assertPrecedence("2.9.123", "2.9.124-test");
|
||||
|
||||
assertPrecedence("1.2.3-a","1.2.3");
|
||||
assertPrecedence("1.2.3-a", "1.2.3");
|
||||
|
||||
assertPrecedence("1.2.3-12","1.2.3-a");
|
||||
assertPrecedence("1.2.3-22","1.2.3-100");
|
||||
assertPrecedence("1.2.3-22","1.2.3-31");
|
||||
assertPrecedence("1.2.3-12", "1.2.3-a");
|
||||
assertPrecedence("1.2.3-22", "1.2.3-100");
|
||||
assertPrecedence("1.2.3-22", "1.2.3-31");
|
||||
assertPrecedence("1.2.3-22", "1.2.3-222");
|
||||
|
||||
assertPrecedence("1.2.3-a.b.c","1.2.3-a.b.d");
|
||||
assertPrecedence("1.2.3-a.b.c","1.2.3-a.b.c.a");
|
||||
assertPrecedence("1.2.3-a.b.c", "1.2.3-a.b.d");
|
||||
assertPrecedence("1.2.3-a.b.c", "1.2.3-a.b.c.a");
|
||||
|
||||
assertPrecedence("1.2.3-a.b.1","1.2.3-a.b.c");
|
||||
assertPrecedence("1.2.3-a.b.1","1.2.3-a.c.1");
|
||||
assertPrecedence("1.2.3-a.cbc.100","1.2.3-a.cca.1");
|
||||
assertPrecedence("1.2.3-a.cb.1","1.2.3-a.cba.1");
|
||||
assertPrecedence("1.2.3-a.b.1", "1.2.3-a.b.c");
|
||||
assertPrecedence("1.2.3-a.b.1", "1.2.3-a.c.1");
|
||||
assertPrecedence("1.2.3-a.cbc.100", "1.2.3-a.cca.1");
|
||||
assertPrecedence("1.2.3-a.cb.1", "1.2.3-a.cba.1");
|
||||
|
||||
// Example from SemVer documentation https://semver.org/#spec-item-11
|
||||
assertPrecedence("1.0.0-alpha", "1.0.0-alpha.1");
|
||||
assertPrecedence("1.0.0-alpha.1", "1.0.0-alpha.beta");
|
||||
assertPrecedence("1.0.0-alpha.beta", "1.0.0-beta");
|
||||
assertPrecedence("1.0.0-beta", "1.0.0-beta.2");
|
||||
assertPrecedence("1.0.0-beta.2", "1.0.0-beta.11");
|
||||
assertPrecedence("1.0.0-beta.11", "1.0.0-rc.1");
|
||||
assertPrecedence("1.0.0-rc.1", "1.0.0");
|
||||
|
||||
Assert.assertTrue(parse("4.12.5").isGreaterOrEqualThan(4, 12, 5));
|
||||
Assert.assertTrue(parse("4.12.5-a").isGreaterOrEqualThan(4, 12, 5));
|
||||
@@ -95,7 +106,11 @@ public class SemVerTest {
|
||||
assertThat(v1).isNotEqualTo(v2);
|
||||
}
|
||||
|
||||
private static void assertParsed(String version, int expectedMajor, int expectedMinor, int expectedPatch, @Nullable String expectedPreRelease) {
|
||||
private static void assertParsed(@NotNull String version,
|
||||
int expectedMajor,
|
||||
int expectedMinor,
|
||||
int expectedPatch,
|
||||
@Nullable String expectedPreRelease) {
|
||||
assertThat(parse(version)).isEqualTo(new SemVer(version, expectedMajor, expectedMinor, expectedPatch, expectedPreRelease));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.intellij.openapi.util.text.LineColumn;
|
||||
import com.intellij.openapi.util.text.NaturalComparator;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.LineSeparator;
|
||||
import com.intellij.util.TripleFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.xml.util.XmlStringUtil;
|
||||
import org.jdom.Verifier;
|
||||
@@ -199,16 +200,16 @@ public class StringUtilTest {
|
||||
@Test
|
||||
public void testNaturalCompare() {
|
||||
|
||||
final List<String> numbers = Arrays.asList("1a000001", "000001a1", "001a0001", "0001A001" , "00001a01", "01a00001");
|
||||
final List<String> numbers = Arrays.asList("1a000001", "000001a1", "001a0001", "0001A001", "00001a01", "01a00001");
|
||||
numbers.sort(NaturalComparator.INSTANCE);
|
||||
assertEquals(Arrays.asList("1a000001", "01a00001", "001a0001", "0001A001" , "00001a01", "000001a1"), numbers);
|
||||
assertEquals(Arrays.asList("1a000001", "01a00001", "001a0001", "0001A001", "00001a01", "000001a1"), numbers);
|
||||
|
||||
final List<String> test = Arrays.asList("test011", "test10", "test10a", "test010");
|
||||
test.sort(NaturalComparator.INSTANCE);
|
||||
assertEquals(Arrays.asList("test10", "test10a", "test010", "test011"), test);
|
||||
|
||||
final List<String> strings = Arrays.asList("Test99", "tes0", "test0", "testing", "test", "test99", "test011", "test1",
|
||||
"test 3", "test2", "test10a", "test10", "1.2.10.5", "1.2.9.1");
|
||||
"test 3", "test2", "test10a", "test10", "1.2.10.5", "1.2.9.1");
|
||||
strings.sort(NaturalComparator.INSTANCE);
|
||||
assertEquals(Arrays.asList("1.2.9.1", "1.2.10.5", "tes0", "test", "test0", "test1", "test2", "test 3", "test10", "test10a",
|
||||
"test011", "Test99", "test99", "testing"), strings);
|
||||
@@ -216,13 +217,14 @@ public class StringUtilTest {
|
||||
final List<String> strings2 = Arrays.asList("t1", "t001", "T2", "T002", "T1", "t2");
|
||||
strings2.sort(NaturalComparator.INSTANCE);
|
||||
assertEquals(Arrays.asList("T1", "t1", "t001", "T2", "t2", "T002"), strings2);
|
||||
assertEquals(1 ,StringUtil.naturalCompare("7403515080361171695", "07403515080361171694"));
|
||||
assertEquals(1, StringUtil.naturalCompare("7403515080361171695", "07403515080361171694"));
|
||||
assertEquals(-14, StringUtil.naturalCompare("_firstField", "myField1"));
|
||||
//idea-80853
|
||||
final List<String> strings3 =
|
||||
Arrays.asList("C148A_InsomniaCure", "C148B_Escape", "C148C_TersePrincess", "C148D_BagOfMice", "C148E_Porcelain");
|
||||
strings3.sort(NaturalComparator.INSTANCE);
|
||||
assertEquals(Arrays.asList("C148A_InsomniaCure", "C148B_Escape", "C148C_TersePrincess", "C148D_BagOfMice", "C148E_Porcelain"), strings3);
|
||||
assertEquals(Arrays.asList("C148A_InsomniaCure", "C148B_Escape", "C148C_TersePrincess", "C148D_BagOfMice", "C148E_Porcelain"),
|
||||
strings3);
|
||||
|
||||
final List<String> l = Arrays.asList("a0002", "a0 2", "a001");
|
||||
l.sort(NaturalComparator.INSTANCE);
|
||||
@@ -374,7 +376,8 @@ public class StringUtilTest {
|
||||
@SuppressWarnings("StringToUpperCaseOrToLowerCaseWithoutLocale")
|
||||
public void testReplaceReturnReplacementIfTextEqualsToReplacedText() {
|
||||
String str = "/tmp";
|
||||
assertSame(str, StringUtil.replace("$PROJECT_FILE$", "$PROJECT_FILE$".toLowerCase().toUpperCase() /* ensure new String instance */, str));
|
||||
assertSame(str,
|
||||
StringUtil.replace("$PROJECT_FILE$", "$PROJECT_FILE$".toLowerCase().toUpperCase() /* ensure new String instance */, str));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -453,6 +456,36 @@ public class StringUtilTest {
|
||||
assertTrue(StringUtil.contains("12", "2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompareCharSequence() {
|
||||
TripleFunction<CharSequence, CharSequence, Boolean, Boolean> assertPrecedence =
|
||||
(lesser, greater, ignoreCase) -> {
|
||||
assertTrue(StringUtil.compare(lesser, greater, ignoreCase) < 0);
|
||||
assertTrue(StringUtil.compare(greater, lesser, ignoreCase) > 0);
|
||||
return true;
|
||||
};
|
||||
TripleFunction<CharSequence, CharSequence, Boolean, Boolean> assertEquality =
|
||||
(lesser, greater, ignoreCase) -> {
|
||||
assertEquals(0, StringUtil.compare(lesser, greater, ignoreCase));
|
||||
assertEquals(0, StringUtil.compare(greater, lesser, ignoreCase));
|
||||
return true;
|
||||
};
|
||||
|
||||
assertPrecedence.fun("A","b", true);
|
||||
assertPrecedence.fun("a","aa", true);
|
||||
assertPrecedence.fun("abb","abC", true);
|
||||
|
||||
assertPrecedence.fun("A","a", false);
|
||||
assertPrecedence.fun("Aa","a", false);
|
||||
assertPrecedence.fun("a","aa", false);
|
||||
assertPrecedence.fun("-","A", false);
|
||||
|
||||
assertEquality.fun("a","A",true);
|
||||
assertEquality.fun("aa12b","Aa12B",true);
|
||||
|
||||
assertEquality.fun("aa12b","aa12b",false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetectSeparators() {
|
||||
assertNull(StringUtil.detectSeparators(""));
|
||||
@@ -549,7 +582,7 @@ public class StringUtilTest {
|
||||
assertEquals("2 m 3 s", StringUtil.formatDurationApproximate(123456));
|
||||
assertEquals("1 h 1 m", StringUtil.formatDurationApproximate(3659009));
|
||||
assertEquals("2 h", StringUtil.formatDurationApproximate(7199000));
|
||||
assertEquals("1 d", StringUtil.formatDurationApproximate((23*60*60 + 59*60 + 59) * 1000L));
|
||||
assertEquals("1 d", StringUtil.formatDurationApproximate((23 * 60 * 60 + 59 * 60 + 59) * 1000L));
|
||||
assertEquals("1 yr 1 mo", StringUtil.formatDurationApproximate(33786061001L));
|
||||
}
|
||||
|
||||
@@ -558,7 +591,8 @@ public class StringUtilTest {
|
||||
assertEquals("<![CDATA[abc]]>", XmlStringUtil.wrapInCDATA("abc"));
|
||||
assertEquals("<![CDATA[abc]]]><![CDATA[]>]]>", XmlStringUtil.wrapInCDATA("abc]]>"));
|
||||
assertEquals("<![CDATA[abc]]]><![CDATA[]>def]]>", XmlStringUtil.wrapInCDATA("abc]]>def"));
|
||||
assertEquals("<![CDATA[123<![CDATA[wow<&>]]]><![CDATA[]>]]]><![CDATA[]><![CDATA[123]]>", XmlStringUtil.wrapInCDATA("123<![CDATA[wow<&>]]>]]><![CDATA[123"));
|
||||
assertEquals("<![CDATA[123<![CDATA[wow<&>]]]><![CDATA[]>]]]><![CDATA[]><![CDATA[123]]>",
|
||||
XmlStringUtil.wrapInCDATA("123<![CDATA[wow<&>]]>]]><![CDATA[123"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -571,7 +605,7 @@ public class StringUtilTest {
|
||||
|
||||
@Test
|
||||
public void testIndexOf_1() {
|
||||
char[] chars = new char[]{'a','b','c','d','a','b','c','d','A','B','C','D'};
|
||||
char[] chars = new char[]{'a', 'b', 'c', 'd', 'a', 'b', 'c', 'd', 'A', 'B', 'C', 'D'};
|
||||
assertEquals(2, StringUtil.indexOf(chars, 'c', 0, 12, false));
|
||||
assertEquals(2, StringUtil.indexOf(chars, 'C', 0, 12, false));
|
||||
assertEquals(10, StringUtil.indexOf(chars, 'C', 0, 12, true));
|
||||
@@ -776,10 +810,12 @@ public class StringUtilTest {
|
||||
CharSequence s = ByteArrayCharSequence.convertToBytesIfPossible("test");
|
||||
assertTrue(s instanceof ByteArrayCharSequence || SystemInfo.IS_AT_LEAST_JAVA9 && s.getClass() == String.class);
|
||||
CharSequence first = StringUtil.first(s, 1, false);
|
||||
assertTrue(String.valueOf(first.getClass()), first instanceof CharSequenceSubSequence || SystemInfo.IS_AT_LEAST_JAVA9 && s.getClass() == String.class);
|
||||
assertTrue(String.valueOf(first.getClass()),
|
||||
first instanceof CharSequenceSubSequence || SystemInfo.IS_AT_LEAST_JAVA9 && s.getClass() == String.class);
|
||||
assertEquals("t", first.toString());
|
||||
CharSequence last = StringUtil.last(s, 1, false);
|
||||
assertTrue(String.valueOf(last.getClass()), last instanceof CharSequenceSubSequence|| SystemInfo.IS_AT_LEAST_JAVA9 && s.getClass() == String.class);
|
||||
assertTrue(String.valueOf(last.getClass()),
|
||||
last instanceof CharSequenceSubSequence || SystemInfo.IS_AT_LEAST_JAVA9 && s.getClass() == String.class);
|
||||
assertEquals("t", last.toString());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user