diff --git a/.gitignore b/.gitignore
index 48267e9..6c9b373 100644
--- a/.gitignore
+++ b/.gitignore
@@ -71,3 +71,8 @@ hs_err_pid*
!gradle/wrapper/gradle-wrapper.jar
+/bin/
+
+.classpath
+.project
+.settings
diff --git a/README.md b/README.md
index 028ec4d..bd9ffd6 100644
--- a/README.md
+++ b/README.md
@@ -1,566 +1,40 @@
strman-java [](https://travis-ci.org/shekhargulati/strman-java) [](https://codecov.io/github/shekhargulati/strman-java?branch=master) [](./LICENSE.txt)
------
-A Java 8 library for working with String. It is inspired by [dleitee/strman](https://github.com/dleitee/strman).
+A Java 8 library for working with Strings.
+You can learn about all the String utility functions implemented in `strman` library by reading the [documentation](https://github.com/shekhargulati/strman-java/wiki).
Getting Started
--------
-To use strman in your application, you have to add `strman` in your classpath. strman is available on [Maven Central](http://search.maven.org/) so you just need to add dependency to your favorite build tool as show below.
+To use strman in your application, you have to add `strman` to your classpath.
+strman is available on [Maven Central](http://search.maven.org/) so you just need to add dependency in your favorite build tool as shown below.
-For Apache Maven users, please add following to your pom.xml.
+For Apache Maven users, please add following to your `pom.xml`.
```xml
com.shekhargulati
strman
- 0.2.0
- jar
+ 0.4.0
```
-Gradle users can add following to their build.gradle file.
+Gradle users can add following to their `build.gradle` file.
```
-compile(group: 'com.shekhargulati', name: 'strman', version: '0.2.0', ext: 'jar'){
- transitive=true
-}
+compile(group: 'com.shekhargulati', name: 'strman', version: '0.4.0')
```
-## Available Functions
+To learn what we added in the latest version please refer to `./changelog.md`.
-These are the available functions in current version of library:
+You can refer to Javadocs online [http://shekhargulati.github.io/strman-java/](http://shekhargulati.github.io/strman-java/).
-## append
+## Inspiration
-Appends Strings to value
-
-```java
-import static strman.Strman.append
-append("f", "o", "o", "b", "a", "r")
-// result => "foobar"
-```
-
-## appendArray
-
-Append an array of String to value
-
-```java
-import static strman.Strman.appendArray
-appendArray("f", new String[]{"o", "o", "b", "a", "r"}
-// result => "foobar"
-```
-
-## at
-
-Get the character at index. This method will take care of negative indexes.
-
-```java
-import static strman.Strman.at
-at("foobar", 0)
-// result => Optional("f")
-```
-
-## between
-
-Returns an array with strings between start and end.
-
-```java
-import static strman.Strman.between
-between("[abc][def]", "[", "]")
-// result => ["abc","def"]
-```
-
-## chars
-
-Returns a String array consisting of the characters in the String.
-
-```java
-import static strman.Strman.chars
-chars("title")
-// result => ["t", "i", "t", "l", "e"]
-```
-
-## collapseWhitespace
-
-Replace consecutive whitespace characters with a single space.
-
-```java
-import static strman.Strman.collapseWhitespace
-collapseWhitespace("foo bar")
-// result => "foo bar"
-```
-
-## contains
-
-Verifies that the needle is contained in the value.
-
-```java
-import static strman.Strman.contains
-contains("foo bar","foo")
-// result => true
-
-contains("foo bar","FOO", false) // turning off case sensitivity
-// result => true
-```
-
-## containsAll
-
-Verifies that all needles are contained in value
-
-```java
-import static strman.Strman.containsAll
-containsAll("foo bar", new String[]{"foo", "bar"})
-// result => true
-
-containsAll("foo bar", new String[]{"FOO", "bar"},false)
-// result => true
-```
-
-## containsAny
-
-Verifies that one or more of needles are contained in value.
-
-```java
-import static strman.Strman.containsAny
-containsAny("bar foo", new String[]{"FOO", "BAR", "Test"}, true)
-// result => true
-```
-
-## countSubstr
-
-Count the number of times substr appears in value
-
-```java
-import static strman.Strman.countSubstr
-countSubstr("aaaAAAaaa", "aaa")
-// result => 2
-countSubstr("aaaAAAaaa", "aaa", false, false)
-// result => 3
-```
-
-## endsWith
-
-Test if value ends with search.
-
-```java
-import static strman.Strman.endsWith
-endsWith("foo bar", "bar")
-// result => true
-endsWith("foo Bar", "BAR", false)
-// result => true
-```
-
-## ensureLeft
-
-Ensures that the value begins with prefix. If it doesn't exist, it's prepended.
-
-```java
-import static strman.Strman.ensureLeft
-ensureLeft("foobar", "foo")
-// result => "foobar"
-ensureLeft("bar", "foo")
-// result => "foobar"
-ensureLeft("foobar", "FOO", false)
-// result => "foobar"
-```
-
-## base64Decode
-
-Decodes data encoded with MIME base64
-
-```java
-import static strman.Strman.base64Decode
-base64Decode("c3RybWFu")
-// result => "strman"
-```
-
-## base64Encode
-
-Encodes data with MIME base64.
-
-```java
-import static strman.Strman.base64Encode
-base64Encode("strman")
-// result => "c3RybWFu"
-```
-
-## binDecode
-
-Convert binary unicode (16 digits) string to string chars
-
-```java
-import static strman.Strman.binDecode
-binDecode("0000000001000001")
-// result => "A"
-```
-
-## binEncode
-
-Convert string chars to binary unicode (16 digits)
-
-```java
-import static strman.Strman.binEncode
-binEncode("A")
-// result => "0000000001000001"
-```
-
-## decDecode
-
-Convert decimal unicode (5 digits) string to string chars
-
-```java
-import static strman.Strman.decDecode
-decDecode("00065")
-// result => "A"
-```
-
-## decEncode
-
-Convert string chars to decimal unicode (5 digits)
-
-```java
-import static strman.Strman.decEncode
-decEncode("A")
-// result => "00065"
-```
-
-## ensureRight
-
-Ensures that the value ends with suffix. If it doesn't, it's appended.
-
-```java
-import static strman.Strman.ensureRight
-ensureRight("foo", "bar")
-// result => "foobar"
-
-ensureRight("foobar", "bar")
-// result => "foobar"
-
-ensureRight("fooBAR", "bar", false)
-// result => "foobar"
-```
-
-## first
-
-Returns the first n chars of String
-
-```java
-import static strman.Strman.first
-first("foobar", 3)
-// result => "foo"
-```
-
-## head
-
-Return the first char of String
-
-```java
-import static strman.Strman.head
-head("foobar")
-// result => "f"
-```
-
-## hexDecode
-
-Convert hexadecimal unicode (4 digits) string to string chars
-
-```java
-import static strman.Strman.hexDecode
-hexDecode("0041")
-// result => "A"
-```
-
-## hexEncode
-
-Convert string chars to hexadecimal unicode (4 digits)
-
-```java
-import static strman.Strman.hexEncode
-hexEncode("A")
-// result => "0041"
-```
-
-## inequal
-
-Tests if two Strings are inequal
-
-```java
-import static strman.Strman.inequal
-inequal("a", "b")
-// result => true
-```
-
-## insert
-
-Inserts 'substr' into the 'value' at the 'index' provided.
-
-```java
-import static strman.Strman.insert
-insert("fbar", "oo", 1)
-// result => "foobar"
-```
-
-## last
-
-Return the last n chars of String
-
-```java
-import static strman.Strman.last
-last("foobarfoo", 3)
-// result => "foo"
-```
-
-## leftPad
-
-Returns a new string of a given length such that the beginning of the string is padded.
-
-```java
-import static strman.Strman.leftPad
-leftPad("1", "0", 5)
-// result => "00001"
-```
-
-## lastIndexOf
-
-This method returns the index within the calling String object of the last occurrence of the specified value, searching backwards from the offset.
-
-```java
-import static strman.Strman.lastIndexOf
-lastIndexOf("foobarfoobar", "F", false)
-// result => 6
-```
-
-## leftTrim
-
-Removes all spaces on left
-
-```java
-import static strman.Strman.leftTrim
-leftTrim(" strman")
-// result => "strman"
-```
-
-## prepend
-
-Return a new String starting with prepends
-
-```java
-prepend("r", "f", "o", "o", "b", "a")
-// "foobar"
-```
-
-## removeEmptyStrings
-
-Remove empty Strings from string array
-
-```java
-removeEmptyStrings(new String[]{"aa", "", " ", "bb", "cc", null})
-// result => ["aa", "bb", "cc"]
-```
-
-## removeLeft
-
-Returns a new String with the prefix removed, if present.
-
-```java
-removeLeft("foofoo", "foo")
-// "foo"
-```
-
-## removeNonWords
-
-Remove all non word characters.
-
-```java
-removeNonWords("foo&bar-")
-// result => "foobar"
-```
-
-## removeRight
-
-Returns a new string with the 'suffix' removed, if present.
-
-```java
-removeRight("foobar", "bar")
-// result => "foo"
-removeRight("foobar", "BAR",false)
-// result => "foo"
-```
-
-## removeSpaces
-
-Remove all spaces and replace for value.
-
-```java
-removeSpaces("foo bar")
-// result => "foobar"
-```
-
-## repeat
-
-Returns a repeated string given a multiplier.
-
-```
-repeat("1", 3)
-// result => "111"
-```
-
-## reverse
-
-Reverse the input String
-
-```java
-reverse("foo")
-// result => "oof"
-```
-
-## rightPad
-
-Returns a new string of a given length such that the ending of the string is padded.
-
-```java
-rightPad("1", "0", 5)
-// result => "10000"
-```
-
-## rightTrim
-
-Remove all spaces on right.
-
-```java
-rightTrim("strman ")
-// result => "strman"
-```
-
-## safeTruncate
-
-Truncate the string securely, not cutting a word in half. It always returns the last full word.
-
-```java
-safeTruncate("foo bar", 4, ".")
-// result => "foo."
-safeTruncate("A Javascript string manipulation library.", 16, "...")
-// result => "A Javascript..."
-```
-
-## truncate
-
-Truncate the unsecured form string, cutting the independent string of required position.
-
-```java
-truncate("A Javascript string manipulation library.", 14, "...")
-// result => "A Javascrip..."
-```
-
-## htmlDecode
-
-Converts all HTML entities to applicable characters.
-
-```java
-htmlDecode("Ш")
-// result => Ш
-```
-
-## htmlEncode
-
-Convert all applicable characters to HTML entities.
-
-```java
-htmlEncode("Ш")
-// result => "Ш"
-```
-
-## shuffle
-
-It returns a string with its characters in random order.
-
-```java
-shuffle("shekhar")
-```
-
-## slugify
-
-Convert a String to a slug
-
-```java
-slugify("foo bar")
-// result => "foo-bar"
-```
-
-## transliterate
-
-Remove all non valid characters. Example: change á => a or ẽ => e.
-
-```java
-transliterate("fóõ bár")
-// result => "foo bar"
-```
-
-## surround
-
-Surrounds a 'value' with the given 'prefix' and 'suffix'.
-
-```java
-surround("div", "<", ">"
-// result => "
s"
-```
-
-## tail
-
-```java
-tail("foobar")
-// result => "oobar"
-```
-
-## toCamelCase
-
-Transform to camelCase
-
-```java
-toCamelCase("CamelCase")
-// result => "camelCase"
-toCamelCase("camel-case")
-// result => "camelCase"
-```
-
-## toStudlyCase
-
-Transform to StudlyCaps.
-
-```java
-toStudlyCase("hello world")
-// result => "HelloWorld"
-```
-
-## toDecamelize
-
-Decamelize String
-
-```java
-toDecamelize("helloWorld",null)
-// result => "hello world"
-```
-
-## toKebabCase
-
-Transform to kebab-case.
-
-```java
-toKebabCase("hello World")
-// result => "hello-world"
-```
-
-## toSnakeCase
-
-Transform to snake_case.
-
-```java
-toSnakeCase("hello world")
-// result => "hello_world"
-```
+This library is inspired by [dleitee/strman](https://github.com/dleitee/strman).
License
-------
diff --git a/build.gradle b/build.gradle
index 5baa1f1..7fba771 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,6 @@
plugins {
id 'net.researchgate.release' version '2.3.3'
+ id "net.ltgt.errorprone" version "0.0.10"
}
group 'com.shekhargulati'
@@ -9,6 +10,8 @@ apply plugin: 'maven'
apply plugin: 'maven-publish'
apply plugin: 'signing'
apply plugin: "jacoco"
+apply from: rootProject.file('gradle/checkstyle.gradle')
+apply plugin: "net.ltgt.errorprone"
sourceCompatibility = 1.8
@@ -92,4 +95,4 @@ jacocoTestReport {
}
}
-check.dependsOn jacocoTestReport
\ No newline at end of file
+check.dependsOn jacocoTestReport
diff --git a/changelog.md b/changelog.md
new file mode 100644
index 0000000..03f1e28
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,63 @@
+# Version 0.3.0
+
+
+* __Feature required in #73 (#77)__: Added `charsCount` function
+
+ [César Aguilera](mailto:cesar.aguilera.p@gmail.com) - Tue, 9 May 2017 18:16:11 +0530
+
+
+
+* __fixed bug in containsAll (#76)__
+
+ [wli75](mailto:wli75@illinois.edu) - Tue, 7 Mar 2017 20:09:18 +0530
+
+
+
+* __Resolved #66__: Added `trimEnd` function
+
+ [Shekhar Gulati](mailto:shekhargulati84@gmail.com) - Wed, 24 Aug 2016 15:32:45 +0530
+
+
+
+* __Resolved #65__: Added `trimStart`function
+
+ [Shekhar Gulati](mailto:shekhargulati84@gmail.com) - Wed, 24 Aug 2016 15:02:00 +0530
+
+
+
+* __Resolved #68__: Added `upperFirst` function
+
+ [Shekhar Gulati](mailto:shekhargulati84@gmail.com) - Wed, 24 Aug 2016 14:26:16 +0530
+
+
+
+* __Resolved #69__: Added `words` function
+
+ [Shekhar Gulati](mailto:shekhargulati84@gmail.com) - Wed, 24 Aug 2016 12:56:18 +0530
+
+
+
+* __Resolved#71__: Added `isEnclosedBetween` function
+
+ [Shekhar Gulati](mailto:shekhargulati84@gmail.com) - Wed, 24 Aug 2016 12:11:04 +0530
+
+
+
+* __Resolved #54 and Resolved #59__: Added `capitalize` and `lowerFirst` functions
+
+ [Shekhar Gulati](mailto:shekhargulati84@gmail.com) - Wed, 27 Jul 2016 23:19:41 +0530
+
+
+
+* __Resolved #53__: Added `join` function
+
+ [Shekhar Gulati](mailto:shekhargulati84@gmail.com) - Mon, 25 Jul 2016 15:29:43 +0530
+
+
+
+* __Simplify Maven and Gradle configuration (#70)__
+
+ [Marcin Zajączkowski](mailto:mszpak@wp.pl) - Tue, 19 Jul 2016 20:58:57 +0530
+
+
+
diff --git a/etc/checkstyle-exclude.xml b/etc/checkstyle-exclude.xml
new file mode 100644
index 0000000..533e04f
--- /dev/null
+++ b/etc/checkstyle-exclude.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
diff --git a/etc/checkstyle.xml b/etc/checkstyle.xml
new file mode 100644
index 0000000..d93ff58
--- /dev/null
+++ b/etc/checkstyle.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gradle.properties b/gradle.properties
index 401ddf4..7890fd8 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1 +1 @@
-version=0.3.0-SNAPSHOT
\ No newline at end of file
+version= 0.5.0-SNAPSHOT
\ No newline at end of file
diff --git a/gradle/checkstyle.gradle b/gradle/checkstyle.gradle
new file mode 100644
index 0000000..19768d2
--- /dev/null
+++ b/gradle/checkstyle.gradle
@@ -0,0 +1,10 @@
+apply plugin: 'checkstyle'
+
+checkstyle {
+ configFile rootProject.file('etc/checkstyle.xml')
+ showViolations true
+}
+
+dependencies {
+ checkstyle 'com.puppycrawl.tools:checkstyle:7.7'
+}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 4e58c1b..1e1ca40 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip
diff --git a/src/main/java/strman/Strman.java b/src/main/java/strman/Strman.java
index fe5fad5..9b1e3c2 100644
--- a/src/main/java/strman/Strman.java
+++ b/src/main/java/strman/Strman.java
@@ -1,4 +1,3 @@
-
/*
*
* * The MIT License
@@ -27,22 +26,26 @@
package strman;
+import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.IntStream;
import java.util.stream.Stream;
-import static java.util.stream.Collectors.joining;
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.*;
/**
* A String manipulation library without any dependencies
*/
public abstract class Strman {
- private static final Predicate
NULL_STRING_PREDICATE = str -> str == null;
+ private static final Predicate NULL_STRING_PREDICATE = Objects::isNull;
private static final Supplier NULL_STRING_MSG_SUPPLIER = () -> "'value' should be not null.";
+ private static final String[] EMPTY_ARRAY = new String[0];
private Strman() {
}
@@ -87,7 +90,7 @@ public static String appendArray(final String value, final String[] appends) {
* @return an Optional String if found else empty
*/
public static Optional at(final String value, int index) {
- if (value == null || value.isEmpty()) {
+ if (isNullOrEmpty(value)) {
return Optional.empty();
}
int length = value.length();
@@ -112,7 +115,10 @@ public static String[] between(final String value, final String start, final Str
validate(end, NULL_STRING_PREDICATE, () -> "'end' should be not null.");
String[] parts = value.split(end);
- return Arrays.stream(parts).map(subPart -> subPart.substring(subPart.indexOf(start) + start.length())).toArray(String[]::new);
+ return Arrays.stream(parts)
+ .filter(subPart -> subPart.contains(start))
+ .map(subPart -> subPart.substring(subPart.indexOf(start) + start.length()))
+ .toArray(String[]::new);
}
/**
@@ -126,7 +132,6 @@ public static String[] chars(final String value) {
return value.split("");
}
-
/**
* Replace consecutive whitespace characters with a single space.
*
@@ -138,7 +143,6 @@ public static String collapseWhitespace(final String value) {
return value.trim().replaceAll("\\s\\s+", " ");
}
-
/**
* Verifies that the needle is contained in the value. The search is case insensitive
*
@@ -175,7 +179,7 @@ public static boolean contains(final String value, final String needle, final bo
*/
public static boolean containsAll(final String value, final String[] needles) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
- return Arrays.stream(needles).allMatch(needle -> contains(value, needle, true));
+ return Arrays.stream(needles).allMatch(needle -> contains(value, needle, false));
}
/**
@@ -235,9 +239,11 @@ public static long countSubstr(final String value, final String subStr) {
* @param allowOverlapping boolean to take into account overlapping
* @return count of times substring exists
*/
- public static long countSubstr(final String value, final String subStr, final boolean caseSensitive, boolean allowOverlapping) {
+ public static long countSubstr(final String value, final String subStr, final boolean caseSensitive,
+ boolean allowOverlapping) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
- return countSubstr(caseSensitive ? value : value.toLowerCase(), caseSensitive ? subStr : subStr.toLowerCase(), allowOverlapping, 0L);
+ return countSubstr(caseSensitive ? value : value.toLowerCase(), caseSensitive ? subStr : subStr.toLowerCase(),
+ allowOverlapping, 0L);
}
/**
@@ -274,7 +280,8 @@ public static boolean endsWith(final String value, final String search, final bo
* @param caseSensitive true or false
* @return true or false
*/
- public static boolean endsWith(final String value, final String search, final int position, final boolean caseSensitive) {
+ public static boolean endsWith(final String value, final String search, final int position,
+ final boolean caseSensitive) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
int remainingLength = position - search.length();
if (caseSensitive) {
@@ -320,7 +327,7 @@ public static String ensureLeft(final String value, final String prefix, final b
*/
public static String base64Decode(final String value) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
- return new String(Base64.getDecoder().decode(value));
+ return new String(Base64.getDecoder().decode(value), StandardCharsets.UTF_8);
}
/**
@@ -331,7 +338,7 @@ public static String base64Decode(final String value) {
*/
public static String base64Encode(final String value) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
- return Base64.getEncoder().encodeToString(value.getBytes());
+ return Base64.getEncoder().encodeToString(value.getBytes(StandardCharsets.UTF_8));
}
/**
@@ -405,9 +412,8 @@ public static String ensureRight(final String value, final String suffix, boolea
* @param n Number of chars to return
* @return The first n chars
*/
- public static String first(final String value, final int n) {
- validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
- return value.substring(0, n);
+ public static Optional first(final String value, final int n) {
+ return Optional.ofNullable(value).filter(v -> !v.isEmpty()).map(v -> v.substring(0, n));
}
/**
@@ -416,7 +422,7 @@ public static String first(final String value, final int n) {
* @param value The input String
* @return The first char
*/
- public static String head(final String value) {
+ public static Optional head(final String value) {
return first(value, 1);
}
@@ -429,7 +435,7 @@ public static String head(final String value) {
*/
public static String format(final String value, String... params) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
- Pattern p = Pattern.compile("\\{(\\w+)\\}");
+ Pattern p = Pattern.compile("\\{(\\w+)}");
Matcher m = p.matcher(value);
String result = value;
while (m.find()) {
@@ -634,7 +640,8 @@ public static int lastIndexOf(final String value, final String needle, boolean c
* @param caseSensitive whether search should be case sensitive
* @return Return position of the last occurrence of 'needle'.
*/
- public static int lastIndexOf(final String value, final String needle, final int offset, final boolean caseSensitive) {
+ public static int lastIndexOf(final String value, final String needle, final int offset,
+ final boolean caseSensitive) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
validate(needle, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
if (caseSensitive) {
@@ -769,7 +776,8 @@ public static String removeRight(final String value, final String suffix) {
public static String removeRight(final String value, final String suffix, final boolean caseSensitive) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
validate(suffix, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
- return endsWith(value, suffix, caseSensitive) ? value.substring(0, value.toLowerCase().lastIndexOf(suffix.toLowerCase())) : value;
+ return endsWith(value, suffix, caseSensitive) ? value
+ .substring(0, value.toLowerCase().lastIndexOf(suffix.toLowerCase())) : value;
}
/**
@@ -804,13 +812,15 @@ public static String repeat(final String value, final int multiplier) {
* @param caseSensitive whether search should be case sensitive or not
* @return String replaced with 'newvalue'.
*/
- public static String replace(final String value, final String search, final String newValue, final boolean caseSensitive) {
+ public static String replace(final String value, final String search, final String newValue,
+ final boolean caseSensitive) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
validate(search, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
if (caseSensitive) {
return value.replace(search, newValue);
}
- return Pattern.compile(search, Pattern.CASE_INSENSITIVE).matcher(value).replaceAll(Matcher.quoteReplacement(newValue));
+ return Pattern.compile(search, Pattern.CASE_INSENSITIVE).matcher(value)
+ .replaceAll(Matcher.quoteReplacement(newValue));
}
/**
@@ -901,10 +911,22 @@ public static String[] split(final String value, final String regex) {
* @return Words Array
*/
public static String[] words(final String value) {
+ return words(value, "\\s+");
+ }
+
+ /**
+ * Splits a String to words by delimiter, \s+ by default
+ *
+ * @param value The input String
+ * @param delimiter delimiter for splitting input String
+ * @return words array
+ */
+ public static String[] words(final String value, final String delimiter) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
- return value.split("\\W+");
+ return value.split(delimiter);
}
+
/**
* Truncate the unsecured form string, cutting the independent string of required position.
*
@@ -944,7 +966,8 @@ public static String htmlDecode(final String encodedHtml) {
*/
public static String htmlEncode(final String html) {
validate(html, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
- return html.chars().mapToObj(c -> "\\u" + String.format("%04x", c).toUpperCase()).map(e -> HtmlEntities.encodedEntities.get(e)).collect(joining());
+ return html.chars().mapToObj(c -> "\\u" + String.format("%04x", c).toUpperCase())
+ .map(HtmlEntities.encodedEntities::get).collect(joining());
}
/**
@@ -988,7 +1011,7 @@ public static String slice(final String value, int begin, int end) {
public static String slugify(final String value) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
String transliterated = transliterate(collapseWhitespace(value.trim().toLowerCase()));
- return Arrays.stream(words(transliterated.replace("&", "-and-"))).collect(joining("-"));
+ return Arrays.stream(words(transliterated.replace("&", "-and-"), "\\W+")).collect(joining("-"));
}
/**
@@ -1009,7 +1032,6 @@ public static String transliterate(final String value) {
return result;
}
-
/**
* Surrounds a 'value' with the given 'prefix' and 'suffix'.
*
@@ -1031,7 +1053,9 @@ public static String surround(final String value, final String prefix, final Str
* @return String in camelCase.
*/
public static String toCamelCase(final String value) {
- validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
+ if (value == null || value.length() == 0) {
+ return "";
+ }
String str = toStudlyCase(value);
return str.substring(0, 1).toLowerCase() + str.substring(1);
}
@@ -1045,7 +1069,7 @@ public static String toCamelCase(final String value) {
public static String toStudlyCase(final String value) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
String[] words = collapseWhitespace(value.trim()).split("\\s*(_|-|\\s)\\s*");
- return Arrays.stream(words).filter(w -> !w.trim().isEmpty()).map(w -> head(w).toUpperCase() + tail(w)).collect(joining());
+ return Arrays.stream(words).filter(w -> !w.trim().isEmpty()).map(Strman::upperFirst).collect(joining());
}
/**
@@ -1054,9 +1078,8 @@ public static String toStudlyCase(final String value) {
* @param value The input String
* @return String tail
*/
- public static String tail(final String value) {
- validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
- return last(value, value.length() - 1);
+ public static Optional tail(final String value) {
+ return Optional.ofNullable(value).filter(v -> !v.isEmpty()).map(v -> last(v, v.length() - 1));
}
/**
@@ -1094,8 +1117,7 @@ public static String toSnakeCase(final String value) {
public static String decode(final String value, final int digits, final int radix) {
validate(value, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
- return Arrays
- .stream(value.split("(?<=\\G.{" + digits + "})"))
+ return Arrays.stream(value.split("(?<=\\G.{" + digits + "})"))
.map(data -> String.valueOf(Character.toChars(Integer.parseInt(data, radix))))
.collect(joining());
}
@@ -1105,6 +1127,328 @@ public static String encode(final String value, final int digits, final int radi
return value.chars().mapToObj(ch -> leftPad(Integer.toString(ch, radix), "0", digits)).collect(joining());
}
+ /**
+ * Join concatenates all the elements of the strings array into a single String. The separator string is placed between elements in the resulting string.
+ *
+ * @param strings The input array to concatenate
+ * @param separator The separator to use
+ * @return Concatenated String
+ */
+ public static String join(final String[] strings, final String separator) throws IllegalArgumentException {
+ if (strings == null) {
+ throw new IllegalArgumentException("Input array 'strings' can't be null");
+ }
+ if (separator == null) {
+ throw new IllegalArgumentException("separator can't be null");
+ }
+ StringJoiner joiner = new StringJoiner(separator);
+ for (String el : strings) {
+ joiner.add(el);
+ }
+ return joiner.toString();
+ }
+
+ /**
+ * Converts the first character of string to upper case and the remaining to lower case.
+ *
+ * @param input The string to capitalize
+ * @return The capitalized string
+ */
+ public static String capitalize(final String input) throws IllegalArgumentException {
+ if (input == null) {
+ throw new IllegalArgumentException("input can't be null");
+ }
+ if (input.length() == 0) {
+ return "";
+ }
+ return head(input).map(String::toUpperCase).map(h -> tail(input).map(t -> h + t.toLowerCase()).orElse(h)).get();
+ }
+
+ /**
+ * Converts the first character of string to lower case.
+ *
+ * @param input The string to convert
+ * @return The converted string
+ */
+ public static String lowerFirst(final String input) throws IllegalArgumentException {
+ if (input == null) {
+ throw new IllegalArgumentException("input can't be null");
+ }
+ if (input.length() == 0) {
+ return "";
+ }
+
+ return head(input).map(String::toLowerCase).map(h -> tail(input).map(t -> h + t).orElse(h)).get();
+ }
+
+ /**
+ * Verifies whether String is enclosed by encloser
+ *
+ * @param input The input String
+ * @param encloser String which encloses input String
+ * @return true if enclosed false otherwise
+ */
+ public static boolean isEnclosedBetween(final String input, final String encloser) {
+ return isEnclosedBetween(input, encloser, encloser);
+ }
+
+ /**
+ * Verifies whether String is enclosed by encloser
+ *
+ * @param input The input String
+ * @param leftEncloser String which encloses input String at left start
+ * @param rightEncloser String which encloses input String at the right end
+ * @return true if enclosed false otherwise
+ */
+ public static boolean isEnclosedBetween(final String input, final String leftEncloser, String rightEncloser) {
+ if (input == null) {
+ throw new IllegalArgumentException("input can't be null");
+ }
+ if (leftEncloser == null) {
+ throw new IllegalArgumentException("leftEncloser can't be null");
+ }
+ if (rightEncloser == null) {
+ throw new IllegalArgumentException("rightEncloser can't be null");
+ }
+ return input.startsWith(leftEncloser) && input.endsWith(rightEncloser);
+ }
+
+ /**
+ * Converts the first character of string to upper case.
+ *
+ * @param input The string to convert.
+ * @return Returns the converted string.
+ */
+ public static String upperFirst(String input) {
+ if (input == null) {
+ throw new IllegalArgumentException("input can't be null");
+ }
+ return head(input).map(String::toUpperCase).map(h -> tail(input).map(t -> h + t).orElse(h)).get();
+ }
+
+ /**
+ * Removes leading whitespace from string.
+ *
+ * @param input The string to trim.
+ * @return Returns the trimmed string.
+ */
+ public static Optional trimStart(final String input) {
+ return Optional.ofNullable(input).filter(v -> !v.isEmpty()).map(Strman::leftTrim);
+ }
+
+ /**
+ * Removes leading characters from string.
+ *
+ * @param input The string to trim.
+ * @param chars The characters to trim.
+ * @return Returns the trimmed string.
+ */
+ public static Optional trimStart(final String input, String... chars) {
+ return Optional.ofNullable(input).filter(v -> !v.isEmpty()).map(v -> {
+ String pattern = String.format("^[%s]+", join(chars, "\\"));
+ return v.replaceAll(pattern, "");
+ });
+ }
+
+ /**
+ * Removes trailing whitespace from string.
+ *
+ * @param input The string to trim.
+ * @return Returns the trimmed string.
+ */
+ public static Optional trimEnd(final String input) {
+ return Optional.ofNullable(input).filter(v -> !v.isEmpty()).map(Strman::rightTrim);
+ }
+
+ /**
+ * Removes trailing characters from string.
+ *
+ * @param input The string to trim.
+ * @param chars The characters to trim.
+ * @return Returns the trimmed string.
+ */
+ public static Optional trimEnd(final String input, String... chars) {
+ return Optional.ofNullable(input).filter(v -> !v.isEmpty()).map(v -> {
+ String pattern = String.format("[%s]+$", join(chars, "\\"));
+ return v.replaceAll(pattern, "");
+ });
+ }
+
+ /**
+ * Counts the number of occurrences of each character in the string
+ *
+ * @param input The input string
+ * @return A map containing the number of occurrences of each character in the string
+ */
+ public static Map charsCount(String input) {
+ if (isNullOrEmpty(input)) {
+ return Collections.emptyMap();
+ }
+
+ return input.chars().mapToObj(c -> (char) c).collect(groupingBy(identity(), counting()));
+ }
+
+ /**
+ * Checks if string is empty. This is a null safe check and will return true when string is null.
+ *
+ * @param input The input string
+ * @return true if input string is null or empty
+ */
+ public static boolean isBlank(String input) {
+ return input == null || input.isEmpty();
+ }
+
+ /**
+ * Changes passed in string to all lower case and adds underscore between words.
+ *
+ * @param input The input string
+ * @return the input string in all lower case with underscores between words
+ */
+ public static String underscored(final String input) {
+ if (input == null || input.length() == 0) {
+ return "";
+ }
+
+ return input.trim().replaceAll("([a-z\\d])([A-Z]+)", "$1_$2").replaceAll("[-\\s]+", "_").toLowerCase();
+ }
+
+ /**
+ * Aggregates the contents of n strings into a single list of tuples.
+ *
+ * @param inputs A list of strings.
+ * @return A list of strings if none of the strings in the input is null or empty.
+ * An empty list otherwise.
+ */
+ public static List zip(String... inputs) {
+ if (inputs.length == 0) {
+ return Collections.emptyList();
+ }
+ OptionalInt min = Arrays.stream(inputs).mapToInt(str -> str == null ? 0 : str.length()).min();
+ if (!min.isPresent()) {
+ return Collections.emptyList();
+ }
+ return IntStream.range(0, min.getAsInt())
+ .mapToObj(elementIndex -> Arrays.stream(inputs)
+ .map(input -> String.valueOf(input.charAt(elementIndex)))
+ .collect(joining()))
+ .collect(toList());
+ }
+
+ /**
+ * Split lines to an array
+ *
+ * @param input The input String
+ * @return lines in an array
+ */
+ public static String[] lines(String input) {
+ if (input == null) {
+ return EMPTY_ARRAY;
+ }
+ return input.split("\r\n?|\n");
+ }
+
+ /**
+ * Converts a underscored or camelized string into an dasherized one.
+ *
+ * @param input The input String
+ * @return dasherized String.
+ */
+ public static String dasherize(String input) {
+ return toKebabCase(input);
+ }
+
+ /**
+ * Converts an underscored, camelized, or dasherized string into a humanized one. Also removes beginning and ending whitespace.
+ *
+ * @param input The input String
+ * @return humanized version of String
+ */
+ public static String humanize(final String input) {
+ if (input == null || input.length() == 0) {
+ return "";
+ }
+ return upperFirst(underscored(input).replaceAll("_", " "));
+ }
+
+ /**
+ * Returns a copy of the string in which all the case-based characters have had their case swapped.
+ *
+ * @param input Input string
+ * @return String with all the case swapped
+ */
+ public static String swapCase(String input) {
+ if (input == null || input.length() == 0) {
+ return "";
+ }
+ StringBuilder resultBuilder = new StringBuilder();
+ for (char ch : input.toCharArray()) {
+ if (Character.isUpperCase(ch)) {
+ resultBuilder.append(Character.toLowerCase(ch));
+ } else {
+ resultBuilder.append(Character.toUpperCase(ch));
+ }
+ }
+ return resultBuilder.toString();
+ }
+
+ /**
+ * Returns a string representation of the number passed in where groups of three digits are delimited by comma
+ *
+ * @param number Input number
+ * @return formatted String
+ */
+ public static String formatNumber(long number) {
+ String stringRepresentation = Long.toString(number);
+ StringBuilder sb = new StringBuilder();
+ int bound = stringRepresentation.length() - 1;
+ String delimiter = ",";
+ int counter = 0;
+ for (int i = bound; i >= 0; i--) {
+ char c = stringRepresentation.charAt(i);
+ if (i != bound && counter % 3 == 0) {
+ sb.append(delimiter);
+ }
+ sb.append(c);
+ counter++;
+ }
+ return sb.reverse().toString();
+ }
+
+ public static String[] chop(String input, int step) {
+ if (input == null || input.length() == 0) {
+ return EMPTY_ARRAY;
+ }
+ if (step == 0) {
+ return new String[]{input};
+ }
+ int strLength = input.length();
+ int iterations = strLength % step == 0 ? strLength / step : strLength / step + 1;
+ return IntStream.iterate(0, i -> i + step)
+ .limit(iterations)
+ .mapToObj(i -> input.substring(i, (i + step) < strLength ? i + step : strLength))
+ .toArray(String[]::new);
+ }
+
+ /**
+ * Converts a String into its Start Case version
+ * https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage
+ *
+ * @param input The input String
+ * @return Start Case String
+ */
+ public static String startCase(final String input) {
+ validate(input, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
+ // split into a word when we encounter a space, or an underscore, or a dash, or a switch from lower to upper case
+ String[] words = words(input, "\\s|_|-|(?<=[a-z])(?=[A-Z])");
+ return Arrays.stream(words).filter(w -> !w.trim().isEmpty())
+ .map(w -> upperFirst(w.toLowerCase())).collect(joining(" "));
+ }
+
+ public static String escapeRegExp(final String input) {
+ validate(input, NULL_STRING_PREDICATE, NULL_STRING_MSG_SUPPLIER);
+ return input.replaceAll("[\\\\\\^\\$\\*\\+\\-\\?\\.\\|\\(\\)\\{\\}\\[\\]]", "\\\\$0");
+ }
+
private static void validate(String value, Predicate predicate, final Supplier supplier) {
if (predicate.test(value)) {
throw new IllegalArgumentException(supplier.get());
@@ -1124,4 +1468,10 @@ private static long countSubstr(String value, String subStr, boolean allowOverla
}
return countSubstr(value.substring(offset), subStr, allowOverlapping, ++count);
}
+
+ private static boolean isNullOrEmpty(String input) {
+ return input == null || input.isEmpty();
+ }
+
}
+
diff --git a/src/test/java/strman/StrmanTest.java b/src/test/java/strman/StrmanTests.java
similarity index 66%
rename from src/test/java/strman/StrmanTest.java
rename to src/test/java/strman/StrmanTests.java
index be931e4..8ab7ffe 100644
--- a/src/test/java/strman/StrmanTest.java
+++ b/src/test/java/strman/StrmanTests.java
@@ -26,21 +26,29 @@
package strman;
-import org.junit.Test;
-
import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Optional;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.CoreMatchers.*;
+import static org.hamcrest.collection.IsArrayContaining.hasItemInArray;
import static org.hamcrest.collection.IsArrayContainingInOrder.arrayContaining;
+import static org.hamcrest.collection.IsArrayWithSize.arrayWithSize;
import static org.hamcrest.collection.IsArrayWithSize.emptyArray;
+import static org.hamcrest.collection.IsEmptyCollection.empty;
import static org.junit.Assert.*;
import static strman.Strman.*;
import static strman.Strman.endsWith;
-import static strman.Strman.format;
-public class StrmanTest {
+public class StrmanTests {
@Test
public void append_shouldAppendStringsToEndOfValue() throws Exception {
@@ -84,9 +92,9 @@ public void between_shouldReturnArrayWithStringsBetweenStartAndEnd() throws Exce
}
@Test
- public void between_shouldReturnFullStringWhenStartAndEndDoesNotExist() throws Exception {
- assertThat(between("[abc][def]", "{", "}"), arrayContaining("[abc][def]"));
- assertThat(between("", "{", "}"), arrayContaining(""));
+ public void between_shouldReturnEmptyArrayWhenStartAndEndDoesNotExist() throws Exception {
+ assertThat(between("[abc][def]", "{", "}").length, equalTo(0));
+ assertThat(between("", "{", "}").length, equalTo(0));
}
@Test
@@ -344,7 +352,7 @@ public void first_shouldReturnFirstThreeCharsOfString() throws Exception {
final String[] fixture = {
"foo", "foobar"
};
- Arrays.stream(fixture).forEach(el -> assertThat(first(el, 3), equalTo("foo")));
+ Arrays.stream(fixture).forEach(el -> assertThat(first(el, 3), equalTo(Optional.of("foo"))));
}
@Test
@@ -353,7 +361,7 @@ public void head_shouldReturnFirstCharOfString() throws Exception {
"foo", "foobar"
};
- Arrays.stream(fixture).forEach(el -> assertThat(head(el), equalTo("f")));
+ Arrays.stream(fixture).forEach(el -> assertThat(head(el), equalTo(Optional.of("f"))));
}
@Test
@@ -410,9 +418,9 @@ public void indexOf_shouldBeTrueWhenNeedleExistCaseSensitive() throws Exception
@Test
public void inequal_shouldTestInequalityOfStrings() throws Exception {
- assertThat(inequal("a", "b"), equalTo(true));
- assertThat(inequal("a", "a"), equalTo(false));
- assertThat(inequal("0", "1"), equalTo(true));
+ assertThat(unequal("a", "b"), equalTo(true));
+ assertThat(unequal("a", "a"), equalTo(false));
+ assertThat(unequal("0", "1"), equalTo(true));
}
@Test
@@ -800,7 +808,8 @@ public void toKebabCase_shouldKebabCaseAString() throws Exception {
" de_camelize"
};
- Arrays.stream(fixture).forEach(el -> assertThat(String.format("toKebabCase(%s) should be de-camelize", el), toKebabCase(el), equalTo("de-camelize")));
+ Arrays.stream(fixture).forEach(el ->
+ assertThat(String.format("toKebabCase(%s) should be de-camelize", el), toKebabCase(el), equalTo("de-camelize")));
}
@Test
@@ -820,6 +829,18 @@ public void toSnakeCase_shouldSnakeCaseAString() throws Exception {
Arrays.stream(fixture).forEach(el -> assertThat(String.format("toSnakeCase(%s) should be de_camelize", el), toSnakeCase(el), equalTo("de_camelize")));
}
+ @Test
+ public void snakeCase_shouldConvertAStringToSnakecase() throws Exception {
+ String[] input = {
+ "Foo Bar",
+ "fooBar"
+ };
+
+ Arrays.stream(input).forEach(el ->
+ assertThat(String.format("%s should be foo_bar", el), toSnakeCase(el), is(equalTo("foo_bar"))));
+
+ }
+
@Test
public void unequal_shouldTestInequalityOfStrings() throws Exception {
assertThat(unequal("a", "b"), equalTo(true));
@@ -845,4 +866,376 @@ public void removeRight_shouldNotLowercaseWhenCaseInsensitive() throws Exception
String result = removeRight("Remove the END at the end", " END", false);
assertThat(result, is("Remove the END at the"));
}
-}
\ No newline at end of file
+
+ @Test
+ public void transliterate_shouldDeburrTheString() throws Exception {
+ String result = transliterate("déjà vu");
+ assertThat(result, is(equalTo("deja vu")));
+ }
+
+ @Ignore
+ public void htmlEncode_shouldConvertCharactersToTheirHtmlEntities() throws Exception {
+ String result = htmlEncode("fred, barney, & pebbles");
+ assertThat(result, is(equalTo("fred, barney, & pebbles")));
+ }
+
+ @Test
+ public void kebabCase_shouldConvertAStringToKebabCase() throws Exception {
+ String[] input = {
+ "Foo Bar",
+ "fooBar"
+ };
+
+ Arrays.stream(input).forEach(el ->
+ assertThat(String.format("%s should be foo-bar", el), toKebabCase(el), is(equalTo("foo-bar"))));
+
+ }
+
+ @Test
+ public void join_shouldJoinArrayOfStringIntoASingleString() throws Exception {
+ String[] strings = {
+ "hello",
+ "world",
+ "123"
+ };
+ assertThat(join(strings, ";"), is(equalTo("hello;world;123")));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void join_shouldThrowIllegalArgumentExceptionWhenSeparatorIsNull() throws Exception {
+ String[] strings = {
+ "hello",
+ "world",
+ "123"
+ };
+
+ join(strings, null);
+ }
+
+ @Test
+ public void join_shouldReturnEmptyStringWhenInputArrayIsEmpty() throws Exception {
+ String[] emptyArray = {};
+ assertThat(join(emptyArray, ","), is(equalTo("")));
+ }
+
+ @Test
+ public void capitalize_shouldCapitalizeFirstCharacterOfString() throws Exception {
+ String[] strings = {
+ "FRED",
+ "fRED",
+ "fred"
+ };
+ Arrays.stream(strings).forEach(el -> assertThat(String.format("%s should be Fred", el), capitalize(el), equalTo("Fred")));
+ }
+
+ @Test
+ public void lowerFirst_shouldLowercasedFirstCharacterOfString() throws Exception {
+ assertThat(lowerFirst("FRED"), is(equalTo("fRED")));
+ assertThat(lowerFirst("fred"), is(equalTo("fred")));
+ assertThat(lowerFirst("Fred"), is(equalTo("fred")));
+ }
+
+ @Test
+ public void isEnclosedBetween_shouldChekcWhetherStringIsEnclosed() throws Exception {
+ assertThat(isEnclosedBetween("{{shekhar}}", "{{", "}}"), is(true));
+ assertThat(isEnclosedBetween("shekhar", "{{", "}}"), is(false));
+ assertThat(isEnclosedBetween("*shekhar*", "*"), is(true));
+ assertThat(isEnclosedBetween("shekhar", "*"), is(false));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void isEnclosedBetween_shouldThrowIllegalArgumentExceptionWhenEncloserIsNull() throws Exception {
+ assertThat(isEnclosedBetween("shekhar", null), is(false));
+ }
+
+ @Test
+ public void words_shouldConvertTextToWords() throws Exception {
+ final String line = "This is a string, with words!";
+ assertThat(words(line), arrayContaining("This", "is", "a", "string,", "with", "words!"));
+ }
+
+ @Test
+ public void upperFirst_shouldConvertFirstCharToUpperCase() throws Exception {
+ assertThat(upperFirst("fred"), is("Fred"));
+ }
+
+ @Test
+ public void upperFirst_shouldReturnSameStringIfFirstCharIsUpperCase() throws Exception {
+ assertThat(upperFirst("FRED"), is("FRED"));
+ }
+
+ @Test
+ public void trimStart_shouldRemoveAllWhitespaceAtStart() throws Exception {
+ assertThat(trimStart(" abc "), is(Optional.of("abc ")));
+ assertThat(trimStart("abc "), is(Optional.of("abc ")));
+ assertThat(trimStart("abc"), is(Optional.of("abc")));
+ assertThat(trimStart(""), is(Optional.empty()));
+ assertThat(trimStart(null), is(Optional.empty()));
+ }
+
+ @Test
+ public void trimStart_shouldRemoveSpecialCharactersAtStart() throws Exception {
+ assertThat(trimStart("-_-abc-_-", "_", "-"), is(Optional.of("abc-_-")));
+ assertThat(trimStart("-_-!abc-_-", "_", "-", "!"), is(Optional.of("abc-_-")));
+ assertThat(trimStart("-_-#abc-_-", "_", "-", "!", "#"), is(Optional.of("abc-_-")));
+ }
+
+ @Test
+ public void trimEnd_shouldRemoveAllTrailingWhitespace() throws Exception {
+ assertThat(trimEnd(" abc "), is(Optional.of(" abc")));
+ assertThat(trimEnd("abc "), is(Optional.of("abc")));
+ assertThat(trimEnd("abc"), is(Optional.of("abc")));
+ assertThat(trimEnd(""), is(Optional.empty()));
+ assertThat(trimEnd(null), is(Optional.empty()));
+ }
+
+ @Test
+ public void trimEnd_shouldRemoveAllTrailingSpecialCharacters() throws Exception {
+ assertThat(trimEnd("-_-abc-_-", "_", "-"), is(Optional.of("-_-abc")));
+ assertThat(trimEnd("-_-abc!-_-", "_", "-", "!"), is(Optional.of("-_-abc")));
+ assertThat(trimEnd("-_-abc#-_-", "_", "-", "!", "#"), is(Optional.of("-_-abc")));
+ }
+
+
+ @Test
+ public void charsCount_shouldReturnEmptyWhenInputStringIsNull() {
+ assertThat(charsCount(null), equalTo(Collections.emptyMap()));
+ }
+
+ @Test
+ public void charsCount_shouldReturnEmptyWhenInputStringIsEmpty() {
+ assertThat(charsCount(""), equalTo(Collections.emptyMap()));
+ }
+
+ @Test
+ public void charsCount_shouldReturnCharsCountWhenInputIsASimpleString() {
+ Map expectedOutput = new HashMap() {{
+ put('a', 1L);
+ put('b', 1L);
+ put('c', 1L);
+ }};
+
+ assertThat(charsCount("abc"), equalTo(expectedOutput));
+ }
+
+ @Test
+ public void charsCount_shouldReturnCharsCountWhenInputIsAComplexString() {
+ Map expectedOutput = new HashMap() {{
+ put('a', 1L);
+ put('b', 2L);
+ put('c', 3L);
+
+ put('A', 1L);
+ put('B', 2L);
+ put('C', 3L);
+ put('-', 10L);
+ }};
+
+ assertThat(charsCount("-----abbcccCCCBBA-----"), equalTo(expectedOutput));
+ }
+
+ @Test
+ public void isBlank_shouldReturnTrueIfNull() {
+ assertTrue(isBlank(null));
+ }
+
+ @Test
+ public void isBlank_shouldReturnTrueIfEmpty() {
+ assertTrue(isBlank(""));
+ }
+
+ @Test
+ public void isBlank_shouldReturnFalseIfNotEmpty() {
+ assertFalse(isBlank("ac"));
+ }
+
+ @Test
+ public void underscored_shouldReturnUnderscoredString() {
+ assertThat(underscored("MozTransform"), equalTo("moz_transform"));
+ }
+
+ @Test
+ public void underscored_shouldReturnEmptyStringIfEmptyStringPassedIn() {
+ assertThat(underscored(""), equalTo(""));
+ }
+
+ @Test
+ public void underscored_shouldReturnNullIfNullPassedIn() {
+ assertThat(underscored(null), equalTo(""));
+ }
+
+ @Test
+ public void underscored_shouldUnderscoreInputString() throws Exception {
+// assertThat(underscored("foo-bar-baz"), equalTo("foo_bar_baz"));
+ assertThat(underscored("fooBarBaz"), equalTo("foo_bar_baz"));
+// assertThat(underscored("FooBarBaz"), equalTo("foo_bar_baz"));
+// assertThat(underscored(" foo bar baz "), equalTo("foo_bar_baz"));
+ }
+
+ @Test
+ public void zip_shouldReturnEmptyList_whenNullOrEmptyIsPassedIn() {
+ assertThat(zip("a", null), is(empty()));
+ assertThat(zip("", "a"), is(empty()));
+ }
+
+ @Test
+ public void zip_shouldReturnListOfOneElement_forSimplestValidInput() {
+ assertThat(zip("a", "b"), equalTo(asList("ab")));
+ }
+
+ @Test
+ public void zip_shouldReturnExpectedListOfPairs_whenBothInputsHaveSameSize() {
+ assertThat(zip("abc", "def"), equalTo(asList("ad", "be", "cf")));
+ assertThat(zip("ABC", "DEF"), equalTo(asList("AD", "BE", "CF")));
+ }
+
+ @Test
+ public void zip_shouldReturnExpectedListOfPairs_whenFirstInputIsBiggerThanSecond() {
+ assertThat(zip("abc", "d"), equalTo(asList("ad")));
+ assertThat(zip("ABCDE", "FGH"), equalTo(asList("AF", "BG", "CH")));
+ }
+
+ @Test
+ public void zip_shouldReturnExpectedListOfPairs_whenSecondInputIsBiggerThanFirst() {
+ assertThat(zip("d", "abc"), equalTo(asList("da")));
+ assertThat(zip("FGH", "ABCDE"), equalTo(asList("FA", "GB", "HC")));
+ }
+
+ @Test
+ public void zip_shouldReturnExpectedListOfTriplets_whenThreeInputs() {
+ assertThat(zip("abc", "def", "ghi"), equalTo(asList("adg", "beh", "cfi")));
+ }
+
+ @Test
+ public void zip_shouldReturnExpectedListOfTuples_whenMoreThanThreeInputs() {
+ assertThat(zip("abc", "def", "ghi", "123"), equalTo(asList("adg1", "beh2", "cfi3")));
+ }
+
+ @Test
+ public void zip_shouldReturnEmptyList_whenNotEnoughInputs() {
+ assertThat(zip(), is(empty()));
+ }
+
+ @Test
+ public void zip_shouldReturnInputInListForm_whenOnlyOneInput() {
+ assertThat(zip("zip"), is(equalTo(asList("z", "i", "p"))));
+ assertThat(zip("z"), is(equalTo(singletonList("z"))));
+ }
+
+ @Test
+ public void lines_shouldReturnEmptyArrayWhenInputIsNull() throws Exception {
+ assertThat(lines(null), emptyArray());
+ }
+
+ @Test
+ public void lines_shouldReturnArrayWithOneEmptyElementWhenInputIsEmptyString() throws Exception {
+ assertThat(lines(""), arrayWithSize(1));
+ assertThat(lines(""), hasItemInArray(""));
+ }
+
+ @Test
+ public void lines_shouldSplitToLines() throws Exception {
+ assertThat(lines("Hello\r\nWorld").length, equalTo(2));
+ assertThat(lines("Hello\rWorld").length, equalTo(2));
+ assertThat(lines("Hello World").length, equalTo(1));
+ assertThat(lines("\r\n\n\r ").length, equalTo(4));
+ assertThat(lines("Hello\r\r\nWorld").length, equalTo(3));
+ assertThat(lines("Hello\r\rWorld").length, equalTo(3));
+ }
+
+ @Test
+ public void humanize_shouldHumanizeStrings() throws Exception {
+ assertThat(humanize("the_humanize_method"), equalTo("The humanize method"));
+ assertThat(humanize("ThehumanizeMethod"), equalTo("Thehumanize method"));
+ assertThat(humanize("ThehumanizeMethod"), equalTo("Thehumanize method"));
+ assertThat(humanize("the humanize method"), equalTo("The humanize method"));
+ assertThat(humanize("the humanize_id method_id"), equalTo("The humanize id method id"));
+ assertThat(humanize("the humanize method "), equalTo("The humanize method"));
+ assertThat(humanize(" capitalize dash-CamelCase_underscore trim "), equalTo("Capitalize dash camel case underscore trim"));
+ assertThat(humanize(""), equalTo(""));
+ assertThat(humanize(null), equalTo(""));
+ }
+
+ @Test
+ public void dasherize_shouldDasherizeInputString() throws Exception {
+ assertThat(dasherize("the_dasherize_string_method"), equalTo("the-dasherize-string-method"));
+ assertThat(dasherize("TheDasherizeStringMethod"), equalTo("the-dasherize-string-method"));
+ assertThat(dasherize("thisIsATest"), equalTo("this-is-a-test"));
+ assertThat(dasherize("this Is A Test"), equalTo("this-is-a-test"));
+ assertThat(dasherize("thisIsATest123"), equalTo("this-is-a-test123"));
+ assertThat(dasherize("123thisIsATest"), equalTo("123this-is-a-test"));
+ assertThat(dasherize("the dasherize string method"), equalTo("the-dasherize-string-method"));
+ assertThat(dasherize("the dasherize string method "), equalTo("the-dasherize-string-method"));
+ assertThat(dasherize("input with a-dash"), equalTo("input-with-a-dash"));
+ assertThat(dasherize(""), equalTo(""));
+ assertThat(dasherize(null), equalTo(""));
+ }
+
+ @Test
+ public void swapCase_shouldSwapCaseOfCharacters() throws Exception {
+ assertThat(swapCase("AaBbCcDdEe"), equalTo("aAbBcCdDeE"));
+ assertThat(swapCase("Hello World"), equalTo("hELLO wORLD"));
+ assertThat(swapCase(""), equalTo(""));
+ assertThat(swapCase(null), equalTo(""));
+ }
+
+ @Test
+ public void chop_shouldChopStringByStep() throws Exception {
+ assertThat(chop(null, 2).length, equalTo(0));
+ assertThat(chop("whitespace", 2).length, equalTo(5));
+ assertThat(chop("whitespace", 3).length, equalTo(4));
+ assertThat(chop("whitespace", 0)[0].length(), equalTo(10));
+ }
+
+ @Test
+ public void formatNumber_shouldFormatNumberWithCommaDelimiter() throws Exception {
+ assertThat(formatNumber(1000), equalTo("1,000"));
+ assertThat(formatNumber(100000), equalTo("100,000"));
+ assertThat(formatNumber(10000000), equalTo("10,000,000"));
+ assertThat(formatNumber(100000000), equalTo("100,000,000"));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void startCase_shouldThrowException() throws Exception {
+ startCase(null);
+ }
+
+ @Test
+ public void startCase_shouldStartCaseInputString() throws Exception {
+ assertThat(startCase(""), equalTo(""));
+ assertThat(startCase("ALL CAPS"), equalTo("All Caps"));
+ assertThat(startCase("camelCase"), equalTo("Camel Case"));
+ assertThat(startCase("kebab-case"), equalTo("Kebab Case"));
+ assertThat(startCase("Snake_case"), equalTo("Snake Case"));
+ assertThat(startCase(" spaces "), equalTo("Spaces"));
+ assertThat(startCase("spaces between words"), equalTo("Spaces Between Words"));
+ assertThat(startCase("--dashes--"), equalTo("Dashes"));
+ assertThat(startCase("dashes----between----words"), equalTo("Dashes Between Words"));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void escapeRegExp_shouldThrowException() throws Exception {
+ escapeRegExp(null);
+ }
+
+ @Test
+ public void escapeRegExp_shouldEscapeRegExp() throws Exception {
+ assertThat(escapeRegExp("\\"), equalTo("\\\\"));
+ assertThat(escapeRegExp("^"), equalTo("\\^"));
+ assertThat(escapeRegExp("$"), equalTo("\\$"));
+ assertThat(escapeRegExp("*"), equalTo("\\*"));
+ assertThat(escapeRegExp("+"), equalTo("\\+"));
+ assertThat(escapeRegExp("-"), equalTo("\\-"));
+ assertThat(escapeRegExp("?"), equalTo("\\?"));
+ assertThat(escapeRegExp("."), equalTo("\\."));
+ assertThat(escapeRegExp("|"), equalTo("\\|"));
+ assertThat(escapeRegExp("("), equalTo("\\("));
+ assertThat(escapeRegExp(")"), equalTo("\\)"));
+ assertThat(escapeRegExp("{"), equalTo("\\{"));
+ assertThat(escapeRegExp("}"), equalTo("\\}"));
+ assertThat(escapeRegExp("["), equalTo("\\["));
+ assertThat(escapeRegExp("]"), equalTo("\\]"));
+ assertThat(escapeRegExp("How much is (2+3)? 5"), equalTo("How much is \\(2\\+3\\)\\? 5"));
+ assertThat(escapeRegExp("\\s|_|-|(?<=[a-z])(?=[A-Z])"), equalTo("\\\\s\\|_\\|\\-\\|\\(\\?<=\\[a\\-z\\]\\)\\(\\?=\\[A\\-Z\\]\\)"));
+ }
+}