Skip to content

Commit

Permalink
Fix StringUtil.skewer to properly convert camelCase and upper case na…
Browse files Browse the repository at this point in the history
…mes (#1042)
  • Loading branch information
radcortez authored Nov 7, 2023
1 parent 2e8b790 commit 82756a6
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -299,77 +299,52 @@ public static String skewer(String camelHumps) {
}

public static String skewer(String camelHumps, char separator) {
return skewer(camelHumps, 0, camelHumps.length(), new StringBuilder(), separator);
}

private static String skewer(String camelHumps, int start, int end, StringBuilder b, char separator) {
int end = camelHumps.length();
StringBuilder b = new StringBuilder();
if (camelHumps.isEmpty()) {
throw new IllegalArgumentException("Method seems to have an empty name");
}
int cp = camelHumps.codePointAt(start);
b.appendCodePoint(Character.toLowerCase(cp));
start += Character.charCount(cp);
if (start == end) {
// a lonely character at the end of the string
return b.toString();
}
if (Character.isUpperCase(cp)) {
// all-uppercase words need one code point of lookahead
int nextCp = camelHumps.codePointAt(start);
if (Character.isUpperCase(nextCp)) {
// it's some kind of `WORD`
for (;;) {
b.appendCodePoint(Character.toLowerCase(nextCp));
start += Character.charCount(cp);
cp = nextCp;
if (start == end) {
return b.toString();
}
nextCp = camelHumps.codePointAt(start);
// combine non-letters in with this name
if (Character.isLowerCase(nextCp)) {

for (int i = 0; i < end; i++) {
char c = camelHumps.charAt(i);
if (Character.isLowerCase(c)) {
b.append(c);
} else if (Character.isUpperCase(c)) {
if (i > 0) {
char last = camelHumps.charAt(i - 1);
if (last != '_' && last != '-') {
b.append(separator);
return skewer(camelHumps, start, end, b, separator);
}
}
// unreachable
} else {
// it was the start of a `Word`; continue until we hit the end or an uppercase.
b.appendCodePoint(nextCp);
start += Character.charCount(nextCp);
for (;;) {
if (start == end) {
return b.toString();
b.append(Character.toLowerCase(c));
int j = i + 1;
for (; j < end; j++) {
char u = camelHumps.charAt(j);
if (Character.isUpperCase(u) || Character.isDigit(u)) {
b.append(Character.toLowerCase(u));
} else {
if (j > i + 1 && u != '_') {
b.insert(b.length() - 1, separator);
}
j--;
break;
}
cp = camelHumps.codePointAt(start);
// combine non-letters in with this name
if (Character.isUpperCase(cp)) {
}
i = j;
} else if (Character.isDigit(c)) {
b.append(c);
} else {
if (i > 0) {
char last = camelHumps.charAt(i - 1);
if (last != '_' && last != '-') {
b.append(separator);
return skewer(camelHumps, start, end, b, separator);
}
b.appendCodePoint(cp);
start += Character.charCount(cp);
}
// unreachable
}
// unreachable
} else {
// it's some kind of `word`
for (;;) {
cp = camelHumps.codePointAt(start);
// combine non-letters in with this name
if (Character.isUpperCase(cp)) {
b.append(separator);
return skewer(camelHumps, start, end, b, separator);
}
b.appendCodePoint(cp);
start += Character.charCount(cp);
if (start == end) {
return b.toString();
} else {
b.append(c);
}
}
// unreachable
}
// unreachable

return b.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,46 @@ void escapingSituations() {

@Test
void skewer() {
assertEquals("sigusr1", StringUtil.skewer("sigusr1"));

assertThrows(IllegalArgumentException.class, () -> StringUtil.skewer(""));
assertThrows(IllegalArgumentException.class, () -> StringUtil.skewer("", '.'));

assertEquals("my-property", StringUtil.skewer("myProperty"));
assertEquals("my.property", StringUtil.skewer("myProperty", '.'));

assertEquals("-", StringUtil.skewer("-"));
assertEquals("_", StringUtil.skewer("_"));
assertEquals("a", StringUtil.skewer("a"));
assertEquals("a", StringUtil.skewer("A"));
assertEquals("a", StringUtil.skewer("a", '.'));
assertEquals("a-b", StringUtil.skewer("a-b"));
assertEquals("_a", StringUtil.skewer("_a"));
assertEquals("_a-b", StringUtil.skewer("_a_b"));

assertEquals("my-property-abc", StringUtil.skewer("myPropertyABC"));
assertEquals("my.property.abc", StringUtil.skewer("myPropertyABC", '.'));

assertEquals("my-property-abc-abc", StringUtil.skewer("myPropertyABCabc"));
assertEquals("my.property.abc.abc", StringUtil.skewer("myPropertyABCabc", '.'));
assertEquals("my-property-ab-cabc", StringUtil.skewer("myPropertyABCabc"));
assertEquals("my.property.ab.cabc", StringUtil.skewer("myPropertyABCabc", '.'));

assertEquals("is-same-rm-override", StringUtil.skewer("isSameRMOverride"));
assertEquals("http-client-http-conduit-factory", StringUtil.skewer("HttpClientHTTPConduitFactory"));
assertEquals("url-connection-http-conduit-factory", StringUtil.skewer("URLConnectionHTTPConduitFactory"));
assertEquals("abc-default", StringUtil.skewer("ABCDefault"));
assertEquals("abc", StringUtil.skewer("ABC"));

assertEquals("discard", StringUtil.skewer("discard"));
assertEquals("a-b", StringUtil.skewer("A_B"));
assertEquals("read-uncommitted", StringUtil.skewer("READ_UNCOMMITTED"));
assertEquals("_read-uncommitted", StringUtil.skewer("_READ_UNCOMMITTED"));
assertEquals("read-uncommitted", StringUtil.skewer("READ__UNCOMMITTED"));
assertEquals("_read-uncommitted", StringUtil.skewer("_READ__UNCOMMITTED"));
assertEquals("sigusr1", StringUtil.skewer("SIGUSR1"));
assertEquals("sigusr1", StringUtil.skewer("sigusr1"));
assertEquals("trend-breaker", StringUtil.skewer("TrendBreaker"));
assertEquals("making-life-difficult", StringUtil.skewer("MAKING_LifeDifficult"));
assertEquals("making-life-difficult", StringUtil.skewer("makingLifeDifficult"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,7 @@ public E convert(final String value) throws IllegalArgumentException, NullPointe
}

private static String hyphenate(String value) {
// We cannot be sure about the format of the enum names
return StringUtil.skewer(value).replaceAll("_-", "-").replaceAll("_", "-");
return StringUtil.skewer(value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public void convertMyEnum() {
assertEquals(hyphenateEnumConverter.convert("TrendBreaker"), MyEnum.TrendBreaker);
assertEquals(hyphenateEnumConverter.convert("trend-breaker"), MyEnum.TrendBreaker);
assertEquals(hyphenateEnumConverter.convert("MAKING_LifeDifficult"), MyEnum.MAKING_LifeDifficult);
//assertEquals(hyphenateEnumConverter.convert("making-life-difficult"), MyEnum.MAKING_LifeDifficult);
assertEquals(hyphenateEnumConverter.convert("making-life-difficult"), MyEnum.MAKING_LifeDifficult);
}

@Test
Expand All @@ -101,7 +101,7 @@ public void convertMyOtherEnum() {
assertEquals(hyphenateEnumConverter.convert("makingLifeDifficult"), MyOtherEnum.makingLifeDifficult);
assertEquals(hyphenateEnumConverter.convert("making-life-difficult"), MyOtherEnum.makingLifeDifficult);
assertEquals(hyphenateEnumConverter.convert("READ__UNCOMMITTED"), MyOtherEnum.READ__UNCOMMITTED);
//assertEquals(hyphenateEnumConverter.convert("read-uncommitted"), MyOtherEnum.READ__UNCOMMITTED);
assertEquals(hyphenateEnumConverter.convert("read-uncommitted"), MyOtherEnum.READ__UNCOMMITTED);
}

@Test
Expand All @@ -111,7 +111,7 @@ public void testIllegalEnumConfigUtilConversion() {
() -> hyphenateEnumConverter.convert("READUNCOMMITTED"));
assertEquals(
"SRCFG00049: Cannot convert READUNCOMMITTED to enum class io.smallrye.config.ImplicitConverterTest$MyEnum, " +
"allowed values: trend-breaker,discard,making-l-ife-difficult,sigusr1,read-uncommitted,a-b",
"allowed values: trend-breaker,making-life-difficult,discard,sigusr1,read-uncommitted,a-b",
exception.getMessage());
}

Expand Down

0 comments on commit 82756a6

Please sign in to comment.