You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2018/12/27 06:56:45 UTC
[groovy] branch master updated: GROOVY-8939: Add methods in
StringGroovyMethods for better API Usage (closes #846)
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 8c5ad7b GROOVY-8939: Add methods in StringGroovyMethods for better API Usage (closes #846)
8c5ad7b is described below
commit 8c5ad7b0ddc5704d514cbaf135bceaaf401d2324
Author: Adithyan K <ad...@gmail.com>
AuthorDate: Wed Dec 26 07:24:30 2018 +0530
GROOVY-8939: Add methods in StringGroovyMethods for better API Usage (closes #846)
---
.../groovy/runtime/StringGroovyMethods.java | 516 +++++++++++++++++++++
src/test/groovy/GroovyMethodsTest.groovy | 334 +++++++++++++
2 files changed, 850 insertions(+)
diff --git a/src/main/java/org/codehaus/groovy/runtime/StringGroovyMethods.java b/src/main/java/org/codehaus/groovy/runtime/StringGroovyMethods.java
index ddca930..66b886c 100644
--- a/src/main/java/org/codehaus/groovy/runtime/StringGroovyMethods.java
+++ b/src/main/java/org/codehaus/groovy/runtime/StringGroovyMethods.java
@@ -3888,4 +3888,520 @@ public class StringGroovyMethods extends DefaultGroovyMethodsSupport {
return self.toString().matches("\\s*");
}
+
+ /**
+ * Returns the last <code>num</code> elements from this CharSequence.
+ * <pre class="groovyTestCase">
+ * def text = "Groovy"
+ * assert text.takeRight( 0 ) == ''
+ * assert text.takeRight( 2 ) == 'vy'
+ * assert text.takeRight( 7 ) == 'Groovy'
+ * </pre>
+ *
+ * @param self the original CharSequence
+ * @param num the number of chars to take from this CharSequence from the right
+ * @return a CharSequence consisting of the last <code>num</code> chars,
+ * or else the whole CharSequence if it has less than <code>num</code> elements.
+ * @since 3.0.0
+ */
+ public static CharSequence takeRight(CharSequence self, int num) {
+ if (num < 0)
+ return self.subSequence(0, 0);
+
+ int begin = Math.max(0, self.length() - num);
+ return self.subSequence(begin, self.length());
+ }
+
+ /**
+ * A GString variant of the equivalent CharSequence method {@link #takeRight(CharSequence, int)}
+ *
+ * @param self the original CharSequence
+ * @param num the number of chars to take from this CharSequence from the right
+ * @return a String consisting of the last <code>num</code> chars,
+ * or else the whole CharSequence if it has less than <code>num</code> elements.
+ * @since 3.0.0
+ */
+ public static String takeRight(String self, int num) {
+ return (String) takeRight((CharSequence) self, num);
+ }
+
+ /**
+ * A String variant of the equivalent CharSequence method {@link #takeRight(CharSequence, int)}
+ *
+ * @param self the original GString
+ * @param num the number of chars to take from this GString from the right
+ * @return a String consisting of the last <code>num</code> chars,
+ * or else the whole GString if it has less than <code>num</code> elements.
+ * @since 3.0.0
+ */
+ public static String takeRight(GString self, int num) {
+ return takeRight(self.toString(), num);
+ }
+
+ /**
+ * Returns the {@code CharSequence} that exists after the first occurrence of the given
+ * {@code searchString} in this CharSequence
+ *
+ * <pre class="groovyTestCase">
+ * def text = "Groovy development. Groovy team"
+ * assert text.takeAfter( 'Groovy' ) == ' development. Groovy team'
+ * assert text.takeAfter( 'team' ) == ''
+ * assert text.takeAfter( '' ) == ''
+ * assert text.takeAfter( 'Unavailable text' ) == ''
+ * assert text.takeAfter( null ) == ''
+ * </pre>
+ *
+ * @param self the original CharSequence
+ * @param searchString CharSequence that is searched in this CharSequence
+ * @return CharSequence that is after the given searchString and empty string if it does not exist
+ * @since 3.0.0
+ */
+ public static CharSequence takeAfter(CharSequence self, CharSequence searchString) {
+ if (searchString == null || searchString.toString().isEmpty() || self.length() <= searchString.length())
+ return self.subSequence(0, 0);
+
+ String s = self.toString();
+
+ int index = s.indexOf(searchString.toString());
+
+ return (index == -1) ? self.subSequence(0, 0) : self.subSequence(index + searchString.length(), self.length());
+ }
+
+ /**
+ * A String variant of the equivalent CharSequence method {@link #takeAfter(CharSequence, CharSequence)}
+ *
+ * @param self the original CharSequence
+ * @param searchString String that is searched in this CharSequence
+ * @return String that is after the given searchString and empty string if it does not exist
+ * @since 3.0.0
+ */
+ public static String takeAfter(String self, CharSequence searchString) {
+ return (String) takeAfter((CharSequence) self, searchString);
+ }
+
+ /**
+ * A GString variant of the equivalent CharSequence method {@link #takeAfter(CharSequence, CharSequence)}
+ *
+ * @param self the original CharSequence
+ * @param searchString CharSequence that is searched in this CharSequence
+ * @return String that is after the given searchString and empty string if it does not exist
+ * @since 3.0.0
+ */
+ public static String takeAfter(GString self, CharSequence searchString) {
+ return takeAfter(self.toString(), searchString);
+ }
+
+ /**
+ * Returns the {@code CharSequence} that exists before the first occurrence of the given
+ * {@code searchString} in this CharSequence
+ *
+ * <pre class="groovyTestCase">
+ * def text = "Groovy development. Groovy team"
+ *
+ * assert text.takeBefore( ' Groovy ' ) == 'Groovy development.'
+ * assert text.takeBefore( ' ' ) == 'Groovy'
+ * assert text.takeBefore( 'Unavailable text' ) == ''
+ * assert text.takeBefore( null ) == ''
+ * </pre>
+ *
+ * @param self the original CharSequence
+ * @param searchString CharSequence that is searched in this CharSequence
+ * @return CharSequence that is before the given searchString
+ * @since 3.0.0
+ */
+ public static CharSequence takeBefore(CharSequence self, CharSequence searchString) {
+ if (searchString == null || searchString.toString().isEmpty() || self.length() <= searchString.length())
+ return self.subSequence(0, 0);
+
+ String s = self.toString();
+
+ int index = s.indexOf(searchString.toString());
+
+ return (index == -1) ? self.subSequence(0, 0) : self.subSequence(0, index);
+ }
+
+ /**
+ * A GString variant of the equivalent CharSequence method {@link #takeBefore(CharSequence, CharSequence)}
+ *
+ * @param self the original CharSequence
+ * @param searchString CharSequence that is searched in this CharSequence
+ * @return String that is before the given searchString
+ * @since 3.0.0
+ */
+ public static String takeBefore(GString self, String searchString) {
+ return takeBefore(self.toString(), searchString);
+ }
+
+ /**
+ * A String variant of the equivalent CharSequence method {@link #takeBefore(CharSequence, CharSequence)}
+ *
+ * @param self the original CharSequence
+ * @param searchString CharSequence that is searched in this CharSequence
+ * @return String that is before the given searchString
+ * @since 3.0.0
+ */
+ public static String takeBefore(String self, String searchString) {
+ return (String) takeBefore((CharSequence) self, searchString);
+ }
+
+ /**
+ * The method returns new CharSequence after removing the right {@code num} chars. Returns empty String if the
+ * {@code num} is greater than the length of the CharSequence
+ *
+ * <pre class="groovyTestCase">
+ * def text = "groovy"
+ *
+ * assert text.dropRight( 3 ) == 'gro'
+ * assert text.dropRight( 6 ) == ''
+ * assert text.dropRight( 0 ) == 'groovy'
+ * assert text.dropRight( -1 ) == 'groovy'
+ * assert text.dropRight( 10 ) == ''
+ *
+ * </pre>
+ *
+ * @param self the original CharSequence
+ * @param num number of characters
+ * @return CharSequence after removing the right {@code num} chars and empty of the {@code num} is greater than the
+ * length of the CharSequence
+ * @since 3.0.0
+ */
+ public static CharSequence dropRight(CharSequence self, int num) {
+
+ if (num < 0)
+ return self;
+
+ if (num >= self.length())
+ return self.subSequence(0, 0);
+
+ return take(self, self.length() - num);
+ }
+
+ /**
+ * A String variant of the equivalent CharSequence method {@link #dropRight(CharSequence, int)}
+ *
+ * @param self the original CharSequence
+ * @param num number of characters
+ * @return String after removing the right {@code num} chars and empty of the {@code num} is greater than the
+ * length of the CharSequence
+ * @since 3.0.0
+ */
+ public static String dropRight(String self, int num) {
+ return (String) dropRight((CharSequence) self, num);
+ }
+
+
+ /**
+ * A GString variant of the equivalent CharSequence method {@link #dropRight(CharSequence, int)}
+ *
+ * @param self the original CharSequence
+ * @param num number of characters
+ * @return String after removing the right {@code num} chars and empty of the {@code num} is greater than the
+ * length of the CharSequence
+ * @since 3.0.0
+ */
+ public static String dropRight(GString self, int num) {
+ return dropRight(self.toString(), num);
+ }
+
+ /**
+ * Returns the CharSequence that is in between the first occurrence of the given {@code from} and {@code to}
+ * CharSequences and empty if the unavailable inputs are given
+ *
+ * <pre class="groovyTestCase">
+ * def text = "Groovy"
+ *
+ * assert text.takeBetween( 'r', 'v' ) == 'oo'
+ * assert text.takeBetween( 'r', 'z' ) == ''
+ * assert text.takeBetween( 'a', 'r' ) == ''
+ *
+ * </pre>
+ *
+ * @param self the original CharSequence
+ * @param from beginning of search
+ * @param to end of search
+ * @return the CharSequence that is in between the given two CharSequences and empty if the unavailable inputs are
+ * given
+ * @see #takeBetween(CharSequence, CharSequence, CharSequence, int)
+ * @since 3.0.0
+ */
+ public static CharSequence takeBetween(CharSequence self, CharSequence from, CharSequence to) {
+ if (from == null || to == null || from.length() == 0 || to.length() == 0 || from.length() > self.length() || to.length() > self.length())
+ return self.subSequence(0, 0);
+
+ String s = self.toString();
+ String f = from.toString();
+
+ int fi = s.indexOf(f);
+
+ if (fi == -1)
+ return self.subSequence(0, 0);
+
+ String t = to.toString();
+
+ int ti = s.indexOf(t, fi + from.length());
+
+ if (ti == -1)
+ return self.subSequence(0, 0);
+
+ return self.subSequence(fi + from.length(), ti);
+ }
+
+ /**
+ * A String variant of the equivalent CharSequence method {@link #takeBetween(CharSequence, CharSequence, CharSequence)}
+ *
+ * @param self the original CharSequence
+ * @param from beginning of search
+ * @param to end of search
+ * @return String that is in between the given two CharSequences and empty if the unavailable inputs are
+ * given
+ * @since 3.0.0
+ */
+ public static String takeBetween(String self, CharSequence from, CharSequence to) {
+ return (String) takeBetween((CharSequence) self, from, to);
+ }
+
+ /**
+ * A GString variant of the equivalent CharSequence method {@link #takeBetween(CharSequence, CharSequence, CharSequence)}
+ *
+ * @param self the original CharSequence
+ * @param from beginning of search
+ * @param to end of search
+ * @return String that is in between the given two CharSequences and empty if the unavailable inputs are
+ * given
+ * @since 3.0.0
+ */
+ public static String takeBetween(GString self, CharSequence from, CharSequence to) {
+ return takeBetween(self.toString(), from, to);
+ }
+
+ /**
+ * Method to take the characters between the first occurrence of the two subsequent {@code enclosure} strings
+ *
+ * <pre class="groovyTestCase">
+ * def text = "name = 'some name'"
+ *
+ * assert text.takeBetween( "'" ) == 'some name'
+ * assert text.takeBetween( 'z' ) == ''
+ *
+ * </pre>
+ *
+ * @param self the original CharSequence
+ * @param enclosure Enclosure String
+ * @return CharSequence between the 2 subsequent {@code enclosure} strings
+ * @see #takeBetween(CharSequence, CharSequence, int)
+ * @since 3.0.0
+ */
+ public static CharSequence takeBetween(CharSequence self, CharSequence enclosure) {
+ return takeBetween(self, enclosure, enclosure);
+ }
+
+ /**
+ * A String variant of the equivalent CharSequence method {@link #takeBetween(CharSequence, CharSequence)}
+ *
+ * @param self the original GString
+ * @param enclosure Enclosure String
+ * @return String between the 2 subsequent {@code enclosure} strings
+ * @since 3.0.0
+ */
+ public static String takeBetween(String self, CharSequence enclosure) {
+ return (String) takeBetween((CharSequence) self, enclosure);
+ }
+
+ /**
+ * A GString variant of the equivalent CharSequence method {@link #takeBetween(CharSequence, CharSequence)}
+ *
+ * @param self the original GString
+ * @param enclosure Enclosure String
+ * @return String between the 2 subsequent {@code enclosure} strings
+ * @since 3.0.0
+ */
+ public static String takeBetween(GString self, CharSequence enclosure) {
+ return takeBetween(self.toString(), enclosure);
+ }
+
+ /**
+ * Returns the CharSequence that is in between the given the nth (specified by occurrence) pair of
+ * {@code from} and {@code to} CharSequences and empty if the unavailable inputs are given.
+ *
+ * <pre class="groovyTestCase">
+ * def text = "t1=10 ms, t2=100 ms"
+ *
+ * assert text.takeBetween( '=', ' ', 0 ) == '10'
+ * assert text.takeBetween( '=', ' ', 1 ) == '100'
+ * assert text.takeBetween( 't1', 'z' ) == ''
+ * </pre>
+ *
+ * @param self the original CharSequence
+ * @param from beginning of search
+ * @param to end of search
+ * @param occurrence nth occurrence that is to be returned. 0 represents first one
+ * @return the CharSequence that is in between the given the nth (specified by occurrence) pair of
+ * {@code from} and {@code to} CharSequences and empty if the unavailable inputs are given.
+ * @see #takeBetween(CharSequence, CharSequence, CharSequence)
+ * @since 3.0.0
+ */
+ public static CharSequence takeBetween(CharSequence self, CharSequence from, CharSequence to, int occurrence) {
+ if (from == null || to == null || from.length() > self.length() || to.length() > self.length() || (to.length() + from.length() >= self.length()) || occurrence < 0)
+ return self.subSequence(0, 0);
+
+ String s = self.toString();
+ String f = from.toString();
+
+ int start = 0;
+ int counter = 0;
+
+ while (counter <= occurrence) {
+ int fi = s.indexOf(f, start);
+
+ if (fi == -1)
+ return self.subSequence(0, 0);
+
+ int ti = s.indexOf(to.toString(), fi + f.length());
+
+ if (ti == -1)
+ return self.subSequence(0, 0);
+
+ if (counter == occurrence)
+ return self.subSequence(fi + f.length(), ti);
+
+ start = ti + to.length() + 1;
+ counter++;
+ }
+
+ return self.subSequence(0, 0);
+ }
+
+ /**
+ * A String variant of the equivalent CharSequence method
+ * {@link #takeBetween(CharSequence, CharSequence, CharSequence, int)}
+ *
+ * @param self the original CharSequence
+ * @param from beginning of search
+ * @param to end of search
+ * @param occurrence nth occurrence that is to be returned. 0 represents first one
+ * @return the String that is in between the given nth (specified by occurrence) pair of
+ * {@code from} and {@code to} CharSequences and empty if the unavailable inputs are given.
+ * @since 3.0.0
+ */
+ public static String takeBetween(String self, CharSequence from, CharSequence to, int occurrence) {
+ return (String) takeBetween((CharSequence) self, from, to, occurrence);
+ }
+
+ /**
+ * A GString variant of the equivalent CharSequence method
+ * {@link #takeBetween(CharSequence, CharSequence, CharSequence, int)}
+ *
+ * @param self the original CharSequence
+ * @param from beginning of search
+ * @param to end of search
+ * @param occurrence nth occurrence that is to be returned. 0 represents first one
+ * @return the String that is in between the given nth (specified by occurrence) pair of
+ * {@code from} and {@code to} CharSequences and empty if the unavailable inputs are given.
+ * @since 3.0.0
+ */
+ public static String takeBetween(GString self, CharSequence from, CharSequence to, int occurrence) {
+ return takeBetween(self.toString(), from, to, occurrence);
+ }
+
+ /**
+ * Method to take the characters between nth (specified by occurrence) pair of @code enclosure} strings
+ *
+ * <pre class="groovyTestCase">
+ * def text = "t1='10' ms, t2='100' ms"
+ *
+ * assert text.takeBetween( "'", 0 ) == '10'
+ * assert text.takeBetween( "'", 1 ) == '100'
+ * assert text.takeBetween( "'", 2 ) == ''
+ * </pre>
+ *
+ * @param self the original CharSequence
+ * @param enclosure Enclosure String
+ * @param occurrence nth occurrence being returned
+ * @return CharSequence between the nth occurrence of pair of {@code enclosure} strings
+ * @see #takeBetween(CharSequence, CharSequence, int)
+ * @since 3.0.0
+ */
+ public static CharSequence takeBetween(CharSequence self, CharSequence enclosure, int occurrence) {
+ return takeBetween(self, enclosure, enclosure, occurrence);
+ }
+
+ /**
+ * A String variant of the equivalent CharSequence method
+ * {@link #takeBetween(CharSequence, CharSequence, int)}
+ *
+ * @param self the original CharSequence
+ * @param enclosure Enclosure String
+ * @param occurrence nth occurrence being returned
+ * @return String between the nth occurrence of pair of {@code enclosure} strings
+ * @since 3.0.0
+ */
+ public static String takeBetween(String self, CharSequence enclosure, int occurrence) {
+ return (String) takeBetween((CharSequence) self, enclosure, occurrence);
+ }
+
+ /**
+ * A GString variant of the equivalent CharSequence method
+ * {@link #takeBetween(CharSequence, CharSequence, int)}
+ *
+ * @param self the original CharSequence
+ * @param enclosure Enclosure String
+ * @param occurrence nth occurrence being returned
+ * @return String between the nth occurrence of pair of {@code enclosure} strings
+ * @since 3.0.0
+ */
+ public static String takeBetween(GString self, CharSequence enclosure, int occurrence) {
+ return takeBetween(self.toString(), enclosure, occurrence);
+ }
+
+ /**
+ * Checks whether this CharSequence starts with the {@code searchString} ignoring the case considerations
+ *
+ * @param self the original CharSequence
+ * @param searchString CharSequence being checked against this
+ * @return {@code true} if the character sequence represented by the argument is a prefix of this CharSequence
+ * ignoring the case considerations. {@code false} otherwise. Returns false if the argument is null
+ * @since 3.0.0
+ */
+ public static boolean startsWithIgnoreCase(CharSequence self, CharSequence searchString) {
+ if (searchString == null || searchString.length() == 0 || self.length() < searchString.length())
+ return false;
+
+ String s = take(self.toString(), searchString.length()).toString();
+
+ return s.equalsIgnoreCase(searchString.toString());
+ }
+
+ /**
+ * Checks whether this CharSequence ends with the {@code searchString} ignoring the case considerations
+ *
+ * @param self the original CharSequence
+ * @param searchString CharSequence bring checked against this
+ * @return {@code true} if the character sequence represented by the argument is a suffix of this CharSequence
+ * ignoring the case considerations. {@code false} otherwise. Returns false if the argument is null
+ * @since 3.0.0
+ */
+ public static boolean endsWithIgnoreCase(CharSequence self, CharSequence searchString) {
+ if (searchString == null || searchString.length() == 0 || self.length() < searchString.length())
+ return false;
+
+ String s = takeRight(self.toString(), searchString.length()).toString();
+
+ return s.equalsIgnoreCase(searchString.toString());
+ }
+
+ /**
+ * Checks whether this CharSequence contains the {@code searchString} ignoring the caseConsiderations
+ *
+ * @param self the original CharSequence
+ * @param searchString CharSequence being checked against this
+ * @return {@code true} if the character sequence represented by the argument exists in this CharSequence
+ * ignoring the case considerations. {@code false} otherwise. Returns false if the argument is null
+ * @since 3.0.0
+ */
+ public static boolean containsIgnoreCase(CharSequence self, CharSequence searchString) {
+ if (searchString == null || searchString.length() == 0 || self.length() < searchString.length())
+ return false;
+
+ return self.toString().toLowerCase().contains(searchString.toString().toLowerCase());
+ }
}
diff --git a/src/test/groovy/GroovyMethodsTest.groovy b/src/test/groovy/GroovyMethodsTest.groovy
index b773890..b23fd27 100644
--- a/src/test/groovy/GroovyMethodsTest.groovy
+++ b/src/test/groovy/GroovyMethodsTest.groovy
@@ -19,6 +19,7 @@
package groovy
import java.awt.Dimension
+import java.nio.CharBuffer
import java.util.concurrent.LinkedBlockingQueue
import org.codehaus.groovy.util.StringUtil
@@ -1820,6 +1821,339 @@ class GroovyMethodsTest extends GroovyTestCase {
([] as int[]).swap(1, 2)
}
}
+
+ void testCharSequenceTakeRight() {
+ def data = ['groovy', // String
+ "${'groovy'}", // GString
+ java.nio.CharBuffer.wrap('groovy'),
+ new StringBuffer('groovy'),
+ new StringBuilder('groovy')]
+ data.each {
+ // Need toString() as CharBuffer.subSequence returns a java.nio.StringCharBuffer
+ assert it.takeRight(-1).toString() == ''
+ assert it.takeRight(0).toString() == ''
+ assert it.takeRight(3).toString() == 'ovy'
+ assert it.takeRight(6).toString() == 'groovy'
+ assert it.takeRight(10).toString() == 'groovy'
+ }
+ }
+
+ void testCharSequenceTakeAfter() {
+ def text = 'Groovy development. Groovy team'
+
+ def data = [text, // String
+ "${text}", // GString
+ java.nio.CharBuffer.wrap(text),
+ new StringBuffer(text),
+ new StringBuilder(text)]
+
+ List<List<String>> searchStringsAndResults = [
+
+ ['Groovy', ' development. Groovy team'],
+ ['team', ''],
+ ['Java.', ''],
+ ['Unavailable text', ''],
+ ['Some larger String than self', ''],
+ ['', ''],
+ [null, '']
+ ]
+
+ data.each { s ->
+
+ searchStringsAndResults.each { r ->
+
+ // Need toString() as CharBuffer.subSequence returns a java.nio.StringCharBuffer
+
+ assert s.takeAfter(r[0]).toString() == r[1] //String as searchString
+ assert s.takeAfter("${r[0]}").toString() == r[1] //GString as searchString
+
+ if (r[0]) {
+ assert s.takeAfter(java.nio.CharBuffer.wrap(r[0])).toString() == r[1] //CharBuffer as searchString
+ assert s.takeAfter(new StringBuffer(r[0])).toString() == r[1] //StringBuffer as searchString
+ assert s.takeAfter(new StringBuilder(r[0])).toString() == r[1] //StringBuilder as searchString
+ }
+ }
+ }
+
+ }
+
+ void testCharSequenceTakeBefore() {
+ def text = "Groovy development. Groovy team"
+
+ def data = [text, // String
+ "${text}", // GString
+ java.nio.CharBuffer.wrap(text),
+ new StringBuffer(text),
+ new StringBuilder(text)]
+
+ List<List<String>> searchStringsAndResults = [
+
+ [' Groovy ', 'Groovy development.'],
+ ['Groovy', ''],
+ [' ', 'Groovy'],
+ ['Unavailable text', ''],
+ ['Some larger String than self', ''],
+ ['r', 'G'],
+ ['', ''],
+ [null, '']
+ ]
+
+ data.each { s ->
+
+ searchStringsAndResults.each { r ->
+
+ // Need toString() as CharBuffer.subSequence returns a java.nio.StringCharBuffer
+
+ assert s.takeBefore(r[0]).toString() == r[1] //String as searchString
+ assert s.takeBefore("${r[0]}").toString() == r[1] //GString as searchString
+
+ if (r[0]) {
+ assert s.takeBefore(java.nio.CharBuffer.wrap(r[0])).toString() == r[1] //CharBuffer as searchString
+ assert s.takeBefore(new StringBuffer(r[0])).toString() == r[1] //StringBuffer as searchString
+ assert s.takeBefore(new StringBuilder(r[0])).toString() == r[1] //StringBuilder as searchString
+ }
+ }
+ }
+
+ }
+
+ void testCharSequenceDropRight() {
+ def data = ['groovy', // String
+ "${'groovy'}", // GString
+ java.nio.CharBuffer.wrap('groovy'),
+ new StringBuffer('groovy'),
+ new StringBuilder('groovy')]
+ data.each {
+ // Need toString() as CharBuffer.subSequence returns a java.nio.StringCharBuffer
+ assert it.dropRight(-1).toString() == 'groovy'
+ assert it.dropRight(0).toString() == 'groovy'
+ assert it.dropRight(3).toString() == 'gro'
+ assert it.dropRight(6).toString() == ''
+ assert it.dropRight(10).toString() == ''
+ }
+ }
+
+ void testCharSequenceTakeBetween() {
+
+ def text = 'Time taken for Select Query = 12 ms, Update Query = 15 ms. Result = "One", "Two"'
+
+ def data = [text, // String
+ "${text}", // GString
+ java.nio.CharBuffer.wrap(text),
+ new StringBuffer(text),
+ new StringBuilder(text)]
+
+ data.each { s ->
+
+ List<List<String>> fromToCasesWithoutNum = [
+
+ ['Query = ', ' ms', '12'], //positive case
+ ['Query = ', ' MS', ''], //negative case with invalid 'to'
+ ['Query123 = ', ' ms', ''] //negative case with invalid 'from'
+ ]
+
+ fromToCasesWithoutNum.each { r ->
+
+ assert s.takeBetween(r[0], r[1]).toString() == r[2]
+ assert s.takeBetween("${r[0]}", "${r[1]}").toString() == r[2]
+
+ if (r[0] && r[1]) {
+ assert s.takeBetween(CharBuffer.wrap(r[0]), CharBuffer.wrap(r[1])).toString() == r[2]
+ assert s.takeBetween(new StringBuffer(r[0]), CharBuffer.wrap(r[1])).toString() == r[2]
+ assert s.takeBetween(CharBuffer.wrap(r[0]), new StringBuilder(r[1])).toString() == r[2]
+ }
+ }
+ }
+
+ data.each { s ->
+
+ List<List<String>> enclosureWithoutNum = [
+
+ ['"', 'One'], //positive case
+ ['Query', ' = 12 ms, Update '], //negative case with invalid enclosure
+ ['Query123', ''] //negative case with invalid enclosure
+ ]
+
+ enclosureWithoutNum.each { r ->
+
+ assert s.takeBetween(r[0]).toString() == r[1]
+ assert s.takeBetween("${r[0]}").toString() == r[1]
+
+ if (r[0] && r[1]) {
+ assert s.takeBetween(CharBuffer.wrap(r[0])).toString() == r[1]
+ assert s.takeBetween(new StringBuffer(r[0])).toString() == r[1]
+ assert s.takeBetween(new StringBuilder(r[0])).toString() == r[1]
+ }
+ }
+ }
+
+ data.each { s ->
+
+ List<List<Object>> fromToCasesWithNum = [
+
+ ['Query = ', ' ms', 1, '15'],
+ ['Query = ', ' ms', 2, '']
+ ]
+
+ fromToCasesWithNum.each { r ->
+
+ assert s.takeBetween(r[0], r[1], r[2]).toString() == r[3]
+ assert s.takeBetween("${r[0]}", "${r[1]}", r[2]).toString() == r[3]
+
+ if (r[0] && r[1]) {
+ assert s.takeBetween(CharBuffer.wrap(r[0]), CharBuffer.wrap(r[1]), r[2]).toString() == r[3]
+ assert s.takeBetween(new StringBuffer(r[0]), new StringBuffer(r[1]), r[2]).toString() == r[3]
+ assert s.takeBetween(new StringBuilder(r[0]), new StringBuilder(r[1]), r[2]).toString() == r[3]
+ }
+ }
+ }
+
+ data.each { s ->
+
+ List<List<Object>> enclosureWithNum = [
+
+ ['"', 1, 'Two'],
+ ['"', 2, ''],
+ ['"', -1, '']
+ ]
+
+ enclosureWithNum.each { r ->
+
+ assert s.takeBetween(r[0], r[1]).toString() == r[2]
+ assert s.takeBetween("${r[0]}", r[1]).toString() == r[2]
+
+ if (r[0] && r[1]) {
+ assert s.takeBetween(CharBuffer.wrap(r[0]), r[1]).toString() == r[2]
+ assert s.takeBetween(new StringBuffer(r[0]), r[1]).toString() == r[2]
+ assert s.takeBetween(new StringBuilder(r[0]), r[1]).toString() == r[2]
+ }
+ }
+ }
+
+ assert 'smalltext'.takeBetween('somelargertextfrom', 'somelargertextto') == ''
+ assert 'smalltext'.takeBetween('somelargertextfrom', 'somelargertextto', 0) == ''
+
+ def text2 = "name = 'some name'"
+
+ assert text2.takeBetween("'") == 'some name'
+ assert text2.takeBetween('z') == ''
+
+ def text3 = "t1=10 ms, t2=100 ms"
+
+ assert text3.takeBetween('=', ' ', 0) == '10'
+ assert text3.takeBetween('=', ' ', 1) == '100'
+ assert text3.takeBetween('t1', 'z') == ''
+
+ assert 'one\ntwo\nthree'.takeBetween('\n') == 'two'
+ }
+
+ void testCharSequenceStartsWithIgnoreCase() {
+ def text = 'Some Text'
+
+ def data = [text, // String
+ "${text}", // GString
+ java.nio.CharBuffer.wrap(text),
+ new StringBuffer(text),
+ new StringBuilder(text)]
+
+ List<List<Object>> searchStringsAndResults = [
+
+ ['SOME', true],
+ ['some', true],
+ ['Some', true],
+ ['Wrong', false],
+ ['Some larger String than self', false],
+ ['', false],
+ [null, false]
+ ]
+
+ data.each { s ->
+
+ searchStringsAndResults.each { r ->
+
+ assert s.startsWithIgnoreCase(r[0]) == r[1]
+ assert s.startsWithIgnoreCase("${r[0]}") == r[1]
+
+ if (r[0]) {
+ assert s.startsWithIgnoreCase(CharBuffer.wrap(r[0])) == r[1]
+ assert s.startsWithIgnoreCase(new StringBuffer(r[0])) == r[1]
+ assert s.startsWithIgnoreCase(new StringBuilder(r[0])) == r[1]
+ }
+ }
+ }
+ }
+
+ void testCharSequenceEndsWithIgnoreCase() {
+ def text = 'Some Text'
+
+ def data = [text, // String
+ "${text}", // GString
+ java.nio.CharBuffer.wrap(text),
+ new StringBuffer(text),
+ new StringBuilder(text)]
+
+ List<List<Object>> searchStringsAndResults = [
+
+ ['TEXT', true],
+ ['text', true],
+ ['Text', true],
+ ['Wrong', false],
+ ['Some larger String than self', false],
+ ['', false],
+ [null, false]
+ ]
+
+ data.each { s ->
+
+ searchStringsAndResults.each { r ->
+
+ assert s.endsWithIgnoreCase(r[0]) == r[1]
+ assert s.endsWithIgnoreCase("${r[0]}") == r[1]
+
+ if (r[0]) {
+ assert s.endsWithIgnoreCase(CharBuffer.wrap(r[0])) == r[1]
+ assert s.endsWithIgnoreCase(new StringBuffer(r[0])) == r[1]
+ assert s.endsWithIgnoreCase(new StringBuilder(r[0])) == r[1]
+ }
+ }
+ }
+ }
+
+ void testCharSequenceContainsIgnoreCase() {
+ def text = 'Some Text'
+
+ def data = [text, // String
+ "${text}", // GString
+ java.nio.CharBuffer.wrap(text),
+ new StringBuffer(text),
+ new StringBuilder(text)]
+
+ List<List<Object>> searchStringsAndResults = [
+
+ ['E TEX', true],
+ ['Me t', true],
+ ['me T', true],
+ ['Wrong', false],
+ ['Some larger String than self', false],
+ ['', false],
+ [null, false]
+ ]
+
+ data.each { s ->
+
+ searchStringsAndResults.each { r ->
+
+ assert s.containsIgnoreCase(r[0]) == r[1]
+ assert s.containsIgnoreCase("${r[0]}") == r[1]
+
+ if (r[0]) {
+ assert s.containsIgnoreCase(CharBuffer.wrap(r[0])) == r[1]
+ assert s.containsIgnoreCase(new StringBuffer(r[0])) == r[1]
+ assert s.containsIgnoreCase(new StringBuilder(r[0])) == r[1]
+ }
+ }
+ }
+ }
}
class WackyList extends LinkedList {