diff --git a/.internal/createCaseFirst.js b/.internal/createCaseFirst.js index 029097a2f..2d4cfee74 100644 --- a/.internal/createCaseFirst.js +++ b/.internal/createCaseFirst.js @@ -11,6 +11,10 @@ import stringToArray from './stringToArray.js' */ function createCaseFirst(methodName) { return (string) => { + if (!string) { + return '' + } + const strSymbols = hasUnicode(string) ? stringToArray(string) : undefined diff --git a/camelCase.js b/camelCase.js index 596f37bf7..9882da6f2 100644 --- a/camelCase.js +++ b/camelCase.js @@ -1,5 +1,6 @@ import upperFirst from './upperFirst.js' import words from './words.js' +import toString from './toString.js' /** * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). @@ -21,7 +22,7 @@ import words from './words.js' * // => 'fooBar' */ const camelCase = (string) => ( - words(`${string}`.replace(/['\u2019]/g, '')).reduce((result, word, index) => { + words(toString(string).replace(/['\u2019]/g, '')).reduce((result, word, index) => { word = word.toLowerCase() return result + (index ? upperFirst(word) : word) }, '') diff --git a/capitalize.js b/capitalize.js index 5b889d15c..2ad2ffed9 100644 --- a/capitalize.js +++ b/capitalize.js @@ -1,4 +1,5 @@ import upperFirst from './upperFirst.js' +import toString from './toString.js' /** * Converts the first character of `string` to upper case and the remaining @@ -13,7 +14,7 @@ import upperFirst from './upperFirst.js' * capitalize('FRED') * // => 'Fred' */ -const capitalize = (string) => upperFirst(string.toLowerCase()) +const capitalize = (string) => upperFirst(toString(string).toLowerCase()) export default capitalize diff --git a/escape.js b/escape.js index fa2ed605a..eda499a1c 100644 --- a/escape.js +++ b/escape.js @@ -41,7 +41,7 @@ const reHasUnescapedHtml = RegExp(reUnescapedHtml.source) function escape(string) { return (string && reHasUnescapedHtml.test(string)) ? string.replace(reUnescapedHtml, (chr) => htmlEscapes[chr]) - : string + : (string || '') } export default escape diff --git a/kebabCase.js b/kebabCase.js index 61b6898ca..bc436b949 100644 --- a/kebabCase.js +++ b/kebabCase.js @@ -1,4 +1,5 @@ import words from './words.js' +import toString from './toString.js' /** * Converts `string` to @@ -21,7 +22,7 @@ import words from './words.js' * // => 'foo-bar' */ const kebabCase = (string) => ( - words(`${string}`.replace(/['\u2019]/g, '')).reduce((result, word, index) => ( + words(toString(string).replace(/['\u2019]/g, '')).reduce((result, word, index) => ( result + (index ? '-' : '') + word.toLowerCase() ), '') ) diff --git a/lowerCase.js b/lowerCase.js index e460e5143..3da8966cf 100644 --- a/lowerCase.js +++ b/lowerCase.js @@ -1,4 +1,5 @@ import words from './words.js' +import toString from './toString.js' const reQuotes = /['\u2019]/g @@ -22,7 +23,7 @@ const reQuotes = /['\u2019]/g * // => 'foo bar' */ const lowerCase = (string) => ( - words(`${string}`.replace(reQuotes, '')).reduce((result, word, index) => ( + words(toString(string).replace(reQuotes, '')).reduce((result, word, index) => ( result + (index ? ' ' : '') + word.toLowerCase() ), '') ) diff --git a/pad.js b/pad.js index e37e4def8..3cfd9131b 100644 --- a/pad.js +++ b/pad.js @@ -25,7 +25,7 @@ import stringSize from './.internal/stringSize.js' function pad(string, length, chars) { const strLength = length ? stringSize(string) : 0 if (!length || strLength >= length) { - return string + return (string || '') } const mid = (length - strLength) / 2 return ( diff --git a/padEnd.js b/padEnd.js index 3234c194a..0fe4ab188 100644 --- a/padEnd.js +++ b/padEnd.js @@ -26,7 +26,7 @@ function padEnd(string, length, chars) { const strLength = length ? stringSize(string) : 0 return (length && strLength < length) ? (string + createPadding(length - strLength, chars)) - : string + : (string || '') } export default padEnd diff --git a/padStart.js b/padStart.js index a4271b74f..025708384 100644 --- a/padStart.js +++ b/padStart.js @@ -26,7 +26,7 @@ function padStart(string, length, chars) { const strLength = length ? stringSize(string) : 0 return (length && strLength < length) ? (createPadding(length - strLength, chars) + string) - : string + : (string || '') } export default padStart diff --git a/snakeCase.js b/snakeCase.js index 2599e9f56..8ddde6e41 100644 --- a/snakeCase.js +++ b/snakeCase.js @@ -1,4 +1,5 @@ import words from './words.js' +import toString from './toString.js' /** * Converts `string` to @@ -24,7 +25,7 @@ import words from './words.js' * // => 'foo_2_bar' */ const snakeCase = (string) => ( - words(`${string}`.replace(/['\u2019]/g, '')).reduce((result, word, index) => ( + words(toString(string).replace(/['\u2019]/g, '')).reduce((result, word, index) => ( result + (index ? '_' : '') + word.toLowerCase() ), '') ) diff --git a/test/Strings-category-methods.js b/test/Strings-category-methods.js deleted file mode 100644 index 9e391a56e..000000000 --- a/test/Strings-category-methods.js +++ /dev/null @@ -1,43 +0,0 @@ -import assert from 'assert'; -import lodashStable from 'lodash'; -import { _, stubString } from './utils.js'; - -describe('"Strings" category methods', function() { - var stringMethods = [ - 'camelCase', - 'capitalize', - 'escape', - 'kebabCase', - 'lowerCase', - 'lowerFirst', - 'pad', - 'padEnd', - 'padStart', - 'repeat', - 'snakeCase', - 'toLower', - 'toUpper', - 'trim', - 'trimEnd', - 'trimStart', - 'truncate', - 'unescape', - 'upperCase', - 'upperFirst' - ]; - - lodashStable.each(stringMethods, function(methodName) { - var func = _[methodName]; - - it('`_.' + methodName + '` should return an empty string for empty values', function() { - var values = [, null, undefined, ''], - expected = lodashStable.map(values, stubString); - - var actual = lodashStable.map(values, function(value, index) { - return index ? func(value) : func(); - }); - - assert.deepStrictEqual(actual, expected); - }); - }); -}); diff --git a/test/Strings-category-methods.test.js b/test/Strings-category-methods.test.js new file mode 100644 index 000000000..781a050ef --- /dev/null +++ b/test/Strings-category-methods.test.js @@ -0,0 +1,83 @@ +import assert from 'assert'; +import lodashStable from 'lodash'; +import { stubString } from './utils.js'; + +import camelCase from '../camelCase.js'; +import capitalize from '../capitalize.js'; +import escape from '../escape.js'; +import kebabCase from '../kebabCase.js'; +import lowerCase from '../lowerCase.js'; +import lowerFirst from '../lowerFirst.js'; +import pad from '../pad.js'; +import padEnd from '../padEnd.js'; +import padStart from '../padStart.js'; +import repeat from '../repeat.js'; +import snakeCase from '../snakeCase.js'; +import trim from '../trim.js'; +import trimStart from '../trimStart.js'; +import trimEnd from '../trimEnd.js'; +import truncate from '../truncate.js'; +import unescape from '../unescape.js'; +import upperCase from '../upperCase.js'; +import upperFirst from '../upperFirst'; + + +const methods = { + camelCase, + capitalize, + escape, + kebabCase, + lowerCase, + lowerFirst, + pad, + padEnd, + padStart, + repeat, + snakeCase, + trim, + trimStart, + trimEnd, + truncate, + unescape, + upperCase, + upperFirst +} + + +describe('"Strings" category methods', function() { + var stringMethods = [ + 'camelCase', + 'capitalize', + 'escape', + 'kebabCase', + 'lowerCase', + 'lowerFirst', + 'pad', + 'padEnd', + 'padStart', + 'repeat', + 'snakeCase', + 'trim', + 'trimEnd', + 'trimStart', + 'truncate', + 'unescape', + 'upperCase', + 'upperFirst' + ]; + + lodashStable.each(stringMethods, function(methodName) { + var func = methods[methodName]; + + it('`_.' + methodName + '` should return an empty string for empty values', function() { + var values = [, null, undefined, ''], + expected = lodashStable.map(values, stubString); + + var actual = lodashStable.map(values, function(value, index) { + return index ? func(value) : func(); + }); + + assert.deepStrictEqual(actual, expected); + }); + }); +}); diff --git a/trim.js b/trim.js index c79ead74c..b7ac73171 100644 --- a/trim.js +++ b/trim.js @@ -25,7 +25,7 @@ function trim(string, chars) { return string.trim() } if (!string || !chars) { - return string + return (string || '') } const strSymbols = stringToArray(string) const chrSymbols = stringToArray(chars) diff --git a/trimEnd.js b/trimEnd.js index caba219cf..b802521ba 100644 --- a/trimEnd.js +++ b/trimEnd.js @@ -26,7 +26,7 @@ function trimEnd(string, chars) { return string[methodName]() } if (!string || !chars) { - return string + return (string || '') } const strSymbols = stringToArray(string) const end = charsEndIndex(strSymbols, stringToArray(chars)) + 1 diff --git a/trimStart.js b/trimStart.js index 2d232a888..6138a88e8 100644 --- a/trimStart.js +++ b/trimStart.js @@ -26,7 +26,7 @@ function trimStart(string, chars) { return string[methodName]() } if (!string || !chars) { - return string + return (string || '') } const strSymbols = stringToArray(string) const start = charsStartIndex(strSymbols, stringToArray(chars)) diff --git a/truncate.js b/truncate.js index de0eef11f..f3a928cdc 100644 --- a/truncate.js +++ b/truncate.js @@ -5,6 +5,7 @@ import isObject from './isObject.js' import isRegExp from './isRegExp.js' import stringSize from './.internal/stringSize.js' import stringToArray from './.internal/stringToArray.js' +import toString from './toString.js' /** Used as default options for `truncate`. */ const DEFAULT_TRUNC_LENGTH = 30 @@ -59,6 +60,9 @@ function truncate(string, options) { length = 'length' in options ? options.length : length omission = 'omission' in options ? baseToString(options.omission) : omission } + + string = toString(string) + let strSymbols let strLength = string.length if (hasUnicode(string)) { diff --git a/unescape.js b/unescape.js index 9644f395c..e05c73608 100644 --- a/unescape.js +++ b/unescape.js @@ -32,7 +32,7 @@ const reHasEscapedHtml = RegExp(reEscapedHtml.source) function unescape(string) { return (string && reHasEscapedHtml.test(string)) ? string.replace(reEscapedHtml, (entity) => htmlUnescapes[entity]) - : string + : (string || '') } export default unescape diff --git a/upperCase.js b/upperCase.js index 68839526e..db14da836 100644 --- a/upperCase.js +++ b/upperCase.js @@ -1,4 +1,5 @@ import words from './words.js' +import toString from './toString.js' /** * Converts `string`, as space separated words, to upper case. @@ -20,7 +21,7 @@ import words from './words.js' * // => 'FOO BAR' */ const upperCase = (string) => ( - words(`${string}`.replace(/['\u2019]/g, '')).reduce((result, word, index) => ( + words(toString(string).replace(/['\u2019]/g, '')).reduce((result, word, index) => ( result + (index ? ' ' : '') + word.toUpperCase() ), '') )