├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── .verb.md ├── LICENSE ├── README.md ├── docs └── example.md ├── example.md ├── gulpfile.js ├── index.js ├── lib ├── array │ ├── after.js │ ├── arrayify.js │ ├── before.js │ ├── compact.js │ ├── difference.js │ ├── each.js │ ├── first.js │ ├── flatten.js │ ├── forEach.js │ ├── index.js │ ├── indexOf.js │ ├── isArray.js │ ├── last.js │ ├── map.js │ ├── slice.js │ ├── sort.js │ ├── union.js │ └── unique.js ├── collection │ ├── any.js │ ├── contains.js │ └── index.js ├── fs │ ├── index.js │ ├── tryRead.js │ ├── tryReaddir.js │ └── tryRequire.js ├── function │ ├── identity.js │ ├── index.js │ ├── noop.js │ └── partialRight.js ├── index.js ├── lang │ ├── hasValues.js │ ├── index.js │ ├── isEmpty.js │ ├── isObject.js │ ├── isPlainObject.js │ └── typeOf.js ├── math │ ├── index.js │ └── sum.js ├── object │ ├── defaults.js │ ├── extend.js │ ├── filter.js │ ├── forIn.js │ ├── forOwn.js │ ├── functions.js │ ├── hasOwn.js │ ├── index.js │ ├── keys.js │ ├── mapValues.js │ ├── merge.js │ ├── methods.js │ ├── omit.js │ ├── pick.js │ ├── pluck.js │ ├── prop.js │ ├── reduce.js │ ├── result.js │ └── some.js └── string │ ├── camelcase.js │ ├── centerAlign.js │ ├── chop.js │ ├── count.js │ ├── dashcase.js │ ├── dotcase.js │ ├── ellipsis.js │ ├── hyphenate.js │ ├── index.js │ ├── isString.js │ ├── pascalcase.js │ ├── pathcase.js │ ├── replace.js │ ├── reverse.js │ ├── rightAlign.js │ ├── sentencecase.js │ ├── slugify.js │ ├── snakecase.js │ ├── toString.js │ ├── truncate.js │ └── wordwrap.js ├── package.json ├── support └── plugins.js ├── test ├── array.js ├── collection.js ├── fixtures │ ├── README.md │ ├── a.js │ ├── a.md │ └── b.js ├── fs.js ├── lang.js ├── math.js ├── object.js └── string.js └── verbfile.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | end_of_line = lf 7 | charset = utf-8 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.json] 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.yml] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [*.md] 21 | indent_style = space 22 | indent_size = 2 23 | trim_trailing_whitespace = false 24 | 25 | [test/fixtures/*] 26 | trim_trailing_whitespace = false 27 | insert_final_newline = false -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | * text eol=lf 3 | 4 | # binaries 5 | *.ai binary 6 | *.psd binary 7 | *.jpg binary 8 | *.gif binary 9 | *.png binary 10 | *.jpeg binary -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | *.sublime-* 3 | _gh_pages 4 | bower_components 5 | node_modules 6 | npm-debug.log 7 | actual 8 | test/actual 9 | temp 10 | tmp 11 | TODO.md 12 | vendor 13 | coverage 14 | benchmark 15 | staging 16 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "asi": false, 3 | "boss": true, 4 | "curly": false, 5 | "eqeqeq": true, 6 | "eqnull": true, 7 | "esnext": true, 8 | "immed": true, 9 | "latedef": false, 10 | "laxbreak": true, 11 | "laxcomma": false, 12 | "mocha": true, 13 | "newcap": true, 14 | "noarg": true, 15 | "node": true, 16 | "sub": true, 17 | "undef": true, 18 | "unused": true 19 | } 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "0.10" 5 | - "0.12" 6 | - "iojs" 7 | git: 8 | depth: 10 -------------------------------------------------------------------------------- /.verb.md: -------------------------------------------------------------------------------- 1 | # {%= name %} {%= badge("fury") %} {%= badge("travis") %} 2 | 3 | > {%= description %} 4 | 5 | 6 | {%= include("install-npm", {save: true}) %} 7 | 8 | ## TOC 9 | 10 | 11 | 12 | 13 | ## Usage 14 | 15 | **Utils grouped by collection** 16 | 17 | The top level export gives you an object with utils grouped into collections, like `array`, `object`, `math`, etc: 18 | 19 | ```js 20 | var utils = require('{%= name %}'); 21 | //=> {array: {flatten: [function], ...}, collection: {...}} 22 | ``` 23 | 24 | See [example.md](./example.md) for an example of the `utils` object. 25 | 26 | 27 | **Get all utils on one object** 28 | 29 | If you want all utils on a single object (e.g. not grouped by collection): 30 | 31 | ```js 32 | // all utils are on the `_` property 33 | var utils = require('{%= name %}')._; 34 | ``` 35 | 36 | **Only get a specific collection** 37 | 38 | If you just want the `string` or `object` utils: 39 | 40 | ```js 41 | var string = require('{%= name %}').string; 42 | var object = require('{%= name %}').object; 43 | ``` 44 | 45 | ## API 46 | {%= apidocs("lib/**/*.js") %} 47 | 48 | ## Code coverage 49 | 50 | Please help improve code coverage by [adding unit tests](#contributing). 51 | 52 | ``` 53 | {%= coverage("coverage/summary.txt") %} 54 | ``` 55 | 56 | ## Running tests 57 | {%= include("tests") %} 58 | 59 | ## Contributing 60 | > {%= include("contributing") %} 61 | 62 | ### Adding utils 63 | 64 | If you want to do a PR to add a util, please read the following first: 65 | 66 | - follow the same coding style as the rest of the library, same with code comments 67 | - add sufficient unit tests 68 | - Install dev dependencies and [run verb](#running-verb) 69 | - Look over the README to make sure that verb rendered out the docs with your method and code comments. 70 | 71 | **Adding external modules as dependencies** 72 | 73 | - External modules will only be considered if they meet the same quality and coding standards as the rest of the library. At minimum this includes documentation, code comments, and unit tests. Benchmarks are also strongly preferred. 74 | 75 | ### Updating the docs 76 | 77 | Do not edit the readme manually since [verb] is used to generate documentation. 78 | 79 | - API docs: If you see an error in the API documentation, just update the code comments for that method, then [run verb](#running-verb). 80 | - Everything else, please look over the [.verb.md](./.verb.md) template to see where the error is, then [run verb](#running-verb). 81 | 82 | ### Running verb 83 | {%= include("run-verb") %} 84 | 85 | 86 | ## About 87 | 88 | **Why another utils lib?** 89 | 90 | - I'm a node.js developer. I want fast, light, dependable utility functions for node.js projects. 91 | - Do you really need bloated, everything-but-the-kitchen-sink functions that are guaranteed to work with IE 4, **for your Yeoman generator or gulp plugin**!? Nonsense. 92 | - The benchmarks that accompany many of the functions in the library show that in some cases, the penalty for using such "kitchen-sink" code is a 2,000-5,000% reduction in speed. Sometimes greater. 93 | 94 | **Project goals** 95 | 96 | - Fastest implementation of each method, without too much compromise. Covering uncommon cases is fine, but don't go overboard. 97 | - Clean well-documented, commented code. 98 | - [When it makes sense](#adding-utils), external libraries are used and exposed instead of writing new code. 99 | - Focus on node.js usage and projects that are likely to use a number of these utils in one project. If you only need one or two of these in a small project, don't use this. Use small modules that do only one thing. 100 | 101 | ## Related projects 102 | > This project depends on these great libraries. If you don't need a full utility belt for your project, any of these can be used by themselves: 103 | 104 | {%= related(Object.keys(dependencies)) %} 105 | 106 | ## Author 107 | {%= include("author") %} 108 | 109 | ## License 110 | {%= copyright() %} 111 | {%= license() %} 112 | 113 | *** 114 | 115 | {%= include("footer") %} 116 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2015, Jon Schlinkert. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # utils [![NPM version](https://badge.fury.io/js/utils.svg)](http://badge.fury.io/js/utils) [![Build Status](https://travis-ci.org/jonschlinkert/utils.svg)](https://travis-ci.org/jonschlinkert/utils) 2 | 3 | > Fast, generic JavaScript/node.js utility functions. 4 | 5 | Install with [npm](https://www.npmjs.com/) 6 | 7 | ```sh 8 | $ npm i utils --save 9 | ``` 10 | 11 | ## TOC 12 | 13 | 14 | 15 | * [Usage](#usage) 16 | * [API](#api) 17 | * [Code coverage](#code-coverage) 18 | * [Running tests](#running-tests) 19 | * [Contributing](#contributing) 20 | - [Adding utils](#adding-utils) 21 | - [Updating the docs](#updating-the-docs) 22 | - [Running verb](#running-verb) 23 | * [About](#about) 24 | * [Related projects](#related-projects) 25 | * [Author](#author) 26 | * [License](#license) 27 | 28 | _(Table of contents generated by [verb](https://github.com/verbose/verb))_ 29 | 30 | 31 | 32 | ## Usage 33 | 34 | **Utils grouped by collection** 35 | 36 | The top level export gives you an object with utils grouped into collections, like `array`, `object`, `math`, etc: 37 | 38 | ```js 39 | var utils = require('utils'); 40 | //=> {array: {flatten: [function], ...}, collection: {...}} 41 | ``` 42 | 43 | See [example.md](./example.md) for an example of the `utils` object. 44 | 45 | **Get all utils on one object** 46 | 47 | If you want all utils on a single object (e.g. not grouped by collection): 48 | 49 | ```js 50 | // all utils are on the `_` property 51 | var utils = require('utils')._; 52 | ``` 53 | 54 | **Only get a specific collection** 55 | 56 | If you just want the `string` or `object` utils: 57 | 58 | ```js 59 | var string = require('utils').string; 60 | var object = require('utils').object; 61 | ``` 62 | 63 | ## API 64 | 65 | ### [.after](lib/array/after.js#L19) 66 | 67 | Returns all of the items in an array after the specified index. 68 | 69 | **Params** 70 | 71 | * `array` **{Array}**: Collection 72 | * `n` **{Number}**: Starting index (number of items to exclude) 73 | * `returns` **{Array}**: Array exluding `n` items. 74 | 75 | **Example** 76 | 77 | ```js 78 | after(['a', 'b', 'c'], 1) 79 | //=> ['c'] 80 | ``` 81 | 82 | ### [.arrayify](lib/array/arrayify.js#L20) 83 | 84 | Cast the give `value` to an array. 85 | 86 | **Params** 87 | 88 | * `val` **{*}** 89 | * `returns` **{Array}** 90 | 91 | **Example** 92 | 93 | ```js 94 | arrayify('abc') 95 | //=> ['abc'] 96 | 97 | arrayify(['abc']) 98 | //=> ['abc'] 99 | ``` 100 | 101 | ### [.before](lib/array/before.js#L20) 102 | 103 | Returns all of the items in an array up to the specified number Opposite of `<%= after() %`. 104 | 105 | **Params** 106 | 107 | * `array` **{Array}** 108 | * `n` **{Number}** 109 | * `returns` **{Array}**: Array excluding items after the given number. 110 | 111 | **Example** 112 | 113 | ```js 114 | before(['a', 'b', 'c'], 2) 115 | //=> ['a', 'b'] 116 | ``` 117 | 118 | ### [.compact](lib/array/compact.js#L17) 119 | 120 | Remove all falsey values from an array. 121 | 122 | **Params** 123 | 124 | * `arr` **{Array}** 125 | * `returns` **{Array}** 126 | 127 | **Example** 128 | 129 | ```js 130 | compact([null, a, undefined, 0, false, b, c, '']); 131 | //=> [a, b, c] 132 | ``` 133 | 134 | ### [.difference](lib/array/difference.js#L24) 135 | 136 | Return the difference between the first array and additional arrays. 137 | 138 | **Params** 139 | 140 | * `a` **{Array}** 141 | * `b` **{Array}** 142 | * `returns` **{Array}** 143 | 144 | **Example** 145 | 146 | ```js 147 | var a = ['a', 'b', 'c', 'd']; 148 | var b = ['b', 'c']; 149 | 150 | diff(a, b); 151 | //=> ['a', 'd'] 152 | ``` 153 | 154 | ### [.each](lib/array/each.js#L27) 155 | 156 | Loop over each item in an array and call the given function on every element. 157 | 158 | **Params** 159 | 160 | * `array` **{Array}** 161 | * `fn` **{Function}** 162 | * `thisArg` **{Object}**: Optionally pass a `thisArg` to be used as the context in which to call the function. 163 | * `returns` **{Array}** 164 | 165 | **Example** 166 | 167 | ```js 168 | each(['a', 'b', 'c'], function (ele) { 169 | return ele + ele; 170 | }); 171 | //=> ['aa', 'bb', 'cc'] 172 | 173 | each(['a', 'b', 'c'], function (ele, i) { 174 | return i + ele; 175 | }); 176 | //=> ['0a', '1b', '2c'] 177 | ``` 178 | 179 | ### [.first](lib/array/first.js#L20) 180 | 181 | Returns the first item, or first `n` items of an array. 182 | 183 | **Params** 184 | 185 | * `array` **{Array}** 186 | * `n` **{Number}**: Number of items to return, starting at `0`. 187 | * `returns` **{Array}** 188 | 189 | **Example** 190 | 191 | ```js 192 | first(['a', 'b', 'c', 'd', 'e'], 2) 193 | //=> ['a', 'b'] 194 | ``` 195 | 196 | ### [.flatten](lib/array/flatten.js#L18) 197 | 198 | Recursively flatten an array or arrays. Uses the fastest implementation of array flatten for node.js 199 | 200 | **Params** 201 | 202 | * `array` **{Array}** 203 | * `returns` **{Array}**: Flattened array 204 | 205 | **Example** 206 | 207 | ```js 208 | flatten(['a', ['b', ['c']], 'd', ['e']]); 209 | //=> ['a', 'b', 'c', 'd', 'e'] 210 | ``` 211 | 212 | ### [.forEach](lib/array/forEach.js#L27) 213 | 214 | Loop over each item in an array and call the given function on every element. 215 | 216 | **Params** 217 | 218 | * `array` **{Array}** 219 | * `fn` **{Function}** 220 | * `thisArg` **{Object}**: Optionally pass a `thisArg` to be used as the context in which to call the function. 221 | * `returns` **{Array}** 222 | 223 | **Example** 224 | 225 | ```js 226 | forEach(['a', 'b', 'c'], function (ele) { 227 | return ele + ele; 228 | }); 229 | //=> ['aa', 'bb', 'cc'] 230 | 231 | forEach(['a', 'b', 'c'], function (ele, i) { 232 | return i + ele; 233 | }); 234 | //=> ['0a', '1b', '2c'] 235 | ``` 236 | 237 | ### [.isArray](lib/array/isArray.js#L19) 238 | 239 | Returns true if the given `value` is an array. 240 | 241 | **Params** 242 | 243 | * `value` **{Array}**: Value to test. 244 | 245 | **Example** 246 | 247 | ```js 248 | isArray(1); 249 | //=> 'false' 250 | 251 | isArray([1]); 252 | //=> 'true' 253 | ``` 254 | 255 | ### [.last](lib/array/last.js#L20) 256 | 257 | Returns the last item, or last `n` items of an array. 258 | 259 | **Params** 260 | 261 | * `array` **{Array}** 262 | * `n` **{Number}**: Number of items to return, starting with the last item. 263 | * `returns` **{Array}** 264 | 265 | **Example** 266 | 267 | ```js 268 | last(['a', 'b', 'c', 'd', 'e'], 2) 269 | //=> ['d', 'e'] 270 | ``` 271 | 272 | ### [.map](lib/array/map.js#L27) 273 | 274 | Returns a new array with the results of calling the given function on every element in the array. This is a faster, node.js focused alternative to JavaScript's native array map. 275 | 276 | **Params** 277 | 278 | * `array` **{Array}** 279 | * `fn` **{Function}** 280 | * `returns` **{Array}** 281 | 282 | **Example** 283 | 284 | ```js 285 | map(['a', 'b', 'c'], function (ele) { 286 | return ele + ele; 287 | }); 288 | //=> ['aa', 'bb', 'cc'] 289 | 290 | map(['a', 'b', 'c'], function (ele, i) { 291 | return i + ele; 292 | }); 293 | //=> ['0a', '1b', '2c'] 294 | ``` 295 | 296 | ### [.slice](lib/array/slice.js#L21) 297 | 298 | Alternative to JavaScript's native array-slice method. Slices `array` from the `start` index up to but not including the `end` index. 299 | 300 | **Params** 301 | 302 | * `array` **{Array}**: the array to slice. 303 | * `start` **{Number}**: Optionally define the starting index. 304 | * `end` **{Number}**: Optionally define the ending index. 305 | 306 | **Example** 307 | 308 | ```js 309 | var arr = ['a', 'b', 'd', 'e', 'f', 'g', 'h', 'i', 'j']; 310 | 311 | slice(arr, 3, 6); 312 | //=> ['e', 'f', 'g'] 313 | ``` 314 | 315 | ### [.union](lib/array/union.js#L19) 316 | 317 | Return an array free of duplicate values. Fastest ES5 implementation. 318 | 319 | **Params** 320 | 321 | * `array` **{Array}**: The array to uniquify 322 | * `returns` **{Array}**: With all union values. 323 | 324 | **Example** 325 | 326 | ```js 327 | union(['a', 'b', 'c', 'c']); 328 | //=> ['a', 'b', 'c'] 329 | ``` 330 | 331 | ### [.unique](lib/array/unique.js#L19) 332 | 333 | Return an array free of duplicate values. Fastest ES5 implementation. 334 | 335 | **Params** 336 | 337 | * `array` **{Array}**: The array to uniquify 338 | * `returns` **{Array}**: With all unique values. 339 | 340 | **Example** 341 | 342 | ```js 343 | unique(['a', 'b', 'c', 'c']); 344 | //=> ['a', 'b', 'c'] 345 | ``` 346 | 347 | ### [.any](lib/collection/any.js#L14) 348 | 349 | Returns `true` if `value` exists in the given string, array 350 | or object. See [any] for documentation. 351 | 352 | **Params** 353 | 354 | * `value` **{*}** 355 | * `target` **{*}** 356 | * `options` **{Object}** 357 | 358 | ### [.contains](lib/collection/contains.js#L17) 359 | 360 | Return true if `collection` contains `value` 361 | 362 | **Params** 363 | 364 | * `collection` **{Array|Object}** 365 | * `string` **{*}** 366 | * `returns` **{Boolean}** 367 | 368 | ### [.tryRead](lib/fs/tryRead.js#L15) 369 | 370 | Try to read the given `filepath`, fail silently and return `null` 371 | when a file doesn't exist. Slightly faster than using `fs.existsSync`. 372 | 373 | **Params** 374 | 375 | * `fp` **{String}**: Path of the file to read. 376 | * `returns` **{String|Null}**: the `utf8` contents string, or `null` if an error is thrown. 377 | 378 | ### [.tryReaddir](lib/fs/tryReaddir.js#L16) 379 | 380 | Try to read the given `directory`. Wraps `fs.readdirSync()` with 381 | a try/catch, so it fails silently instead of throwing when the 382 | directory doesn't exist. 383 | 384 | **Params** 385 | 386 | * `dir` **{String}**: Starting directory 387 | * `returns` **{Array}**: Array of files. 388 | 389 | ### [.tryRequire](lib/fs/tryRequire.js#L15) 390 | 391 | Try to require the given file, returning `null` if not successful 392 | instead of throwing an error. 393 | 394 | **Params** 395 | 396 | * `fp` **{String}**: File path of the file to require 397 | * `returns` **{*}**: Returns the module function/object, or `null` if not found. 398 | 399 | ### [.identity](lib/function/identity.js#L11) 400 | 401 | Returns the first argument passed to the function. 402 | 403 | * `returns` **{*}** 404 | 405 | ### [.noop](lib/function/noop.js#L12) 406 | 407 | A "no-operation" function. Returns `undefined` regardless 408 | of the arguments it receives. 409 | 410 | * `returns` **{undefined}** 411 | 412 | ### [.partialRight](lib/function/partialRight.js#L25) 413 | 414 | Partially applies arguments that will be appended to those provided to the returned function. 415 | 416 | **Params** 417 | 418 | * `ctx` **{Object}**: Optionally supply an invocation context for the returned function. 419 | * `fn` **{Function}**: The function to which arguments should be partially applied. 420 | * `arguments` __{..._}_*: List of arguments to be partially applied. 421 | * `returns` **{Function}**: Returns a function with partially applied arguments. 422 | 423 | **Example** 424 | 425 | ```js 426 | function fullname(first, last) { 427 | return first + ' ' + last; 428 | } 429 | 430 | var name = partialRight(fn, 'Woodward'); 431 | name('Brian'); 432 | //=> 'Brian Woodward' 433 | ``` 434 | 435 | ### [.hasValues](lib/lang/hasValues.js#L34) 436 | 437 | Returns true if any value exists, false if empty. Works for booleans, functions, numbers, strings, nulls, objects and arrays. 438 | 439 | **Params** 440 | 441 | * `object` **{Object}**: The object to check for `value` 442 | * `value` **{*}**: the value to look for 443 | * `returns` **{Boolean}**: True if any values exists. 444 | 445 | **Example** 446 | 447 | ```js 448 | hasValues('a'); 449 | //=> true 450 | 451 | hasValues(''); 452 | //=> false 453 | 454 | hasValues(1); 455 | //=> true 456 | 457 | hasValues({a: 'a'}}); 458 | //=> true 459 | 460 | hasValues({}}); 461 | //=> false 462 | 463 | hasValues(['a']); 464 | //=> true 465 | ``` 466 | 467 | ### [.isEmpty](lib/lang/isEmpty.js#L37) 468 | 469 | Returns true if the given value is empty, false if any value exists. Works for booleans, functions, numbers, strings, nulls, objects and arrays. 470 | 471 | **Params** 472 | 473 | * `object` **{Object}**: The object to check for `value` 474 | * `value` **{*}**: the value to look for 475 | * `returns` **{Boolean}**: False if any values exists. 476 | 477 | **Example** 478 | 479 | ```js 480 | isEmpty('a'); 481 | //=> false 482 | 483 | isEmpty(''); 484 | //=> true 485 | 486 | isEmpty(1); 487 | //=> false 488 | 489 | isEmpty({a: 'a'}); 490 | //=> false 491 | 492 | isEmpty({}); 493 | //=> true 494 | 495 | isEmpty(['a']); 496 | //=> false 497 | ``` 498 | 499 | ### [.isObject](lib/lang/isObject.js#L22) 500 | 501 | Return true if the given `value` is an object with keys. 502 | 503 | **Params** 504 | 505 | * `value` **{Object}**: The value to check. 506 | * `returns` **{Boolean}** 507 | 508 | **Example** 509 | 510 | ```js 511 | isObject(['a', 'b', 'c']) 512 | //=> 'false' 513 | 514 | isObject({a: 'b'}) 515 | //=> 'true' 516 | ``` 517 | 518 | ### [.isPlainObject](lib/lang/isPlainObject.js#L23) 519 | 520 | Return true if the given `value` is an object with keys. 521 | 522 | **Params** 523 | 524 | * `value` **{Object}**: The value to check. 525 | * `returns` **{Boolean}** 526 | 527 | **Example** 528 | 529 | ```js 530 | isPlainObject(Object.create({})); 531 | //=> true 532 | isPlainObject(Object.create(Object.prototype)); 533 | //=> true 534 | isPlainObject({foo: 'bar'}); 535 | //=> true 536 | isPlainObject({}); 537 | //=> true 538 | ``` 539 | 540 | ### [.sum](lib/math/sum.js#L20) 541 | 542 | Returns the sum of all numbers in the given array. 543 | 544 | **Params** 545 | 546 | * `array` **{Array}**: Array of numbers to add up. 547 | * `returns` **{Number}** 548 | 549 | **Example** 550 | 551 | ```js 552 | sum([1, 2, 3, 4, 5]) 553 | //=> '15' 554 | ``` 555 | 556 | ### [.defaults](lib/object/defaults.js#L13) 557 | 558 | Extend `object` with properties of other `objects` 559 | 560 | **Params** 561 | 562 | * `object` **{Object}**: The target object. Pass an empty object to shallow clone. 563 | * `objects` **{Object}** 564 | * `returns` **{Object}** 565 | 566 | ### [.extend](lib/object/extend.js#L16) 567 | 568 | Extend `o` with properties of other `objects`. 569 | 570 | **Params** 571 | 572 | * `o` **{Object}**: The target object. Pass an empty object to shallow clone. 573 | * `objects` **{Object}** 574 | * `returns` **{Object}** 575 | 576 | ### [.functions](lib/object/functions.js#L20) 577 | 578 | Returns a copy of the given `obj` filtered to have only enumerable properties that have function values. 579 | 580 | **Params** 581 | 582 | * `obj` **{Object}** 583 | * `returns` **{Object}** 584 | 585 | **Example** 586 | 587 | ```js 588 | functions({a: 'b', c: function() {}}); 589 | //=> {c: function() {}} 590 | ``` 591 | 592 | ### [.hasOwn](lib/object/hasOwn.js#L18) 593 | 594 | Return true if `key` is an own, enumerable property of the given `obj`. 595 | 596 | **Params** 597 | 598 | * `key` **{String}** 599 | * `obj` **{Object}**: Optionally pass an object to check. 600 | * `returns` **{Boolean}** 601 | 602 | **Example** 603 | 604 | ```js 605 | hasOwn(obj, key); 606 | ``` 607 | 608 | ### [.keys](lib/object/keys.js#L15) 609 | 610 | Return an array of keys for the given `obj`. Uses `Object.keys` 611 | when available, otherwise falls back on `forOwn`. 612 | 613 | **Params** 614 | 615 | * `obj` **{Object}** 616 | * `returns` **{Array}**: Array of keys. 617 | 618 | ### [mapValues](lib/object/mapValues.js#L17) 619 | 620 | Returns new object where each value is the result of 621 | calling the a `callback` function. 622 | 623 | **Params** 624 | 625 | * **{Object}**: obj The object to iterate over 626 | * `cb` **{Function}**: Callback function 627 | * **{Object}**: thisArg Invocation context of `cb` 628 | * `returns` **{Object}** 629 | 630 | ### [.merge](lib/object/merge.js#L23) 631 | 632 | Recursively combine the properties of `o` with the 633 | properties of other `objects`. 634 | 635 | **Params** 636 | 637 | * `o` **{Object}**: The target object. Pass an empty object to shallow clone. 638 | * `objects` **{Object}** 639 | * `returns` **{Object}** 640 | 641 | ### [.methods](lib/object/methods.js#L15) 642 | 643 | Returns a list of all enumerable properties of `obj` that have function 644 | values 645 | 646 | **Params** 647 | 648 | * `obj` **{Object}** 649 | * `returns` **{Array}** 650 | 651 | ### [.reduce](lib/object/reduce.js#L32) 652 | 653 | Reduces an object to a value that is the accumulated result of running each property in the object through a callback. 654 | 655 | **Params** 656 | 657 | * `obj` **{Object}**: The object to iterate over. 658 | * `iterator` **{Function}**: Iterator function 659 | * `initial` **{Object}**: Initial value. 660 | * `thisArg` **{Object}**: The `this` binding of the iterator function. 661 | * `returns` **{Object}** 662 | 663 | **Example** 664 | 665 | ```js 666 | var a = {a: 'foo', b: 'bar', c: 'baz'}; 667 | 668 | reduce(a, function (acc, value, key, obj) { 669 | // `acc`- the initial value (or value from the previous callback call), 670 | // `value`- the of the current property, 671 | // `key`- the of the current property, and 672 | // `obj` - original object 673 | 674 | acc[key] = value.toUpperCase(); 675 | return acc; 676 | }, {}); 677 | 678 | //=> {a: 'FOO', b: 'BAR', c: 'BAZ'}; 679 | ``` 680 | 681 | ### [.camelcase](lib/string/camelcase.js#L20) 682 | 683 | camelCase the characters in `string`. 684 | 685 | **Params** 686 | 687 | * `string` **{String}**: The string to camelcase. 688 | * `returns` **{String}** 689 | 690 | **Example** 691 | 692 | ```js 693 | camelcase("foo bar baz"); 694 | //=> 'fooBarBaz' 695 | ``` 696 | 697 | ### [.centerAlign](lib/string/centerAlign.js#L21) 698 | 699 | Center align the characters in a string using non-breaking spaces. 700 | 701 | **Params** 702 | 703 | * `str` **{String}**: The string to reverse. 704 | * `returns` **{String}**: Centered string. 705 | 706 | **Example** 707 | 708 | ```js 709 | centerAlign("abc"); 710 | ``` 711 | 712 | ### [.chop](lib/string/chop.js#L26) 713 | 714 | Like trim, but removes both extraneous whitespace and non-word characters from the beginning and end of a string. 715 | 716 | **Params** 717 | 718 | * `string` **{String}**: The string to chop. 719 | * `returns` **{String}** 720 | 721 | **Example** 722 | 723 | ```js 724 | chop("_ABC_"); 725 | //=> 'ABC' 726 | 727 | chop("-ABC-"); 728 | //=> 'ABC' 729 | 730 | chop(" ABC "); 731 | //=> 'ABC' 732 | ``` 733 | 734 | ### [.count](lib/string/count.js#L21) 735 | 736 | Count the number of occurrances of a substring within a string. 737 | 738 | **Params** 739 | 740 | * `string` **{String}** 741 | * `substring` **{String}** 742 | * `returns` **{Number}**: The occurances of `substring` in `string` 743 | 744 | **Example** 745 | 746 | ```js 747 | count("abcabcabc", "a"); 748 | //=> '3' 749 | ``` 750 | 751 | ### [.dashcase](lib/string/dashcase.js#L22) 752 | 753 | dash-case the characters in `string`. This is similar to [slugify], but [slugify] makes the string compatible to be used as a URL slug. 754 | 755 | **Params** 756 | 757 | * `string` **{String}** 758 | * `returns` **{String}** 759 | 760 | **Example** 761 | 762 | ```js 763 | dashcase("a b.c d_e"); 764 | //=> 'a-b-c-d-e' 765 | ``` 766 | 767 | ### [.dotcase](lib/string/dotcase.js#L20) 768 | 769 | dot.case the characters in `string`. 770 | 771 | **Params** 772 | 773 | * `string` **{String}** 774 | * `returns` **{String}** 775 | 776 | **Example** 777 | 778 | ```js 779 | dotcase("a-b-c d_e"); 780 | //=> 'a.b.c.d.e' 781 | ``` 782 | 783 | ### [.ellipsis](lib/string/ellipsis.js#L23) 784 | 785 | Truncate a string to the specified `length`, and append it with an elipsis, `…`. 786 | 787 | **Params** 788 | 789 | * `str` **{String}** 790 | * `length` **{Number}**: The desired length of the returned string. 791 | * `ch` **{String}**: Optionally pass custom characters to append. Default is `…`. 792 | * `returns` **{String}**: The truncated string. 793 | 794 | **Example** 795 | 796 | ```js 797 | ellipsis("foo bar baz", 7); 798 | //=> 'foo bar…' 799 | ``` 800 | 801 | ### [.hyphenate](lib/string/hyphenate.js#L20) 802 | 803 | Replace spaces in a string with hyphens. This 804 | 805 | **Params** 806 | 807 | * `string` **{String}** 808 | * `returns` **{String}** 809 | 810 | **Example** 811 | 812 | ```js 813 | hyphenate("a b c"); 814 | //=> 'a-b-c' 815 | ``` 816 | 817 | ### [.isString](lib/string/isString.js#L20) 818 | 819 | Returns true if the value is a string. 820 | 821 | **Params** 822 | 823 | * `val` **{String}** 824 | * `returns` **{Boolean}**: True if the value is a string. 825 | 826 | **Example** 827 | 828 | ```js 829 | isString('abc'); 830 | //=> 'true' 831 | 832 | isString(null); 833 | //=> 'false' 834 | ``` 835 | 836 | ### [.pascalcase](lib/string/pascalcase.js#L20) 837 | 838 | PascalCase the characters in `string`. 839 | 840 | **Params** 841 | 842 | * `string` **{String}** 843 | * `returns` **{String}** 844 | 845 | **Example** 846 | 847 | ```js 848 | pascalcase("foo bar baz"); 849 | //=> 'FooBarBaz' 850 | ``` 851 | 852 | ### [.pathcase](lib/string/pathcase.js#L20) 853 | 854 | path/case the characters in `string`. 855 | 856 | **Params** 857 | 858 | * `string` **{String}** 859 | * `returns` **{String}** 860 | 861 | **Example** 862 | 863 | ```js 864 | pathcase("a-b-c d_e"); 865 | //=> 'a/b/c/d/e' 866 | ``` 867 | 868 | ### [.replace](lib/string/replace.js#L21) 869 | 870 | Replace occurrences of `a` with `b`. 871 | 872 | **Params** 873 | 874 | * `str` **{String}** 875 | * `a` **{String|RegExp}**: Can be a string or regexp. 876 | * `b` **{String}** 877 | * `returns` **{String}** 878 | 879 | **Example** 880 | 881 | ```js 882 | replace("abcabc", /a/, "z"); 883 | //=> 'zbczbc' 884 | ``` 885 | 886 | ### [.reverse](lib/string/reverse.js#L19) 887 | 888 | Reverse the characters in a string. 889 | 890 | **Params** 891 | 892 | * `str` **{String}**: The string to reverse. 893 | * `returns` **{String}** 894 | 895 | **Example** 896 | 897 | ```js 898 | reverse("abc"); 899 | //=> 'cba' 900 | ``` 901 | 902 | ### [.rightAlign](lib/string/rightAlign.js#L21) 903 | 904 | Right align the characters in a string using non-breaking spaces. 905 | 906 | **Params** 907 | 908 | * `str` **{String}**: The string to reverse. 909 | * `returns` **{String}**: Right-aligned string. 910 | 911 | **Example** 912 | 913 | ```js 914 | rightAlign(str); 915 | ``` 916 | 917 | ### [.sentencecase](lib/string/sentencecase.js#L19) 918 | 919 | Sentence-case the characters in `string`. 920 | 921 | **Params** 922 | 923 | * `string` **{String}** 924 | * `returns` **{String}** 925 | 926 | **Example** 927 | 928 | ```js 929 | sentencecase("foo bar baz."); 930 | //=> 'Foo bar baz.' 931 | ``` 932 | 933 | ### [.snakecase](lib/string/snakecase.js#L20) 934 | 935 | snake_case the characters in `string`. 936 | 937 | **Params** 938 | 939 | * `string` **{String}** 940 | * `returns` **{String}** 941 | 942 | **Example** 943 | 944 | ```js 945 | snakecase("a-b-c d_e"); 946 | //=> 'a_b_c_d_e' 947 | ``` 948 | 949 | ### [.truncate](lib/string/truncate.js#L22) 950 | 951 | Truncate a string by removing all HTML tags and limiting the result to the specified `length`. 952 | 953 | **Params** 954 | 955 | * `str` **{String}** 956 | * `length` **{Number}**: The desired length of the returned string. 957 | * `returns` **{String}**: The truncated string. 958 | 959 | **Example** 960 | 961 | ```js 962 | truncate("foo bar baz", 7); 963 | //=> 'foo bar' 964 | ``` 965 | 966 | ### [.wordwrap](lib/string/wordwrap.js#L21) 967 | 968 | Wrap words to a specified width using [word-wrap]. 969 | 970 | **Params** 971 | 972 | * `string` **{String}**: The string with words to wrap. 973 | * `object` **{Options}**: Options to pass to [word-wrap] 974 | * `returns` **{String}**: Formatted string. 975 | 976 | **Example** 977 | 978 | ```js 979 | wordwrap("a b c d e f", {width: 5, newline: '
'}); 980 | //=> ' a b c
d e f' 981 | ``` 982 | 983 | ## Code coverage 984 | 985 | Please help improve code coverage by [adding unit tests](#contributing). 986 | 987 | ``` 988 | -----------------------|----------|----------|----------|----------|----------------| 989 | File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | 990 | -----------------------|----------|----------|----------|----------|----------------| 991 | utils/ | 100 | 100 | 100 | 100 | | 992 | index.js | 100 | 100 | 100 | 100 | | 993 | utils/lib/ | 100 | 100 | 100 | 100 | | 994 | index.js | 100 | 100 | 100 | 100 | | 995 | utils/lib/array/ | 91.75 | 83.33 | 100 | 92.55 | | 996 | after.js | 100 | 75 | 100 | 100 | | 997 | arrayify.js | 100 | 100 | 100 | 100 | | 998 | before.js | 100 | 75 | 100 | 100 | | 999 | compact.js | 100 | 100 | 100 | 100 | | 1000 | difference.js | 100 | 100 | 100 | 100 | | 1001 | each.js | 100 | 100 | 100 | 100 | | 1002 | first.js | 88.89 | 83.33 | 100 | 88.24 | 27,46 | 1003 | flatten.js | 100 | 100 | 100 | 100 | | 1004 | forEach.js | 100 | 100 | 100 | 100 | | 1005 | index.js | 100 | 100 | 100 | 100 | | 1006 | indexOf.js | 76.92 | 70 | 100 | 83.33 | 23,40 | 1007 | isArray.js | 100 | 100 | 100 | 100 | | 1008 | last.js | 88.89 | 83.33 | 100 | 88.24 | 27,46 | 1009 | map.js | 100 | 100 | 100 | 100 | | 1010 | slice.js | 100 | 100 | 100 | 100 | | 1011 | sort.js | 90.91 | 87.5 | 100 | 90.91 | 27 | 1012 | union.js | 100 | 100 | 100 | 100 | | 1013 | unique.js | 100 | 100 | 100 | 100 | | 1014 | utils/lib/collection/ | 55.56 | 0 | 0 | 55.56 | | 1015 | any.js | 100 | 100 | 100 | 100 | | 1016 | contains.js | 42.86 | 0 | 0 | 42.86 | 18,19,21,22 | 1017 | index.js | 100 | 100 | 100 | 100 | | 1018 | utils/lib/fs/ | 68.75 | 100 | 66.67 | 68.75 | | 1019 | index.js | 100 | 100 | 100 | 100 | | 1020 | tryRead.js | 40 | 100 | 0 | 40 | 16,17,19 | 1021 | tryReaddir.js | 80 | 100 | 100 | 80 | 20 | 1022 | tryRequire.js | 80 | 100 | 100 | 80 | 19 | 1023 | utils/lib/function/ | 36.36 | 0 | 0 | 36.36 | | 1024 | identity.js | 50 | 100 | 0 | 50 | 12 | 1025 | index.js | 100 | 100 | 100 | 100 | | 1026 | noop.js | 50 | 100 | 0 | 50 | 13 | 1027 | partialRight.js | 16.67 | 0 | 0 | 16.67 | 26,27,28,29,30 | 1028 | utils/lib/lang/ | 100 | 100 | 100 | 100 | | 1029 | hasValues.js | 100 | 100 | 100 | 100 | | 1030 | index.js | 100 | 100 | 100 | 100 | | 1031 | isEmpty.js | 100 | 100 | 100 | 100 | | 1032 | isObject.js | 100 | 100 | 100 | 100 | | 1033 | isPlainObject.js | 100 | 100 | 100 | 100 | | 1034 | typeOf.js | 100 | 100 | 100 | 100 | | 1035 | utils/lib/math/ | 100 | 100 | 100 | 100 | | 1036 | index.js | 100 | 100 | 100 | 100 | | 1037 | sum.js | 100 | 100 | 100 | 100 | | 1038 | utils/lib/object/ | 62.77 | 46.15 | 17.65 | 61.96 | | 1039 | defaults.js | 100 | 100 | 100 | 100 | | 1040 | extend.js | 100 | 83.33 | 100 | 100 | | 1041 | filter.js | 100 | 100 | 100 | 100 | | 1042 | forIn.js | 100 | 100 | 100 | 100 | | 1043 | forOwn.js | 100 | 100 | 100 | 100 | | 1044 | functions.js | 28.57 | 0 | 0 | 28.57 | 21,23,24,25,29 | 1045 | hasOwn.js | 100 | 100 | 100 | 100 | | 1046 | index.js | 100 | 100 | 100 | 100 | | 1047 | keys.js | 33.33 | 50 | 0 | 33.33 | 16,17,18,20 | 1048 | mapValues.js | 37.5 | 100 | 0 | 37.5 | 18,19,21,22,25 | 1049 | merge.js | 100 | 75 | 100 | 100 | | 1050 | methods.js | 28.57 | 0 | 0 | 28.57 | 16,18,19,20,24 | 1051 | omit.js | 100 | 100 | 100 | 100 | | 1052 | pick.js | 100 | 100 | 100 | 100 | | 1053 | pluck.js | 75 | 100 | 0 | 75 | 17 | 1054 | prop.js | 33.33 | 100 | 0 | 33.33 | 4,5 | 1055 | reduce.js | 100 | 100 | 100 | 100 | | 1056 | result.js | 25 | 0 | 0 | 25 | 6,7,8,10,11,13 | 1057 | some.js | 30 | 0 | 0 | 30 |... 11,12,13,16 | 1058 | utils/lib/string/ | 99.28 | 96.77 | 96 | 99.1 | | 1059 | camelcase.js | 100 | 100 | 100 | 100 | | 1060 | centerAlign.js | 100 | 100 | 100 | 100 | | 1061 | chop.js | 100 | 100 | 100 | 100 | | 1062 | count.js | 100 | 100 | 100 | 100 | | 1063 | dashcase.js | 100 | 100 | 100 | 100 | | 1064 | dotcase.js | 100 | 100 | 100 | 100 | | 1065 | ellipsis.js | 100 | 100 | 100 | 100 | | 1066 | hyphenate.js | 100 | 100 | 100 | 100 | | 1067 | index.js | 100 | 100 | 100 | 100 | | 1068 | isString.js | 100 | 100 | 100 | 100 | | 1069 | pascalcase.js | 100 | 100 | 100 | 100 | | 1070 | pathcase.js | 100 | 100 | 100 | 100 | | 1071 | replace.js | 100 | 100 | 100 | 100 | | 1072 | reverse.js | 100 | 100 | 100 | 100 | | 1073 | rightAlign.js | 100 | 100 | 100 | 100 | | 1074 | sentencecase.js | 100 | 100 | 100 | 100 | | 1075 | slugify.js | 100 | 100 | 100 | 100 | | 1076 | snakecase.js | 100 | 100 | 100 | 100 | | 1077 | toString.js | 50 | 0 | 0 | 50 | 10 | 1078 | truncate.js | 100 | 100 | 100 | 100 | | 1079 | wordwrap.js | 100 | 100 | 100 | 100 | | 1080 | -----------------------|----------|----------|----------|----------|----------------| 1081 | All files | 84.54 | 80.52 | 67.16 | 83.43 | | 1082 | -----------------------|----------|----------|----------|----------|----------------| 1083 | ``` 1084 | 1085 | ## Running tests 1086 | 1087 | Install dev dependencies: 1088 | 1089 | ```sh 1090 | $ npm i -d && npm test 1091 | ``` 1092 | 1093 | ## Contributing 1094 | 1095 | > Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/utils/issues/new). 1096 | 1097 | ### Adding utils 1098 | 1099 | If you want to do a PR to add a util, please read the following first: 1100 | 1101 | * follow the same coding style as the rest of the library, same with code comments 1102 | * add sufficient unit tests 1103 | * Install dev dependencies and [run verb](#running-verb) 1104 | * Look over the README to make sure that verb rendered out the docs with your method and code comments. 1105 | 1106 | **Adding external modules as dependencies** 1107 | 1108 | * External modules will only be considered if they meet the same quality and coding standards as the rest of the library. At minimum this includes documentation, code comments, and unit tests. Benchmarks are also strongly preferred. 1109 | 1110 | ### Updating the docs 1111 | 1112 | Do not edit the readme manually since [verb](https://github.com/verbose/verb)is used to generate documentation. 1113 | 1114 | * API docs: If you see an error in the API documentation, just update the code comments for that method, then [run verb](#running-verb). 1115 | * Everything else, please look over the [.verb.md](./.verb.md) template to see where the error is, then [run verb](#running-verb). 1116 | 1117 | ### Running verb 1118 | 1119 | Install dev dependencies, then run [verb](https://github.com/verbose/verb): 1120 | 1121 | ```js 1122 | $ npm install -d && verb 1123 | ``` 1124 | 1125 | ## About 1126 | 1127 | **Why another utils lib?** 1128 | 1129 | * I'm a node.js developer. I want fast, light, dependable utility functions for node.js projects. 1130 | * Do you really need bloated, everything-but-the-kitchen-sink functions that are guaranteed to work with IE 4, **for your Yeoman generator or gulp plugin**!? Nonsense. 1131 | * The benchmarks that accompany many of the functions in the library show that in some cases, the penalty for using such "kitchen-sink" code is a 2,000-5,000% reduction in speed. Sometimes greater. 1132 | 1133 | **Project goals** 1134 | 1135 | * Fastest implementation of each method, without too much compromise. Covering uncommon cases is fine, but don't go overboard. 1136 | * Clean well-documented, commented code. 1137 | * [When it makes sense](#adding-utils), external libraries are used and exposed instead of writing new code. 1138 | * Focus on node.js usage and projects that are likely to use a number of these utils in one project. If you only need one or two of these in a small project, don't use this. Use small modules that do only one thing. 1139 | 1140 | ## Related projects 1141 | 1142 | > This project depends on these great libraries. If you don't need a full utility belt for your project, any of these can be used by themselves: 1143 | 1144 | * [any](https://www.npmjs.com/package/any): Returns `true` if a value exists in the given string, array or object. | [homepage](https://github.com/jonschlinkert/any) 1145 | * [arr-diff](https://www.npmjs.com/package/arr-diff): Returns an array with only the unique values from the first array, by excluding all… [more](https://www.npmjs.com/package/arr-diff) | [homepage](https://github.com/jonschlinkert/arr-diff) 1146 | * [arr-flatten](https://www.npmjs.com/package/arr-flatten): Recursively flatten an array or arrays. This is the fastest implementation of array flatten. | [homepage](https://github.com/jonschlinkert/arr-flatten) 1147 | * [arr-map](https://www.npmjs.com/package/arr-map): Faster, node.js focused alternative to JavaScript's native array map. | [homepage](https://github.com/jonschlinkert/arr-map) 1148 | * [arr-union](https://www.npmjs.com/package/arr-union): Combines a list of arrays, returning a single array with unique values, using strict equality… [more](https://www.npmjs.com/package/arr-union) | [homepage](https://github.com/jonschlinkert/arr-union) 1149 | * [array-each](https://www.npmjs.com/package/array-each): Loop over each item in an array and call the given function on every element. | [homepage](https://github.com/jonschlinkert/array-each) 1150 | * [array-slice](https://www.npmjs.com/package/array-slice): Array-slice method. Slices `array` from the `start` index up to, but not including, the `end`… [more](https://www.npmjs.com/package/array-slice) | [homepage](https://github.com/jonschlinkert/array-slice) 1151 | * [array-unique](https://www.npmjs.com/package/array-unique): Return an array free of duplicate values. Fastest ES5 implementation. | [homepage](https://github.com/jonschlinkert/array-unique) 1152 | * [center-align](https://www.npmjs.com/package/center-align): Center-align the text in a string. | [homepage](https://github.com/jonschlinkert/center-align) 1153 | * [export-dirs](https://www.npmjs.com/package/export-dirs): Export directories and their files as node.js modules. | [homepage](https://github.com/jonschlinkert/export-dirs) 1154 | * [export-files](https://www.npmjs.com/package/export-files): node.js utility for exporting a directory of files as modules. | [homepage](https://github.com/jonschlinkert/export-files) 1155 | * [for-in](https://www.npmjs.com/package/for-in): Iterate over the own and inherited enumerable properties of an objecte, and return an object… [more](https://www.npmjs.com/package/for-in) | [homepage](https://github.com/jonschlinkert/for-in) 1156 | * [for-own](https://www.npmjs.com/package/for-own): Iterate over the own enumerable properties of an object, and return an object with properties… [more](https://www.npmjs.com/package/for-own) | [homepage](https://github.com/jonschlinkert/for-own) 1157 | * [has-values](https://www.npmjs.com/package/has-values): Returns true if any values exist, false if empty. Works for booleans, functions, numbers, strings,… [more](https://www.npmjs.com/package/has-values) | [homepage](https://github.com/jonschlinkert/has-values) 1158 | * [is-number](https://www.npmjs.com/package/is-number): Returns true if the value is a number. comprehensive tests. | [homepage](https://github.com/jonschlinkert/is-number) 1159 | * [is-plain-object](https://www.npmjs.com/package/is-plain-object): Returns true if an object was created by the `Object` constructor. | [homepage](https://github.com/jonschlinkert/is-plain-object) 1160 | * [kind-of](https://www.npmjs.com/package/kind-of): Get the native type of a value. | [homepage](https://github.com/jonschlinkert/kind-of) 1161 | * [make-iterator](https://www.npmjs.com/package/make-iterator): Convert an argument into a valid iterator. Based on the `.makeIterator()` implementation in mout https://github.com/mout/mout. | [homepage](https://github.com/jonschlinkert/make-iterator) 1162 | * [object.defaults](https://www.npmjs.com/package/object.defaults): Like `extend` but only copies missing properties/values to the target object. | [homepage](https://github.com/jonschlinkert/object.defaults) 1163 | * [object.filter](https://www.npmjs.com/package/object.filter): Create a new object filtered to have only properties for which the callback returns true. | [homepage](https://github.com/jonschlinkert/object.filter) 1164 | * [object.omit](https://www.npmjs.com/package/object.omit): Return a copy of an object excluding the given key, or array of keys. Also… [more](https://www.npmjs.com/package/object.omit) | [homepage](https://github.com/jonschlinkert/object.omit) 1165 | * [object.pick](https://www.npmjs.com/package/object.pick): Returns a filtered copy of an object with only the specified keys, like `pick` from… [more](https://www.npmjs.com/package/object.pick) | [homepage](https://github.com/jonschlinkert/object.pick) 1166 | * [object.reduce](https://www.npmjs.com/package/object.reduce): Reduces an object to a value that is the accumulated result of running each property… [more](https://www.npmjs.com/package/object.reduce) | [homepage](https://github.com/jonschlinkert/object.reduce) 1167 | * [right-align](https://www.npmjs.com/package/right-align): Right-align the text in a string. | [homepage](https://github.com/jonschlinkert/right-align) 1168 | * [striptags](https://www.npmjs.com/package/striptags): PHP strip_tags in Node.js | [homepage](https://github.com/ericnorris/striptags) 1169 | * [word-wrap](https://www.npmjs.com/package/word-wrap): Wrap words to a specified length. | [homepage](https://github.com/jonschlinkert/word-wrap) 1170 | 1171 | ## Author 1172 | 1173 | **Jon Schlinkert** 1174 | 1175 | + [github/jonschlinkert](https://github.com/jonschlinkert) 1176 | + [twitter/jonschlinkert](http://twitter.com/jonschlinkert) 1177 | 1178 | ## License 1179 | 1180 | Copyright © 2015 Jon Schlinkert 1181 | Released under the MIT license. 1182 | 1183 | *** 1184 | 1185 | _This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on September 23, 2015._ -------------------------------------------------------------------------------- /docs/example.md: -------------------------------------------------------------------------------- 1 | # Utils object 2 | 3 | > This is to help visualize how the `utils` object looks 4 | 5 | All utils from all categories are placed on the `_` object. 6 | 7 | ```js 8 | {%= utils_methods("index.js") %} 9 | ``` 10 | -------------------------------------------------------------------------------- /example.md: -------------------------------------------------------------------------------- 1 | # Utils object 2 | 3 | > This is to help visualize how the `utils` object looks 4 | 5 | All utils from all categories are placed on the `_` object. 6 | 7 | ```js 8 | { _: 9 | { wordwrap: [Function: wordwrap], 10 | truncate: [Function: truncate], 11 | toString: [Function: toString], 12 | snakecase: [Function: snakecase], 13 | slugify: [Function: slugify], 14 | sentencecase: [Function: sentencecase], 15 | rightAlign: [Function: rightAlign], 16 | reverse: [Function: reverse], 17 | replace: [Function: replace], 18 | pathcase: [Function: pathcase], 19 | pascalcase: [Function: pascalcase], 20 | isString: [Function: isString], 21 | hyphenate: [Function: hyphenate], 22 | ellipsis: [Function: ellipsis], 23 | dotcase: [Function: dotcase], 24 | dashcase: [Function: dashcase], 25 | count: [Function: count], 26 | chop: [Function: chop], 27 | centerAlign: [Function: centerAlign], 28 | camelcase: [Function: camelcase], 29 | some: [Function: some], 30 | result: [Function: result], 31 | reduce: [Function: reduce], 32 | prop: [Function: prop], 33 | pluck: [Function: pluck], 34 | pick: [Function: pick], 35 | omit: [Function: omit], 36 | methods: [Function: methods], 37 | merge: [Function: merge], 38 | mapValues: [Function: mapValues], 39 | keys: { [Function: keys] shim: [Function: shim] }, 40 | hasOwn: [Function: hasOwn], 41 | functions: [Function: functions], 42 | forOwn: [Function: forOwn], 43 | forIn: [Function: forIn], 44 | filter: [Function: filter], 45 | extend: [Function: extend], 46 | defaults: [Function: defaults], 47 | sum: [Function: sum_], 48 | typeOf: [Function: kindOf], 49 | isPlainObject: [Function: isPlainObject], 50 | isObject: [Function: isObject], 51 | isEmpty: [Function: isEmpty], 52 | hasValues: [Function: hasValue], 53 | partialRight: [Function: partialRight], 54 | noop: [Function: noop], 55 | identity: [Function: identity], 56 | tryRequire: [Function: tryRequire], 57 | tryReaddir: [Function: tryReaddir], 58 | tryRead: [Function: tryRead], 59 | contains: [Function: contains], 60 | any: [Function: any], 61 | unique: [Function: unique_], 62 | union: [Function: union_], 63 | sort: [Function: sort], 64 | slice: [Function: slice], 65 | map: [Function: map], 66 | last: [Function: last_], 67 | isArray: [Function: isArray], 68 | indexOf: [Function: indexOf], 69 | forEach: [Function: each], 70 | flatten: [Function: flatten], 71 | first: [Function: first], 72 | each: [Function: each], 73 | difference: [Function: difference_], 74 | compact: [Function: compact], 75 | before: [Function: before], 76 | arrayify: [Function: arrayify], 77 | after: [Function: after_] }, 78 | string: 79 | { wordwrap: [Getter], 80 | truncate: [Getter], 81 | toString: [Getter], 82 | snakecase: [Getter], 83 | slugify: [Getter], 84 | sentencecase: [Getter], 85 | rightAlign: [Getter], 86 | reverse: [Getter], 87 | replace: [Getter], 88 | pathcase: [Getter], 89 | pascalcase: [Getter], 90 | isString: [Getter], 91 | hyphenate: [Getter], 92 | ellipsis: [Getter], 93 | dotcase: [Getter], 94 | dashcase: [Getter], 95 | count: [Getter], 96 | chop: [Getter], 97 | centerAlign: [Getter], 98 | camelcase: [Getter] }, 99 | object: 100 | { some: [Getter], 101 | result: [Getter], 102 | reduce: [Getter], 103 | prop: [Getter], 104 | pluck: [Getter], 105 | pick: [Getter], 106 | omit: [Getter], 107 | methods: [Getter], 108 | merge: [Getter], 109 | mapValues: [Getter], 110 | keys: [Getter], 111 | hasOwn: [Getter], 112 | functions: [Getter], 113 | forOwn: [Getter], 114 | forIn: [Getter], 115 | filter: [Getter], 116 | extend: [Getter], 117 | defaults: [Getter] }, 118 | math: { sum: [Getter] }, 119 | lang: 120 | { typeOf: [Getter], 121 | isPlainObject: [Getter], 122 | isObject: [Getter], 123 | isEmpty: [Getter], 124 | hasValues: [Getter] }, 125 | function: { partialRight: [Getter], noop: [Getter], identity: [Getter] }, 126 | fs: { tryRequire: [Getter], tryReaddir: [Getter], tryRead: [Getter] }, 127 | collection: { contains: [Getter], any: [Getter] }, 128 | array: 129 | { unique: [Getter], 130 | union: [Getter], 131 | sort: [Getter], 132 | slice: [Getter], 133 | map: [Getter], 134 | last: [Getter], 135 | isArray: [Getter], 136 | indexOf: [Getter], 137 | forEach: [Getter], 138 | flatten: [Getter], 139 | first: [Getter], 140 | each: [Getter], 141 | difference: [Getter], 142 | compact: [Getter], 143 | before: [Getter], 144 | arrayify: [Getter], 145 | after: [Getter] } } 146 | ``` 147 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var stylish = require('jshint-stylish'); 4 | var istanbul = require('gulp-istanbul'); 5 | var jshint = require('gulp-jshint'); 6 | var mocha = require('gulp-mocha'); 7 | var gulp = require('gulp'); 8 | 9 | var lint = ['index.js', 'lib/**/*.js']; 10 | 11 | gulp.task('lint', function () { 12 | return gulp.src(lint) 13 | .pipe(jshint()) 14 | .pipe(jshint.reporter(stylish)); 15 | }); 16 | 17 | gulp.task('coverage', function () { 18 | return gulp.src(lint) 19 | .pipe(istanbul()) 20 | .pipe(istanbul.hookRequire()); 21 | }); 22 | 23 | gulp.task('test', ['coverage'], function () { 24 | return gulp.src('test/*.js') 25 | .pipe(mocha({reporter: 'spec'})) 26 | .pipe(istanbul.writeReports({ 27 | reporters: [ 'text' ], 28 | reportOpts: {dir: 'coverage', file: 'summary.txt'} 29 | })) 30 | }); 31 | 32 | gulp.task('default', ['lint', 'test']); 33 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * utils 3 | * 4 | * Copyright (c) 2014 Jon Schlinkert. 5 | * Licensed under the MIT license. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | module.exports = require('./lib'); 11 | -------------------------------------------------------------------------------- /lib/array/after.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Returns all of the items in an array after the specified index. 5 | * 6 | * ```js 7 | * after(['a', 'b', 'c'], 1) 8 | * //=> ['c'] 9 | * ``` 10 | * 11 | * @name .after 12 | * @param {Array} `array` Collection 13 | * @param {Number} `n` Starting index (number of items to exclude) 14 | * @return {Array} Array exluding `n` items. 15 | * @crosslink before 16 | * @api public 17 | */ 18 | 19 | module.exports = function after_(arr, n) { 20 | if (!Array.isArray(arr)) { 21 | throw new TypeError('utils#array.after() expects an array.'); 22 | } 23 | return arr ? arr.slice(n) : null; 24 | }; 25 | -------------------------------------------------------------------------------- /lib/array/arrayify.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Cast the give `value` to an array. 5 | * 6 | * ```js 7 | * arrayify('abc') 8 | * //=> ['abc'] 9 | * 10 | * arrayify(['abc']) 11 | * //=> ['abc'] 12 | * ``` 13 | * 14 | * @name .arrayify 15 | * @param {*} `val` 16 | * @return {Array} 17 | * @api public 18 | */ 19 | 20 | module.exports = function arrayify(val) { 21 | return !Array.isArray(val) ? [val] : val; 22 | }; 23 | -------------------------------------------------------------------------------- /lib/array/before.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Returns all of the items in an array up to the specified number 5 | * Opposite of `<%= after() %`. 6 | * 7 | * ```js 8 | * before(['a', 'b', 'c'], 2) 9 | * //=> ['a', 'b'] 10 | * ``` 11 | * 12 | * @name .before 13 | * @param {Array} `array` 14 | * @param {Number} `n` 15 | * @return {Array} Array excluding items after the given number. 16 | * @crosslink after 17 | * @api public 18 | */ 19 | 20 | module.exports = function before(arr, n) { 21 | if (!Array.isArray(arr)) { 22 | throw new TypeError('utils#array.before() expects an array.'); 23 | } 24 | return arr ? arr.slice(0, -n) : null; 25 | }; 26 | -------------------------------------------------------------------------------- /lib/array/compact.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Remove all falsey values from an array. 5 | * 6 | * ```js 7 | * compact([null, a, undefined, 0, false, b, c, '']); 8 | * //=> [a, b, c] 9 | * ``` 10 | * 11 | * @name .compact 12 | * @param {Array} `arr` 13 | * @return {Array} 14 | * @api public 15 | */ 16 | 17 | module.exports = function compact(arr) { 18 | if (!Array.isArray(arr)) { 19 | throw new TypeError('utils#array.compact() expects an array.'); 20 | } 21 | return arr.filter(Boolean); 22 | }; 23 | -------------------------------------------------------------------------------- /lib/array/difference.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var diff = require('arr-diff'); 4 | 5 | /** 6 | * Return the difference between the first array and 7 | * additional arrays. 8 | * 9 | * ```js 10 | * var a = ['a', 'b', 'c', 'd']; 11 | * var b = ['b', 'c']; 12 | * 13 | * diff(a, b); 14 | * //=> ['a', 'd'] 15 | * ``` 16 | * 17 | * @name .difference 18 | * @param {Array} `a` 19 | * @param {Array} `b` 20 | * @return {Array} 21 | * @api public 22 | */ 23 | 24 | module.exports = function difference_(arr) { 25 | if (!Array.isArray(arr)) { 26 | throw new TypeError('utils#array.difference() expects an array.'); 27 | } 28 | return diff.apply(diff, arguments); 29 | }; 30 | -------------------------------------------------------------------------------- /lib/array/each.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Loop over each item in an array and call the given function on every element. 5 | * 6 | * ```js 7 | * each(['a', 'b', 'c'], function (ele) { 8 | * return ele + ele; 9 | * }); 10 | * //=> ['aa', 'bb', 'cc'] 11 | * 12 | * each(['a', 'b', 'c'], function (ele, i) { 13 | * return i + ele; 14 | * }); 15 | * //=> ['0a', '1b', '2c'] 16 | * ``` 17 | * 18 | * @name .each 19 | * @alias .forEach 20 | * @param {Array} `array` 21 | * @param {Function} `fn` 22 | * @param {Object} `thisArg` Optionally pass a `thisArg` to be used as the context in which to call the function. 23 | * @return {Array} 24 | * @api public 25 | */ 26 | 27 | module.exports = require('array-each'); 28 | -------------------------------------------------------------------------------- /lib/array/first.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isNumber = require('is-number'); 4 | 5 | /** 6 | * Returns the first item, or first `n` items of an array. 7 | * 8 | * ```js 9 | * first(['a', 'b', 'c', 'd', 'e'], 2) 10 | * //=> ['a', 'b'] 11 | * ``` 12 | * 13 | * @name .first 14 | * @param {Array} `array` 15 | * @param {Number} `n` Number of items to return, starting at `0`. 16 | * @return {Array} 17 | * @api public 18 | */ 19 | 20 | module.exports = function first(arr, fn) { 21 | if (!Array.isArray(arr)) { 22 | throw new TypeError('utils#array.first() expects an array.'); 23 | } 24 | 25 | var len = arr.length; 26 | if (len === 0) { 27 | return []; 28 | } 29 | 30 | if (!fn) return arr[0]; 31 | 32 | if (isNumber(fn)) { 33 | return arr.slice(0, fn); 34 | } 35 | 36 | if (typeof fn === 'function') { 37 | var val, i = 0; 38 | 39 | while (len--) { 40 | val = arr[i++]; 41 | if (fn(val, i, arr)) { 42 | return val; 43 | } 44 | } 45 | } 46 | return []; 47 | }; 48 | -------------------------------------------------------------------------------- /lib/array/flatten.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Recursively flatten an array or arrays. Uses the fastest 5 | * implementation of array flatten for node.js 6 | * 7 | * ```js 8 | * flatten(['a', ['b', ['c']], 'd', ['e']]); 9 | * //=> ['a', 'b', 'c', 'd', 'e'] 10 | * ``` 11 | * 12 | * @name .flatten 13 | * @param {Array} `array` 14 | * @return {Array} Flattened array 15 | * @api public 16 | */ 17 | 18 | module.exports = require('arr-flatten'); 19 | -------------------------------------------------------------------------------- /lib/array/forEach.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Loop over each item in an array and call the given function on every element. 5 | * 6 | * ```js 7 | * forEach(['a', 'b', 'c'], function (ele) { 8 | * return ele + ele; 9 | * }); 10 | * //=> ['aa', 'bb', 'cc'] 11 | * 12 | * forEach(['a', 'b', 'c'], function (ele, i) { 13 | * return i + ele; 14 | * }); 15 | * //=> ['0a', '1b', '2c'] 16 | * ``` 17 | * 18 | * @name .forEach 19 | * @alias .each 20 | * @param {Array} `array` 21 | * @param {Function} `fn` 22 | * @param {Object} `thisArg` Optionally pass a `thisArg` to be used as the context in which to call the function. 23 | * @return {Array} 24 | * @api public 25 | */ 26 | 27 | module.exports = require('./each'); 28 | -------------------------------------------------------------------------------- /lib/array/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('export-files')(__dirname); 4 | -------------------------------------------------------------------------------- /lib/array/indexOf.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Fast array `.index()`. 5 | * 6 | * ```js 7 | * indexOf(['a', 'b'], 'b'); 8 | * //=> 1 9 | * 10 | * indexOf(['a', 'b', 'a', 'b'], 'b', 2); 11 | * //=> 3 12 | * ``` 13 | * 14 | * @name .indexOf 15 | * @param {Array} `arr` Array to iterate over 16 | * @param {String} `ele` The element to find. 17 | * @param {Array} `start` Starting index. 18 | * @return {Number} Returns the index of `ele` or `-1` 19 | */ 20 | 21 | module.exports = function indexOf(arr, ele, start) { 22 | if (!Array.isArray(arr)) { 23 | throw new TypeError('utils#array.indexOf() expects an array.'); 24 | } 25 | 26 | if (typeof ele === 'undefined') return -1; 27 | start = start || 0; 28 | 29 | var len = arr.length; 30 | var i = start < 0 31 | ? len + start 32 | : start; 33 | 34 | while (i < len) { 35 | if (arr[i] === ele) { 36 | return i; 37 | } 38 | i++; 39 | } 40 | return -1; 41 | }; 42 | -------------------------------------------------------------------------------- /lib/array/isArray.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Returns true if the given `value` is an array. 5 | * 6 | * ```js 7 | * isArray(1); 8 | * //=> 'false' 9 | * 10 | * isArray([1]); 11 | * //=> 'true' 12 | * ``` 13 | * 14 | * @name .isArray 15 | * @param {Array} `value` Value to test. 16 | * @api public 17 | */ 18 | 19 | module.exports = function isArray(value) { 20 | return Array.isArray(value); 21 | }; 22 | -------------------------------------------------------------------------------- /lib/array/last.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isNumber = require('is-number'); 4 | 5 | /** 6 | * Returns the last item, or last `n` items of an array. 7 | * 8 | * ```js 9 | * last(['a', 'b', 'c', 'd', 'e'], 2) 10 | * //=> ['d', 'e'] 11 | * ``` 12 | * 13 | * @name .last 14 | * @param {Array} `array` 15 | * @param {Number} `n` Number of items to return, starting with the last item. 16 | * @return {Array} 17 | * @api public 18 | */ 19 | 20 | module.exports = function last_(arr, fn) { 21 | if (!Array.isArray(arr)) { 22 | throw new TypeError('utils#array.last() expects an array.'); 23 | } 24 | 25 | var len = arr.length; 26 | if (len === 0) { 27 | return []; 28 | } 29 | 30 | if (!fn) return arr[arr.length - 1]; 31 | 32 | if (isNumber(fn)) { 33 | return arr.slice(-fn); 34 | } 35 | 36 | if (typeof fn === 'function') { 37 | var val, i = 0; 38 | 39 | while (len--) { 40 | val = arr[i++]; 41 | if (fn(val, i, arr)) { 42 | return val; 43 | } 44 | } 45 | } 46 | return []; 47 | }; 48 | -------------------------------------------------------------------------------- /lib/array/map.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Returns a new array with the results of calling the given function 5 | * on every element in the array. This is a faster, node.js focused 6 | * alternative to JavaScript's native array map. 7 | * 8 | * ```js 9 | * map(['a', 'b', 'c'], function (ele) { 10 | * return ele + ele; 11 | * }); 12 | * //=> ['aa', 'bb', 'cc'] 13 | * 14 | * map(['a', 'b', 'c'], function (ele, i) { 15 | * return i + ele; 16 | * }); 17 | * //=> ['0a', '1b', '2c'] 18 | * ``` 19 | * 20 | * @name .map 21 | * @param {Array} `array` 22 | * @param {Function} `fn` 23 | * @return {Array} 24 | * @api public 25 | */ 26 | 27 | module.exports = require('arr-map'); 28 | -------------------------------------------------------------------------------- /lib/array/slice.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Alternative to JavaScript's native array-slice method. Slices `array` 5 | * from the `start` index up to but not including the `end` index. 6 | * 7 | * ```js 8 | * var arr = ['a', 'b', 'd', 'e', 'f', 'g', 'h', 'i', 'j']; 9 | * 10 | * slice(arr, 3, 6); 11 | * //=> ['e', 'f', 'g'] 12 | * ``` 13 | * 14 | * @name .slice 15 | * @param {Array} `array` the array to slice. 16 | * @param {Number} `start` Optionally define the starting index. 17 | * @param {Number} `end` Optionally define the ending index. 18 | * @api public 19 | */ 20 | 21 | module.exports = require('array-slice'); 22 | -------------------------------------------------------------------------------- /lib/array/sort.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Sort the given `array`. If an array of objects is passed, 5 | * you may optionally pass a `key` to sort on as the second 6 | * argument. You may alternatively pass a sorting function as 7 | * the second argument. 8 | * 9 | * ```js 10 | * sort(['b', 'a', 'c']) 11 | * //=> ['a', 'b', 'c'] 12 | * 13 | * sort([{a: 'c'}, {a: 'a'}], 'a') 14 | * //=> [{a: 'a'}, {a: 'c'}] 15 | * ``` 16 | * 17 | * @name .sort 18 | * @param {Array} `array` the array to sort. 19 | * @param {String|Function} `key` The object key to sort by, or sorting function. 20 | */ 21 | 22 | module.exports = function sort(arr, key) { 23 | if (!Array.isArray(arr)) { 24 | throw new TypeError('utils#array.sort() expects an array.'); 25 | } 26 | if (arr.length === 0) { 27 | return []; 28 | } 29 | if (typeof key === 'function') { 30 | return arr.sort(key); 31 | } 32 | if (typeof key !== 'string') { 33 | return arr.sort(); 34 | } 35 | return arr.sort(function(a, b) { 36 | var aValue = a[key]; 37 | var bValue = b[key]; 38 | return aValue > bValue ? 1 : (aValue < bValue ? -1 : 0); 39 | }); 40 | }; 41 | -------------------------------------------------------------------------------- /lib/array/union.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var union = require('arr-union'); 4 | 5 | /** 6 | * Return an array free of duplicate values. Fastest ES5 implementation. 7 | * 8 | * ```js 9 | * union(['a', 'b', 'c', 'c']); 10 | * //=> ['a', 'b', 'c'] 11 | * ``` 12 | * 13 | * @name .union 14 | * @param {Array} `array` The array to uniquify 15 | * @return {Array} With all union values. 16 | * @api public 17 | */ 18 | 19 | module.exports = function union_(arr) { 20 | if (!Array.isArray(arr)) { 21 | throw new TypeError('utils#array.union() expects an array.'); 22 | } 23 | return union.apply(union, arguments); 24 | }; 25 | -------------------------------------------------------------------------------- /lib/array/unique.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var uniq = require('array-unique'); 4 | 5 | /** 6 | * Return an array free of duplicate values. Fastest ES5 implementation. 7 | * 8 | * ```js 9 | * unique(['a', 'b', 'c', 'c']); 10 | * //=> ['a', 'b', 'c'] 11 | * ``` 12 | * 13 | * @name .unique 14 | * @param {Array} `array` The array to uniquify 15 | * @return {Array} With all unique values. 16 | * @api public 17 | */ 18 | 19 | module.exports = function unique_(arr) { 20 | if (!Array.isArray(arr)) { 21 | throw new TypeError('utils#array.unique() expects an array.'); 22 | } 23 | return uniq.apply(uniq, arguments); 24 | }; 25 | -------------------------------------------------------------------------------- /lib/collection/any.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Returns `true` if `value` exists in the given string, array 5 | * or object. See [any] for documentation. 6 | * 7 | * @name .any 8 | * @param {*} `value` 9 | * @param {*} `target` 10 | * @param {Object} `options` 11 | * @api public 12 | */ 13 | 14 | module.exports = require('any'); 15 | -------------------------------------------------------------------------------- /lib/collection/contains.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var indexOf = require('../array/indexOf'); 4 | var some = require('../object/some'); 5 | 6 | /** 7 | * Return true if `collection` contains `value` 8 | * 9 | * @name .contains 10 | * @param {Array|Object} `collection` 11 | * @param {*} `string` 12 | * @todo make this more flexible 13 | * @return {Boolean} 14 | * @api public 15 | */ 16 | 17 | module.exports = function contains(collection, val) { 18 | if (Array.isArray(collection)) { 19 | return indexOf(collection, val) !== -1; 20 | } 21 | return some(collection, function (v) { 22 | return (v === val); 23 | }); 24 | }; 25 | -------------------------------------------------------------------------------- /lib/collection/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('export-files')(__dirname); 4 | -------------------------------------------------------------------------------- /lib/fs/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('export-files')(__dirname); 4 | -------------------------------------------------------------------------------- /lib/fs/tryRead.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('fs'); 4 | 5 | /** 6 | * Try to read the given `filepath`, fail silently and return `null` 7 | * when a file doesn't exist. Slightly faster than using `fs.existsSync`. 8 | * 9 | * @name .tryRead 10 | * @param {String} `fp` Path of the file to read. 11 | * @return {String|Null} the `utf8` contents string, or `null` if an error is thrown. 12 | * @api public 13 | */ 14 | 15 | module.exports = function tryRead(fp) { 16 | try { 17 | return fs.readFileSync(fp, 'utf8'); 18 | } catch (err) {} 19 | return null; 20 | }; 21 | -------------------------------------------------------------------------------- /lib/fs/tryReaddir.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('fs'); 4 | 5 | /** 6 | * Try to read the given `directory`. Wraps `fs.readdirSync()` with 7 | * a try/catch, so it fails silently instead of throwing when the 8 | * directory doesn't exist. 9 | * 10 | * @name .tryReaddir 11 | * @param {String} `dir` Starting directory 12 | * @return {Array} Array of files. 13 | * @api public 14 | */ 15 | 16 | module.exports = function tryReaddir(dir) { 17 | try { 18 | return fs.readdirSync(dir); 19 | } catch (err) {} 20 | return []; 21 | }; 22 | -------------------------------------------------------------------------------- /lib/fs/tryRequire.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | 5 | /** 6 | * Try to require the given file, returning `null` if not successful 7 | * instead of throwing an error. 8 | * 9 | * @name .tryRequire 10 | * @param {String} `fp` File path of the file to require 11 | * @return {*} Returns the module function/object, or `null` if not found. 12 | * @api public 13 | */ 14 | 15 | module.exports = function tryRequire(fp) { 16 | try { 17 | return require(path.resolve(fp)); 18 | } catch (err) {} 19 | return null; 20 | }; 21 | -------------------------------------------------------------------------------- /lib/function/identity.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Returns the first argument passed to the function. 5 | * 6 | * @name .identity 7 | * @return {*} 8 | * @api public 9 | */ 10 | 11 | module.exports = function identity(val) { 12 | return val; 13 | }; 14 | -------------------------------------------------------------------------------- /lib/function/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('export-files')(__dirname); 4 | -------------------------------------------------------------------------------- /lib/function/noop.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * A "no-operation" function. Returns `undefined` regardless 5 | * of the arguments it receives. 6 | * 7 | * @name .noop 8 | * @return {undefined} 9 | * @api public 10 | */ 11 | 12 | module.exports = function noop() { 13 | return; 14 | }; 15 | -------------------------------------------------------------------------------- /lib/function/partialRight.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Partially applies arguments that will be appended to those provided 5 | * to the returned function. 6 | * 7 | * ```js 8 | * function fullname(first, last) { 9 | * return first + ' ' + last; 10 | * } 11 | * 12 | * var name = partialRight(fn, 'Woodward'); 13 | * name('Brian'); 14 | * //=> 'Brian Woodward' 15 | * ``` 16 | * 17 | * @name .partialRight 18 | * @param {Object} `ctx` Optionally supply an invocation context for the returned function. 19 | * @param {Function} `fn` The function to which arguments should be partially applied. 20 | * @param {...*} `arguments` List of arguments to be partially applied. 21 | * @return {Function} Returns a function with partially applied arguments. 22 | * @api public 23 | */ 24 | 25 | module.exports = function partialRight(ctx, fn/*, arguments*/) { 26 | var args = [].slice.call(arguments, 1); 27 | ctx = typeof ctx !== 'function' ? args.shift() : fn; 28 | return function () { 29 | var args = [].slice.call(arguments).concat(args); 30 | return fn.apply(ctx, args); 31 | }; 32 | }; 33 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('export-dirs')(__dirname); 4 | -------------------------------------------------------------------------------- /lib/lang/hasValues.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Returns true if any value exists, false if empty. Works for booleans, 5 | * functions, numbers, strings, nulls, objects and arrays. 6 | * 7 | * ```js 8 | * hasValues('a'); 9 | * //=> true 10 | * 11 | * hasValues(''); 12 | * //=> false 13 | * 14 | * hasValues(1); 15 | * //=> true 16 | * 17 | * hasValues({a: 'a'}}); 18 | * //=> true 19 | * 20 | * hasValues({}}); 21 | * //=> false 22 | * 23 | * hasValues(['a']); 24 | * //=> true 25 | * ``` 26 | * 27 | * @name .hasValues 28 | * @param {Object} `object` The object to check for `value` 29 | * @param {*} `value` the value to look for 30 | * @return {Boolean} True if any values exists. 31 | * @api public 32 | */ 33 | 34 | module.exports = require('has-values'); 35 | -------------------------------------------------------------------------------- /lib/lang/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('export-files')(__dirname); 4 | -------------------------------------------------------------------------------- /lib/lang/isEmpty.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var hasValues = require('has-values'); 4 | 5 | /** 6 | * Returns true if the given value is empty, false if any value exists. Works for booleans, 7 | * functions, numbers, strings, nulls, objects and arrays. 8 | * 9 | * ```js 10 | * isEmpty('a'); 11 | * //=> false 12 | * 13 | * isEmpty(''); 14 | * //=> true 15 | * 16 | * isEmpty(1); 17 | * //=> false 18 | * 19 | * isEmpty({a: 'a'}); 20 | * //=> false 21 | * 22 | * isEmpty({}); 23 | * //=> true 24 | * 25 | * isEmpty(['a']); 26 | * //=> false 27 | * ``` 28 | * 29 | * @name .isEmpty 30 | * @crosslink hasValues 31 | * @param {Object} `object` The object to check for `value` 32 | * @param {*} `value` the value to look for 33 | * @return {Boolean} False if any values exists. 34 | * @api public 35 | */ 36 | 37 | module.exports = function isEmpty(val) { 38 | return !hasValues(val); 39 | }; 40 | -------------------------------------------------------------------------------- /lib/lang/isObject.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var typeOf = require('./typeOf'); 4 | 5 | /** 6 | * Return true if the given `value` is an object with keys. 7 | * 8 | * ```js 9 | * isObject(['a', 'b', 'c']) 10 | * //=> 'false' 11 | * 12 | * isObject({a: 'b'}) 13 | * //=> 'true' 14 | * ``` 15 | * 16 | * @name .isObject 17 | * @param {Object} `value` The value to check. 18 | * @return {Boolean} 19 | * @api public 20 | */ 21 | 22 | module.exports = function isObject(val) { 23 | return typeOf(val) === 'object'; 24 | }; 25 | -------------------------------------------------------------------------------- /lib/lang/isPlainObject.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Return true if the given `value` is an object with keys. 5 | * 6 | * ```js 7 | * isPlainObject(Object.create({})); 8 | * //=> true 9 | * isPlainObject(Object.create(Object.prototype)); 10 | * //=> true 11 | * isPlainObject({foo: 'bar'}); 12 | * //=> true 13 | * isPlainObject({}); 14 | * //=> true 15 | * ``` 16 | * 17 | * @name .isPlainObject 18 | * @param {Object} `value` The value to check. 19 | * @return {Boolean} 20 | * @api public 21 | */ 22 | 23 | module.exports = require('is-plain-object'); 24 | -------------------------------------------------------------------------------- /lib/lang/typeOf.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('kind-of'); 4 | -------------------------------------------------------------------------------- /lib/math/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('export-files')(__dirname); 4 | -------------------------------------------------------------------------------- /lib/math/sum.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var flatten = require('arr-flatten'); 4 | var isNumber = require('is-number'); 5 | 6 | /** 7 | * Returns the sum of all numbers in the given array. 8 | * 9 | * ```js 10 | * sum([1, 2, 3, 4, 5]) 11 | * //=> '15' 12 | * ``` 13 | * 14 | * @name .sum 15 | * @param {Array} `array` Array of numbers to add up. 16 | * @return {Number} 17 | * @api public 18 | */ 19 | 20 | module.exports = function sum_() { 21 | var args = flatten([].concat.apply([], arguments)); 22 | var i = args.length, sum = 0; 23 | while (i--) { 24 | if (!isNumber(args[i])) { 25 | continue; 26 | } 27 | sum += (+args[i]); 28 | } 29 | return sum; 30 | }; 31 | -------------------------------------------------------------------------------- /lib/object/defaults.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Extend `object` with properties of other `objects` 5 | * 6 | * @name .defaults 7 | * @param {Object} `object` The target object. Pass an empty object to shallow clone. 8 | * @param {Object} `objects` 9 | * @return {Object} 10 | * @api public 11 | */ 12 | 13 | module.exports = require('object.defaults'); 14 | -------------------------------------------------------------------------------- /lib/object/extend.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var hasOwn = require('./hasOwn'); 4 | var isPlainObject = require('../lang/isPlainObject'); 5 | 6 | /** 7 | * Extend `o` with properties of other `objects`. 8 | * 9 | * @name .extend 10 | * @param {Object} `o` The target object. Pass an empty object to shallow clone. 11 | * @param {Object} `objects` 12 | * @return {Object} 13 | * @api public 14 | */ 15 | 16 | module.exports = function extend(o) { 17 | if (!isPlainObject(o)) { return {}; } 18 | var args = arguments; 19 | var len = args.length - 1; 20 | 21 | for (var i = 0; i < len; i++) { 22 | var obj = args[i + 1]; 23 | 24 | if (isPlainObject(obj)) { 25 | for (var key in obj) { 26 | if (hasOwn(obj, key)) { 27 | o[key] = obj[key]; 28 | } 29 | } 30 | } 31 | } 32 | return o; 33 | }; 34 | -------------------------------------------------------------------------------- /lib/object/filter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('object.filter'); 4 | -------------------------------------------------------------------------------- /lib/object/forIn.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('for-in'); 4 | -------------------------------------------------------------------------------- /lib/object/forOwn.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('for-own'); -------------------------------------------------------------------------------- /lib/object/functions.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var forIn = require('for-in'); 4 | 5 | /** 6 | * Returns a copy of the given `obj` filtered to have only enumerable 7 | * properties that have function values. 8 | * 9 | * ```js 10 | * functions({a: 'b', c: function() {}}); 11 | * //=> {c: function() {}} 12 | * ``` 13 | * 14 | * @name .functions 15 | * @param {Object} `obj` 16 | * @return {Object} 17 | * @api public 18 | */ 19 | 20 | module.exports = function functions(obj) { 21 | var res = {}; 22 | 23 | forIn(obj, function (val, key) { 24 | if (typeof val === 'function') { 25 | res[key] = val; 26 | } 27 | }); 28 | 29 | return res; 30 | }; 31 | -------------------------------------------------------------------------------- /lib/object/hasOwn.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Return true if `key` is an own, enumerable property 5 | * of the given `obj`. 6 | * 7 | * ```js 8 | * hasOwn(obj, key); 9 | * ``` 10 | * 11 | * @name .hasOwn 12 | * @param {String} `key` 13 | * @param {Object} `obj` Optionally pass an object to check. 14 | * @return {Boolean} 15 | * @api public 16 | */ 17 | 18 | module.exports = function hasOwn(o, key) { 19 | return {}.hasOwnProperty.call(o, key); 20 | }; 21 | -------------------------------------------------------------------------------- /lib/object/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('export-files')(__dirname); 4 | -------------------------------------------------------------------------------- /lib/object/keys.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var forOwn = require('for-own'); 4 | 5 | /** 6 | * Return an array of keys for the given `obj`. Uses `Object.keys` 7 | * when available, otherwise falls back on `forOwn`. 8 | * 9 | * @name .keys 10 | * @param {Object} `obj` 11 | * @return {Array} Array of keys. 12 | * @api public 13 | */ 14 | 15 | module.exports = Object.keys || function (obj) { 16 | var keys = []; 17 | forOwn(obj, function (val, key) { 18 | keys.push(key); 19 | }); 20 | return keys; 21 | }; 22 | -------------------------------------------------------------------------------- /lib/object/mapValues.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var forOwn = require('./forOwn'); 4 | var iterator = require('make-iterator'); 5 | 6 | /** 7 | * Returns new object where each value is the result of 8 | * calling the a `callback` function. 9 | * 10 | * @param {Object} obj The object to iterate over 11 | * @param {Function} `cb` Callback function 12 | * @param {Object} thisArg Invocation context of `cb` 13 | * @return {Object} 14 | * @api public 15 | */ 16 | 17 | module.exports = function mapValues(obj, cb, thisArg) { 18 | var fn = iterator(cb, thisArg); 19 | var res = {}; 20 | 21 | forOwn(obj, function (val, key, orig) { 22 | res[key] = fn(val, key, orig); 23 | }); 24 | 25 | return res; 26 | }; 27 | -------------------------------------------------------------------------------- /lib/object/merge.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isPlainObject = require('../lang/isPlainObject'); 4 | var hasOwn = require('./hasOwn'); 5 | 6 | /** 7 | * Expose `merge` 8 | */ 9 | 10 | module.exports = merge; 11 | 12 | /** 13 | * Recursively combine the properties of `o` with the 14 | * properties of other `objects`. 15 | * 16 | * @name .merge 17 | * @param {Object} `o` The target object. Pass an empty object to shallow clone. 18 | * @param {Object} `objects` 19 | * @return {Object} 20 | * @api public 21 | */ 22 | 23 | function merge(o) { 24 | if (!isPlainObject(o)) { return {}; } 25 | var args = arguments; 26 | var len = args.length - 1; 27 | 28 | for (var i = 0; i < len; i++) { 29 | var obj = args[i + 1]; 30 | 31 | if (isPlainObject(obj)) { 32 | for (var key in obj) { 33 | if (hasOwn(obj, key)) { 34 | if (isPlainObject(obj[key])) { 35 | o[key] = merge(o[key], obj[key]); 36 | } else { 37 | o[key] = obj[key]; 38 | } 39 | } 40 | } 41 | } 42 | } 43 | return o; 44 | } 45 | -------------------------------------------------------------------------------- /lib/object/methods.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var forIn = require('for-in'); 4 | 5 | /** 6 | * Returns a list of all enumerable properties of `obj` that have function 7 | * values 8 | * 9 | * @name .methods 10 | * @param {Object} `obj` 11 | * @return {Array} 12 | * @api public 13 | */ 14 | 15 | module.exports = function methods(obj) { 16 | var keys = []; 17 | 18 | forIn(obj, function (val, key) { 19 | if (typeof val === 'function') { 20 | keys.push(key); 21 | } 22 | }); 23 | 24 | return keys; 25 | }; 26 | -------------------------------------------------------------------------------- /lib/object/omit.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('object.omit'); -------------------------------------------------------------------------------- /lib/object/pick.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('object.pick'); -------------------------------------------------------------------------------- /lib/object/pluck.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var prop = require('./prop'); 4 | var map = require('./mapValues'); 5 | 6 | /** 7 | * Get the value of `key` from all properties in the given 8 | * `object`. 9 | * 10 | * @param {Object} `object` 11 | * @param {Object} `key` 12 | * @return {Object} 13 | * @api true 14 | */ 15 | 16 | module.exports = function pluck(obj, key) { 17 | return map(obj, prop(key)); 18 | }; 19 | -------------------------------------------------------------------------------- /lib/object/prop.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function prop(name) { 4 | return function (obj) { 5 | return obj[name]; 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /lib/object/reduce.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Reduces an object to a value that is the accumulated 5 | * result of running each property in the object through a callback. 6 | * 7 | * ```js 8 | * var a = {a: 'foo', b: 'bar', c: 'baz'}; 9 | * 10 | * reduce(a, function (acc, value, key, obj) { 11 | * // `acc`- the initial value (or value from the previous callback call), 12 | * // `value`- the of the current property, 13 | * // `key`- the of the current property, and 14 | * // `obj` - original object 15 | * 16 | * acc[key] = value.toUpperCase(); 17 | * return acc; 18 | * }, {}); 19 | * 20 | * //=> {a: 'FOO', b: 'BAR', c: 'BAZ'}; 21 | * ``` 22 | * 23 | * @name .reduce 24 | * @param {Object} `obj` The object to iterate over. 25 | * @param {Function} `iterator` Iterator function 26 | * @param {Object} `initial` Initial value. 27 | * @param {Object} `thisArg` The `this` binding of the iterator function. 28 | * @return {Object} 29 | * @api public 30 | */ 31 | 32 | module.exports = require('object.reduce'); 33 | -------------------------------------------------------------------------------- /lib/object/result.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var typeOf = require('../lang/typeOf'); 4 | 5 | module.exports = function result(o, key) { 6 | var val = o[key]; 7 | if (typeof val === 'undefined') { 8 | return; 9 | } 10 | if (typeOf(val) === 'function') { 11 | return val.call(o); 12 | } 13 | return val; 14 | }; 15 | -------------------------------------------------------------------------------- /lib/object/some.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var forOwn = require('for-own'); 4 | var iterator = require('make-iterator'); 5 | 6 | module.exports = function some(obj, cb, thisArg) { 7 | cb = iterator(cb, thisArg); 8 | var result = false; 9 | 10 | forOwn(obj, function (val, key) { 11 | if (cb(val, key, obj)) { 12 | result = true; 13 | return false; // break 14 | } 15 | }); 16 | return result; 17 | }; 18 | -------------------------------------------------------------------------------- /lib/string/camelcase.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | var chop = require('./chop'); 5 | 6 | /** 7 | * camelCase the characters in `string`. 8 | * 9 | * ```js 10 | * camelcase("foo bar baz"); 11 | * //=> 'fooBarBaz' 12 | * ``` 13 | * 14 | * @name .camelcase 15 | * @param {String} `string` The string to camelcase. 16 | * @return {String} 17 | * @api public 18 | */ 19 | 20 | module.exports = function camelcase(str) { 21 | if (!isString(str)) return ''; 22 | if (str.length === 1) {return str.toLowerCase(); } 23 | var re = /[-_.\W\s]+(\w|$)/g; 24 | return chop(str).replace(re, function (_, ch) { 25 | return ch.toUpperCase(); 26 | }); 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /lib/string/centerAlign.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var alignCenter = require('center-align'); 4 | var isString = require('./isString'); 5 | 6 | /** 7 | * Center align the characters in a string using 8 | * non-breaking spaces. 9 | * 10 | * ```js 11 | * centerAlign("abc"); 12 | * ``` 13 | * 14 | * @name .centerAlign 15 | * @param {String} `str` The string to reverse. 16 | * @return {String} Centered string. 17 | * @related rightAlign 18 | * @api public 19 | */ 20 | 21 | module.exports = function centerAlign(str) { 22 | if (!isString(str)) return ''; 23 | return alignCenter(str, ' '); 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /lib/string/chop.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | 5 | /** 6 | * Like trim, but removes both extraneous whitespace and 7 | * non-word characters from the beginning and end of a string. 8 | * 9 | * ```js 10 | * chop("_ABC_"); 11 | * //=> 'ABC' 12 | * 13 | * chop("-ABC-"); 14 | * //=> 'ABC' 15 | * 16 | * chop(" ABC "); 17 | * //=> 'ABC' 18 | * ``` 19 | * 20 | * @name .chop 21 | * @param {String} `string` The string to chop. 22 | * @return {String} 23 | * @api public 24 | */ 25 | 26 | module.exports = function chop(str) { 27 | if (!isString(str)) return ''; 28 | var re = /^[-_.\W\s]+|[-_.\W\s]+$/g; 29 | return str.trim().replace(re, ''); 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /lib/string/count.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | 5 | /** 6 | * Count the number of occurrances of a substring 7 | * within a string. 8 | * 9 | * ```js 10 | * count("abcabcabc", "a"); 11 | * //=> '3' 12 | * ``` 13 | * 14 | * @name .count 15 | * @param {String} `string` 16 | * @param {String} `substring` 17 | * @return {Number} The occurances of `substring` in `string` 18 | * @api public 19 | */ 20 | 21 | module.exports = function count(str, sub) { 22 | if (!isString(str)) return ''; 23 | return sub ? (str.split(sub).length - 1) : '0'; 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /lib/string/dashcase.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | var chop = require('./chop'); 5 | 6 | /** 7 | * dash-case the characters in `string`. This is similar to [slugify], 8 | * but [slugify] makes the string compatible to be used as a URL slug. 9 | * 10 | * ```js 11 | * dashcase("a b.c d_e"); 12 | * //=> 'a-b-c-d-e' 13 | * ``` 14 | * 15 | * @name .dashcase 16 | * @param {String} `string` 17 | * @return {String} 18 | * @tags dasherize, dashify, hyphenate, case 19 | * @api public 20 | */ 21 | 22 | module.exports = function dashcase(str) { 23 | if (!isString(str)) return ''; 24 | if (str.length === 1) {return str.toLowerCase(); } 25 | var re = /[-_.\W\s]+(\w|$)/g; 26 | return chop(str).replace(re, function (_, ch) { 27 | return '-' + ch; 28 | }); 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /lib/string/dotcase.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | var chop = require('./chop'); 5 | 6 | /** 7 | * dot.case the characters in `string`. 8 | * 9 | * ```js 10 | * dotcase("a-b-c d_e"); 11 | * //=> 'a.b.c.d.e' 12 | * ``` 13 | * 14 | * @name .dotcase 15 | * @param {String} `string` 16 | * @return {String} 17 | * @api public 18 | */ 19 | 20 | module.exports = function dotcase(str) { 21 | if (!isString(str)) return ''; 22 | if (str.length === 1) {return str.toLowerCase(); } 23 | var re = /[-_.\W\s]+(\w|$)/g; 24 | return chop(str).replace(re, function (_, ch) { 25 | return '.' + ch; 26 | }); 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /lib/string/ellipsis.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | var truncate = require('./truncate'); 5 | 6 | /** 7 | * Truncate a string to the specified `length`, and append 8 | * it with an elipsis, `…`. 9 | * 10 | * ```js 11 | * ellipsis("foo bar baz", 7); 12 | * //=> 'foo bar…' 13 | * ``` 14 | * 15 | * @name .ellipsis 16 | * @param {String} `str` 17 | * @param {Number} `length` The desired length of the returned string. 18 | * @param {String} `ch` Optionally pass custom characters to append. Default is `…`. 19 | * @return {String} The truncated string. 20 | * @api public 21 | */ 22 | 23 | module.exports = function ellipsis(str, limit, ch) { 24 | if (!isString(str)) return ''; 25 | return truncate(str, limit) + (ch || '…'); 26 | }; 27 | -------------------------------------------------------------------------------- /lib/string/hyphenate.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | var chop = require('./chop'); 5 | 6 | /** 7 | * Replace spaces in a string with hyphens. This 8 | * 9 | * ```js 10 | * hyphenate("a b c"); 11 | * //=> 'a-b-c' 12 | * ``` 13 | * 14 | * @name .hyphenate 15 | * @param {String} `string` 16 | * @return {String} 17 | * @api public 18 | */ 19 | 20 | module.exports = function hyphenate(str) { 21 | if (!isString(str)) return ''; 22 | return chop(str).split(' ').join('-'); 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /lib/string/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('export-files')(__dirname); 4 | -------------------------------------------------------------------------------- /lib/string/isString.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Returns true if the value is a string. 5 | * 6 | * ```js 7 | * isString('abc'); 8 | * //=> 'true' 9 | * 10 | * isString(null); 11 | * //=> 'false' 12 | * ``` 13 | * 14 | * @name .isString 15 | * @param {String} `val` 16 | * @return {Boolean} True if the value is a string. 17 | * @api public 18 | */ 19 | 20 | module.exports = function isString(str) { 21 | return str && typeof str === 'string'; 22 | }; 23 | -------------------------------------------------------------------------------- /lib/string/pascalcase.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | var camelcase = require('./camelcase'); 5 | 6 | /** 7 | * PascalCase the characters in `string`. 8 | * 9 | * ```js 10 | * pascalcase("foo bar baz"); 11 | * //=> 'FooBarBaz' 12 | * ``` 13 | * 14 | * @name .pascalcase 15 | * @param {String} `string` 16 | * @return {String} 17 | * @api public 18 | */ 19 | 20 | module.exports = function pascalcase(str) { 21 | if (!isString(str)) return ''; 22 | if (str.length === 1) {return str.toUpperCase(); } 23 | str = camelcase(str); 24 | return str[0].toUpperCase() + str.slice(1); 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /lib/string/pathcase.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | var chop = require('./chop'); 5 | 6 | /** 7 | * path/case the characters in `string`. 8 | * 9 | * ```js 10 | * pathcase("a-b-c d_e"); 11 | * //=> 'a/b/c/d/e' 12 | * ``` 13 | * 14 | * @name .pathcase 15 | * @param {String} `string` 16 | * @return {String} 17 | * @api public 18 | */ 19 | 20 | module.exports = function pathcase(str) { 21 | if (!isString(str)) return ''; 22 | if (str.length === 1) {return str.toLowerCase(); } 23 | var re = /[_.-\W\s]+(\w|$)/g; 24 | return chop(str).replace(re, function (_, ch) { 25 | return '/' + ch; 26 | }); 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /lib/string/replace.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | 5 | /** 6 | * Replace occurrences of `a` with `b`. 7 | * 8 | * ```js 9 | * replace("abcabc", /a/, "z"); 10 | * //=> 'zbczbc' 11 | * ``` 12 | * 13 | * @name .replace 14 | * @param {String} `str` 15 | * @param {String|RegExp} `a` Can be a string or regexp. 16 | * @param {String} `b` 17 | * @return {String} 18 | * @api public 19 | */ 20 | 21 | module.exports = function replace(str, a, b) { 22 | if (!isString(str)) return ''; 23 | if (!a) { return str; } 24 | if (!b) { b = ''; } 25 | return str.split(a).join(b); 26 | }; 27 | 28 | -------------------------------------------------------------------------------- /lib/string/reverse.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | 5 | /** 6 | * Reverse the characters in a string. 7 | * 8 | * ```js 9 | * reverse("abc"); 10 | * //=> 'cba' 11 | * ``` 12 | * 13 | * @name .reverse 14 | * @param {String} `str` The string to reverse. 15 | * @return {String} 16 | * @api public 17 | */ 18 | 19 | module.exports = function reverse(str) { 20 | if (!isString(str)) return ''; 21 | return str.split('').reverse().join(''); 22 | }; 23 | -------------------------------------------------------------------------------- /lib/string/rightAlign.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var alignRight = require('right-align'); 4 | var isString = require('./isString'); 5 | 6 | /** 7 | * Right align the characters in a string using 8 | * non-breaking spaces. 9 | * 10 | * ```js 11 | * rightAlign(str); 12 | * ``` 13 | * 14 | * @name .rightAlign 15 | * @param {String} `str` The string to reverse. 16 | * @return {String} Right-aligned string. 17 | * @related centerAlign 18 | * @api public 19 | */ 20 | 21 | module.exports = function rightAlign(str) { 22 | if (!isString(str)) return ''; 23 | return alignRight(str); 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /lib/string/sentencecase.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | 5 | /** 6 | * Sentence-case the characters in `string`. 7 | * 8 | * ```js 9 | * sentencecase("foo bar baz."); 10 | * //=> 'Foo bar baz.' 11 | * ``` 12 | * 13 | * @name .sentencecase 14 | * @param {String} `string` 15 | * @return {String} 16 | * @api public 17 | */ 18 | 19 | module.exports = function sentencecase(str) { 20 | if (!isString(str)) return ''; 21 | if (str.length === 1) {return str.toUpperCase(); } 22 | return str.charAt(0).toUpperCase() + str.slice(1); 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /lib/string/slugify.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | var dashcase = require('./dashcase'); 5 | 6 | /** 7 | * TODO: Need to use a proper slugifier for this. 8 | * I don't want to use `node-slug`, it's way too 9 | * huge for this. PR welcome 10 | * 11 | * ```js 12 | * slugify('This is a post title.'); 13 | * //=> 'this-is-a-post-title' 14 | * ``` 15 | * 16 | * @name .slugify 17 | * @param {String} `string` The string to slugify. 18 | * @return {String} Slug. 19 | * @api draft 20 | */ 21 | 22 | module.exports = function slugify(str) { 23 | if (!isString(str)) return ''; 24 | return dashcase(str); 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /lib/string/snakecase.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | var chop = require('./chop'); 5 | 6 | /** 7 | * snake_case the characters in `string`. 8 | * 9 | * ```js 10 | * snakecase("a-b-c d_e"); 11 | * //=> 'a_b_c_d_e' 12 | * ``` 13 | * 14 | * @name .snakecase 15 | * @param {String} `string` 16 | * @return {String} 17 | * @api public 18 | */ 19 | 20 | module.exports = function snakecase(str) { 21 | if (!isString(str)) return ''; 22 | if (str.length === 1) {return str.toLowerCase(); } 23 | var re = /[-_.\W\s]+(\w|$)/g; 24 | return chop(str).replace(re, function (_, ch) { 25 | return '_' + ch; 26 | }); 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /lib/string/toString.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * If `val` is null or undefined returns an empty string, 5 | * otherwise `val` is cast it to a String. 6 | * 7 | */ 8 | 9 | module.exports = function toString(val) { 10 | return val == null ? '' : val.toString(); 11 | }; 12 | -------------------------------------------------------------------------------- /lib/string/truncate.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var isString = require('./isString'); 4 | var striptags = require('striptags'); 5 | 6 | /** 7 | * Truncate a string by removing all HTML tags and limiting the result 8 | * to the specified `length`. 9 | * 10 | * ```js 11 | * truncate("foo bar baz", 7); 12 | * //=> 'foo bar' 13 | * ``` 14 | * 15 | * @name .truncate 16 | * @param {String} `str` 17 | * @param {Number} `length` The desired length of the returned string. 18 | * @return {String} The truncated string. 19 | * @api public 20 | */ 21 | 22 | module.exports = function truncate(str, length) { 23 | if (!isString(str)) return ''; 24 | return striptags(str).substr(0, length); 25 | }; 26 | -------------------------------------------------------------------------------- /lib/string/wordwrap.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var wrap = require('word-wrap'); 4 | var isString = require('./isString'); 5 | 6 | /** 7 | * Wrap words to a specified width using [word-wrap]. 8 | * 9 | * ```js 10 | * wordwrap("a b c d e f", {width: 5, newline: '
'}); 11 | * //=> ' a b c
d e f' 12 | * ``` 13 | * 14 | * @name .wordwrap 15 | * @param {String} `string` The string with words to wrap. 16 | * @param {Options} `object` Options to pass to [word-wrap] 17 | * @return {String} Formatted string. 18 | * @api public 19 | */ 20 | 21 | module.exports = function wordwrap(str) { 22 | if (!isString(str)) return ''; 23 | return wrap.apply(wrap, arguments); 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "utils", 3 | "description": "Fast, generic JavaScript/node.js utility functions.", 4 | "version": "0.3.1", 5 | "homepage": "https://github.com/jonschlinkert/utils", 6 | "author": "Jon Schlinkert (https://github.com/jonschlinkert)", 7 | "repository": "jonschlinkert/utils", 8 | "bugs": { 9 | "url": "https://github.com/jonschlinkert/utils/issues" 10 | }, 11 | "license": "MIT", 12 | "files": [ 13 | "index.js", 14 | "lib/" 15 | ], 16 | "main": "index.js", 17 | "engines": { 18 | "node": ">=0.10.0" 19 | }, 20 | "scripts": { 21 | "test": "mocha" 22 | }, 23 | "dependencies": { 24 | "any": "^1.0.0", 25 | "arr-diff": "^1.1.0", 26 | "arr-flatten": "^1.0.1", 27 | "arr-map": "^2.0.0", 28 | "arr-union": "^3.0.0", 29 | "array-each": "^0.1.1", 30 | "array-slice": "^0.2.3", 31 | "array-unique": "^0.2.1", 32 | "center-align": "^0.1.1", 33 | "export-dirs": "^0.2.4", 34 | "export-files": "^2.1.0", 35 | "for-in": "^0.1.4", 36 | "for-own": "^0.1.3", 37 | "has-values": "^0.1.3", 38 | "is-number": "^2.0.2", 39 | "is-plain-object": "^2.0.1", 40 | "kind-of": "^2.0.1", 41 | "make-iterator": "^0.2.0", 42 | "object.defaults": "^0.3.0", 43 | "object.filter": "^0.3.0", 44 | "object.omit": "^2.0.0", 45 | "object.pick": "^1.1.1", 46 | "object.reduce": "^0.1.7", 47 | "right-align": "^0.1.3", 48 | "striptags": "^2.0.3", 49 | "word-wrap": "^1.1.0" 50 | }, 51 | "devDependencies": { 52 | "chalk": "^1.1.1", 53 | "gulp": "^3.9.0", 54 | "gulp-istanbul": "^0.10.0", 55 | "gulp-jshint": "^1.11.2", 56 | "gulp-mocha": "^2.1.3", 57 | "jshint-stylish": "^2.0.1", 58 | "mocha": "^2.3.2", 59 | "relative": "^3.0.1", 60 | "should": "^7.1.0", 61 | "through2": "^2.0.0", 62 | "verb": "^0.8.10", 63 | "vinyl": "^0.5.3" 64 | }, 65 | "keywords": [ 66 | "array", 67 | "collection", 68 | "function", 69 | "lang", 70 | "language", 71 | "math", 72 | "object", 73 | "object", 74 | "string", 75 | "util", 76 | "utils" 77 | ], 78 | "verb": { 79 | "deps": { 80 | "ignore": [ 81 | "staging" 82 | ] 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /support/plugins.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var chalk = require('chalk'); 4 | var through = require('through2'); 5 | var relative = require('relative'); 6 | var File = require('vinyl'); 7 | var path = require('path'); 8 | 9 | /** 10 | * Ensure that method names are properly defined. 11 | * Also warns if code comments are missing. 12 | */ 13 | 14 | exports.names = function names(options) { 15 | return through.obj(function (file, enc, cb) { 16 | var str = file.contents.toString(); 17 | 18 | if (str.indexOf('@name') === -1 && file.path.indexOf('index.js') === -1) { 19 | var i = str.indexOf('@param'); 20 | if (i !== -1) { 21 | str = str.substr(0, i) + namify(file.path) + '\n * ' + str.substr(i); 22 | } else { 23 | console.log(chalk.red('code comments missing in: '), relative(file.path)); 24 | } 25 | } 26 | file.contents = new Buffer(str); 27 | this.push(file); 28 | cb(); 29 | }); 30 | }; 31 | 32 | 33 | exports.modularize = function modularize(options) { 34 | var files = {}; 35 | return through.obj(function (file, enc, cb) { 36 | var str = file.contents.toString(); 37 | var methods = str.split('};\n\n/**'); 38 | var len = methods.length; 39 | while (len--) { 40 | var method = '/**' + methods[len] + '};\n\n'; 41 | var match = /^utils\.([\w]+)/gm.exec(method); 42 | 43 | if (!match) cb(); 44 | var res = method.split(match[0]).join('module.exports'); 45 | res = res.split('<%= ').join(''); 46 | res = res.split(' %>').join(';'); 47 | files[match[1]] = res; 48 | } 49 | 50 | cb(); 51 | }, function (cb) { 52 | for (var key in files) { 53 | if (files.hasOwnProperty(key)) { 54 | var file = new File({ 55 | path: key + '.js' 56 | }); 57 | 58 | var str = '\'use strict\';\n\n' + files[key]; 59 | file.contents = new Buffer(str); 60 | this.push(file); 61 | } 62 | } 63 | cb(); 64 | }); 65 | }; 66 | 67 | function namify(fp) { 68 | return '@name .'+ basename(fp); 69 | } 70 | 71 | function basename(fp) { 72 | return path.basename(fp, path.extname(fp)); 73 | } 74 | -------------------------------------------------------------------------------- /test/array.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * utils 3 | * 4 | * Copyright (c) 2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | require('mocha'); 11 | require('should'); 12 | var assert = require('assert'); 13 | var utils = require('../index').array; 14 | 15 | var arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']; 16 | 17 | describe('array utils:', function() { 18 | describe('after', function() { 19 | it('should throw on bad args.', function() { 20 | (function () { 21 | utils.after() 22 | }).should.throw('utils#array.after() expects an array.'); 23 | }); 24 | 25 | it('should return all of the items in an array after the given index.', function() { 26 | utils.after(arr, 5).should.eql(['f', 'g', 'h']); 27 | }); 28 | }); 29 | 30 | describe('indexOf', function() { 31 | it('should return the index of an item', function() { 32 | assert(utils.indexOf(['a', 'b'], 'b') === 1); 33 | assert(utils.indexOf(['a', 'b', 'c'], 'c') === 2); 34 | }); 35 | }); 36 | 37 | describe('arrayify', function() { 38 | it('should coerce a value to an array.', function() { 39 | utils.isArray(utils.arrayify('foo')).should.be.true; 40 | utils.isArray(utils.arrayify(['foo'])).should.be.true; 41 | }); 42 | }); 43 | 44 | describe('before', function() { 45 | it('should throw on bad args.', function() { 46 | (function () { 47 | utils.before() 48 | }).should.throw('utils#array.before() expects an array.'); 49 | }); 50 | 51 | it('should return all of the items in an array before the given index.', function() { 52 | utils.before(arr, 5).should.eql(['a', 'b', 'c']); 53 | }); 54 | }); 55 | 56 | describe('compact', function() { 57 | it('should throw on bad args.', function() { 58 | (function () { 59 | utils.compact() 60 | }).should.throw('utils#array.compact() expects an array.'); 61 | }); 62 | 63 | it('should remove falsey values from an array.', function() { 64 | utils.compact([null, 'a', undefined, 0, false, 'b', 'c', '']).should.eql(['a', 'b', 'c']); 65 | }); 66 | }); 67 | 68 | describe('difference', function() { 69 | it('should throw on bad args.', function() { 70 | (function () { 71 | utils.difference() 72 | }).should.throw('utils#array.difference() expects an array.'); 73 | }); 74 | 75 | it('should return the difference from multiple arrays', function() { 76 | var o = {}; 77 | o.a = ['a', 'b', 'c', 'd']; 78 | o.b = ['b', 'c']; 79 | o.c = ['x', 'y']; 80 | utils.difference(o.a, o.b, o.c).should.eql(['a','d']); 81 | utils.difference(o.a, o.b).should.eql(['a','d']); 82 | utils.difference(o.a).should.eql(['a','b','c','d']); 83 | }); 84 | }); 85 | 86 | 87 | describe('first', function() { 88 | it('should throw on bad args.', function() { 89 | (function () { 90 | utils.first() 91 | }).should.throw('utils#array.first() expects an array.'); 92 | }); 93 | 94 | it('should return the first item in an array.', function() { 95 | utils.first(['a', 'b', 'c']).should.equal('a'); 96 | }); 97 | 98 | it('should return an array with the first two items in an array.', function() { 99 | utils.first(['a', 'b', 'c'], 2).should.eql(['a', 'b']); 100 | }); 101 | 102 | it('should return the first item that returns true for the callback:', function() { 103 | utils.first(['a', 'b', 'c'], function (ele) { 104 | return ele === 'b'; 105 | }).should.eql('b'); 106 | }); 107 | }); 108 | 109 | describe('flatten', function() { 110 | it('should recursively flatten an array or arrays.', function() { 111 | utils.flatten(['a', ['b', ['c']], 'd', ['e']]).should.eql(['a', 'b', 'c', 'd', 'e']); 112 | }); 113 | }); 114 | 115 | describe('each', function () { 116 | it('should return undefined when the first arg is null', function () { 117 | assert(utils.each() === undefined); 118 | }); 119 | 120 | it('should loop over each item in an array and call the given function on every element:', function () { 121 | var res = []; 122 | utils.each(['a', 'b', 'c'], function (ele) { 123 | res.push(ele + ele); 124 | }); 125 | res.should.eql(['aa', 'bb', 'cc']); 126 | }); 127 | 128 | it('should "break" when `false` is returned:', function () { 129 | var res = []; 130 | utils.each(['a', 'b', 'c'], function (ele) { 131 | if (ele === 'b') { 132 | return false; 133 | } 134 | res.push(ele + ele); 135 | }); 136 | res.should.eql(['aa']); 137 | }); 138 | }); 139 | 140 | describe('forEach', function() { 141 | it('should loop over each item in an array.', function() { 142 | var one = ['a', 'b', 'c']; 143 | var two = []; 144 | 145 | utils.forEach(['a', 'b', 'c'], function (ele, i) { 146 | one[i] = i + ele; 147 | }); 148 | utils.forEach(['a', 'b', 'c'], function (ele, i) { 149 | two[i] = ele + ele; 150 | }); 151 | 152 | one.should.eql(['0a', '1b', '2c']); 153 | two.should.eql(['aa', 'bb', 'cc']); 154 | }); 155 | }); 156 | 157 | describe('isArray', function() { 158 | it('should return true if the value is an array.', function() { 159 | utils.isArray('foo').should.be.false; 160 | utils.isArray(['foo']).should.be.true; 161 | }); 162 | }); 163 | 164 | describe('last', function() { 165 | it('should throw on bad args.', function() { 166 | (function () { 167 | utils.last() 168 | }).should.throw('utils#array.last() expects an array.'); 169 | }); 170 | 171 | it('should return the last item in an array.', function() { 172 | utils.last(['a', 'b', 'c']).should.equal('c'); 173 | }); 174 | 175 | it('should return an array with the last two items in an array.', function() { 176 | utils.last(['a', 'b', 'c'], 2).should.eql(['b', 'c']); 177 | }); 178 | 179 | it('should return the last item that returns true for the callback:', function() { 180 | utils.last(['a', 'b', 'c'], function (ele) { 181 | return ele === 'b'; 182 | }).should.eql('b'); 183 | }); 184 | }); 185 | 186 | describe('map', function() { 187 | it('should return an empty array when undefined.', function() { 188 | utils.map().should.eql([]); 189 | }); 190 | 191 | it('should map the items in the array and return new values.', function() { 192 | utils.map(['a','b','c'], function(str) { 193 | return str + str; 194 | }).should.eql(['aa', 'bb', 'cc']); 195 | }); 196 | }); 197 | 198 | describe('sort', function() { 199 | it('should throw on bad args.', function() { 200 | (function () { 201 | utils.sort() 202 | }).should.throw('utils#array.sort() expects an array.'); 203 | }); 204 | 205 | it('should sort the items in an array.', function() { 206 | utils.sort(['b', 'c', 'a']).should.eql(['a', 'b', 'c']); 207 | }); 208 | 209 | it('should take a compare function.', function() { 210 | utils.sort(['b', 'c', 'a'], function (a, b) { 211 | return b.localeCompare(a); 212 | }).should.eql(['c', 'b', 'a']); 213 | }); 214 | 215 | it('should sort based on object key:', function() { 216 | utils.sort([{a: 'zzz'}, {a: 'aaa'}], 'a').should.eql([{a:'aaa'},{a:'zzz'}]); 217 | }); 218 | }); 219 | 220 | describe('union', function() { 221 | it('should throw on bad args.', function() { 222 | (function () { 223 | utils.union() 224 | }).should.throw('utils#array.union() expects an array.'); 225 | }); 226 | 227 | it('should union items from multiple arrays:', function() { 228 | utils.union(['a', 'c'], ['b', 'b']).should.eql(['a','c','b']); 229 | }); 230 | 231 | it('should union items from multiple arrays:', function() { 232 | utils.union(['a'], ['b']).should.eql(['a','b']); 233 | }); 234 | }); 235 | 236 | describe('unique', function() { 237 | it('should throw on bad args.', function() { 238 | (function () { 239 | utils.unique() 240 | }).should.throw('utils#array.unique() expects an array.'); 241 | }); 242 | 243 | it('should unique items from multiple arrays:', function() { 244 | utils.unique(['a', 'b', 'c', 'c']).should.eql(['a','b','c']); 245 | }); 246 | }); 247 | }); 248 | -------------------------------------------------------------------------------- /test/collection.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * utils 3 | * 4 | * Copyright (c) 2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | require('should'); 11 | var utils = require('../index').collection; 12 | 13 | describe('collection utils:', function() { 14 | describe('any', function() { 15 | it('should return an empty string when undefined.', function() { 16 | utils.any().should.be.false; 17 | }); 18 | it('should return if a value exists in the given string.', function() { 19 | utils.any('a-b-c', 'a').should.be.true; 20 | utils.any('a-b-c', 'd').should.be.false; 21 | }); 22 | it('should return if a value exists in the given object.', function() { 23 | utils.any({a: 'b', c: 'd'}, 'a').should.be.true; 24 | utils.any([{a: 'b', c: 'd'}], {a: 'b'}).should.be.true; 25 | }); 26 | it('should return if a value exists in the given array.', function() { 27 | utils.any('a-b-c', 'd').should.be.false; 28 | }); 29 | }); 30 | 31 | // describe('contains', function() { 32 | // it('should return an empty string when undefined.', function() { 33 | // utils.contains().should.be.false; 34 | // }); 35 | // it('should return if a value exists in the given string.', function() { 36 | // utils.contains('a-b-c', 'a').should.be.true; 37 | // utils.contains('a-b-c', 'd').should.be.false; 38 | // }); 39 | // it('should return if a value exists in the given object.', function() { 40 | // utils.contains({a: 'b', c: 'd'}, 'a').should.be.true; 41 | // utils.contains([{a: 'b', c: 'd'}], {a: 'b'}).should.be.true; 42 | // }); 43 | // it('should return if a value exists in the given array.', function() { 44 | // utils.contains('a-b-c', 'd').should.be.false; 45 | // }); 46 | // }); 47 | }); 48 | -------------------------------------------------------------------------------- /test/fixtures/README.md: -------------------------------------------------------------------------------- 1 | # template-helpers [![NPM version](https://badge.fury.io/js/template-helpers.svg)](http://badge.fury.io/js/template-helpers) [![Build Status](https://travis-ci.org/jonschlinkert/template-helpers.svg)](https://travis-ci.org/jonschlinkert/template-helpers) 2 | 3 | > Generic JavaScript helpers that can be used with any template engine. Handlebars, Lo-Dash, Underscore, or any engine that supports helper functions. 4 | 5 | ## Install with [npm](npmjs.org) 6 | 7 | ```bash 8 | npm i template-helpers --save 9 | ``` 10 | 11 | ## TOC 12 | 13 | 14 | 15 | - [Usage](#usage) 16 | * [Use with any template engine](#use-with-any-template-engine) 17 | * [Namespacing](#namespacing) 18 | - [Helpers](#helpers) 19 | - [Docs](#docs) 20 | - [Run tests](#run-tests) 21 | - [Related](#related) 22 | 23 | 24 | 25 | ## Usage 26 | 27 | To get all helpers grouped by collection: 28 | 29 | ```js 30 | var helpers = require('template-helpers'); 31 | 32 | // All helpers are on the `_` property 33 | console.log(helpers._); 34 | ``` 35 | 36 | **Get a specific collection** 37 | 38 | ```js 39 | var helpers = require('template-helpers'); 40 | 41 | // get only the math helpers 42 | var math = helpers.math; 43 | ``` 44 | 45 | ### Use with any template engine 46 | 47 | **Lo-Dash Example** 48 | 49 | ```js 50 | var context = {arr: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']}; 51 | 52 | // pass helpers on `imports` 53 | var imports = {imports: helpers.arrays}; 54 | var template = _.template('<%= first(foo) %>', imports); 55 | 56 | // pass context 57 | template({foo: ['a', 'b', 'c']}); 58 | //=> 'a' 59 | ``` 60 | 61 | ### Namespacing 62 | 63 | Handlebars and Lo-Dash both allow **dot notation** to be used for referencing helpers. Other engines may allow this too, I'd be happy to add this information to readme if someone wants to do a PR. 64 | 65 | **Example** 66 | 67 | ```js 68 | <%= path.dirname("a/b/c/d.js") %> 69 | ``` 70 | 71 | This can be used as a way of working around potential naming conflicts. 72 | 73 | 74 | ## Helpers 75 | Currently 87 helpers: 76 | 77 | + **[array](lib/array.js)** 78 | - [after](lib/array.js#L131) 79 | - [arrayify](lib/array.js#L44) 80 | - [before](lib/array.js#L110) 81 | - [compact](lib/array.js#L260) 82 | - [difference](lib/array.js#L280) 83 | - [first](lib/array.js#L62) 84 | - [isArray](lib/array.js#L21) 85 | - [join](lib/array.js#L191) 86 | - [last](lib/array.js#L85) 87 | - [length](lib/array.js#L242) 88 | - [map](lib/array.js#L159) 89 | - [sort](lib/array.js#L217) 90 | - [union](lib/array.js#L347) 91 | - [unique](lib/array.js#L316) 92 | + **[code](lib/code.js)** 93 | - [embed](lib/code.js#L25) 94 | - [jsfiddle](lib/code.js#L51) 95 | + **[collection](lib/collection.js)** 96 | - [any](lib/collection.js#L15) 97 | + **[conditional](lib/conditional.js)** 98 | - [_if](lib/conditional.js#L13) 99 | + **[fs](lib/fs.js)** 100 | - [concat](lib/fs.js#L40) 101 | - [read](lib/fs.js#L19) 102 | + **[html](lib/html.js)** 103 | - [escapeHtml](lib/html.js#L18) 104 | - [sanitize](lib/html.js#L46) 105 | + **[math](lib/math.js)** 106 | - [add](lib/math.js#L19) 107 | - [ceil](lib/math.js#L108) 108 | - [divide](lib/math.js#L54) 109 | - [floor](lib/math.js#L90) 110 | - [multiply](lib/math.js#L72) 111 | - [round](lib/math.js#L129) 112 | - [subtract](lib/math.js#L36) 113 | - [sum](lib/math.js#L146) 114 | + **[object](lib/object.js)** 115 | - [extend](lib/object.js#L224) 116 | - [fallback](lib/object.js#L25) 117 | - [forIn](lib/object.js#L187) 118 | - [forOwn](lib/object.js#L207) 119 | - [get](lib/object.js#L77) 120 | - [hasOwn](lib/object.js#L152) 121 | - [isObject](lib/object.js#L115) 122 | - [isPlainObject](lib/object.js#L138) 123 | - [keys](lib/object.js#L94) 124 | - [merge](lib/object.js#L253) 125 | - [omit](lib/object.js#L170) 126 | - [parse](lib/object.js#L59) 127 | - [stringify](lib/object.js#L42) 128 | + **[path](lib/path.js)** 129 | - [basename](lib/path.js#L38) 130 | - [dirname](lib/path.js#L20) 131 | - [ext](lib/path.js#L92) 132 | - [extname](lib/path.js#L74) 133 | - [filename](lib/path.js#L56) 134 | - [isAbsolute](lib/path.js#L210) 135 | - [isRelative](lib/path.js#L245) 136 | - [join](lib/path.js#L175) 137 | - [relative](lib/path.js#L129) 138 | - [resolve](lib/path.js#L110) 139 | - [segments](lib/path.js#L153) 140 | + **[string](lib/string.js)** 141 | - [camelcase](lib/string.js#L142) 142 | - [centerAlign](lib/string.js#L408) 143 | - [chop](lib/string.js#L123) 144 | - [count](lib/string.js#L352) 145 | - [dashcase](lib/string.js#L230) 146 | - [dotcase](lib/string.js#L206) 147 | - [ellipsis](lib/string.js#L476) 148 | - [hyphenate](lib/string.js#L293) 149 | - [isString](lib/string.js#L23) 150 | - [lowercase](lib/string.js#L61) 151 | - [pascalcase](lib/string.js#L164) 152 | - [pathcase](lib/string.js#L252) 153 | - [replace](lib/string.js#L428) 154 | - [reverse](lib/string.js#L370) 155 | - [rightAlign](lib/string.js#L389) 156 | - [sentencecase](lib/string.js#L274) 157 | - [slugify](lib/string.js#L313) 158 | - [snakecase](lib/string.js#L184) 159 | - [toString](lib/string.js#L44) 160 | - [trim](lib/string.js#L98) 161 | - [truncate](lib/string.js#L455) 162 | - [uppercase](lib/string.js#L79) 163 | - [wordwrap](lib/string.js#L332) 164 | 165 | ## Docs 166 | 167 | 168 | ## Run tests 169 | Install dev dependencies. 170 | 171 | ```bash 172 | npm i -d && npm test 173 | ``` 174 | 175 | ## Related 176 | * [handlebars-helpers](https://github.com/assemble/handlebars-helpers): 120+ Handlebars helpers in ~20 categories, for Assemble, YUI, Ghost or any Handlebars project. Includes helpers like {{i18}}, {{markdown}}, {{relative}}, {{extend}}, {{moment}}, and so on. 177 | 178 | ## Contributing 179 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/template-helpers/issues) 180 | 181 | ## Author 182 | 183 | **Jon Schlinkert** 184 | 185 | + [github/jonschlinkert](https://github.com/jonschlinkert) 186 | + [twitter/jonschlinkert](http://twitter.com/jonschlinkert) 187 | 188 | ## License 189 | Copyright (c) 2015 Jon Schlinkert 190 | Released under the MIT license 191 | 192 | *** 193 | 194 | _This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 11, 2015._ 195 | 196 | [assemble]: https://github.com/assemble/assemble 197 | [verb]: https://github.com/assemble/verb 198 | [template]: https://github.com/jonschlinkert/template 199 | [word-wrap]: https://github.com/jonschlinkert/word-wrap 200 | [helper-concat]: https://github.com/helpers/helper-concat 201 | [path]: https://nodejs.org/api/path.html 202 | -------------------------------------------------------------------------------- /test/fixtures/a.js: -------------------------------------------------------------------------------- 1 | exports.aaa = function aaa(a, b, c) { 2 | return a + b + c; 3 | }; -------------------------------------------------------------------------------- /test/fixtures/a.md: -------------------------------------------------------------------------------- 1 | ``` 2 | foo 3 | ``` -------------------------------------------------------------------------------- /test/fixtures/b.js: -------------------------------------------------------------------------------- 1 | exports.bbb = function bbb(x, y, z) { 2 | return x + y + z; 3 | }; -------------------------------------------------------------------------------- /test/fs.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * utils 3 | * 4 | * Copyright (c) 2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | require('should'); 11 | var utils = require('../index').fs; 12 | 13 | describe('fs utils:', function() { 14 | var orig = process.cwd(); 15 | before(function () { 16 | process.chdir(__dirname + '/fixtures'); 17 | }); 18 | after(function () { 19 | process.chdir(orig); 20 | }); 21 | 22 | describe('fs', function() { 23 | it('should return an empty string when the file does not exist.', function() { 24 | utils.tryReaddir('.').should.containDeep(['README.md']) 25 | }); 26 | 27 | it('should read a file and inject its content.', function() { 28 | utils.tryRequire('a.js').should.have.property('aaa'); 29 | }); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /test/lang.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * utils 3 | * 4 | * Copyright (c) 2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | require('should'); 11 | var utils = require('../index').lang; 12 | 13 | var obj = {a: 'a', b: 'b', c: {d: {e: 'e'}}}; 14 | 15 | describe('lang utils:', function() { 16 | describe('hasValues', function() { 17 | it('should return false if the given value is empty.', function() { 18 | utils.hasValues('').should.be.false; 19 | utils.hasValues({}).should.be.false; 20 | utils.hasValues([]).should.be.false; 21 | }); 22 | 23 | it('should return true if any value exists.', function() { 24 | utils.hasValues('123').should.be.true; 25 | utils.hasValues(1).should.be.true; 26 | utils.hasValues(obj).should.be.true; 27 | utils.hasValues(['a']).should.be.true; 28 | }); 29 | }); 30 | 31 | describe('isEmpty', function() { 32 | it('should return true if the given value is empty.', function() { 33 | utils.isEmpty('').should.be.true; 34 | utils.isEmpty({}).should.be.true; 35 | utils.isEmpty([]).should.be.true; 36 | }); 37 | 38 | it('should return false if any value exists.', function() { 39 | utils.isEmpty('123').should.be.false; 40 | utils.isEmpty(1).should.be.false; 41 | utils.isEmpty(obj).should.be.false; 42 | utils.isEmpty(['a']).should.be.false; 43 | }); 44 | }); 45 | 46 | describe('isObject', function() { 47 | it('should return true if the value is an object.', function() { 48 | utils.isObject(obj).should.be.true; 49 | utils.isObject([]).should.be.false; 50 | utils.isObject('foo').should.be.false; 51 | }); 52 | }); 53 | 54 | describe('isPlainObject', function() { 55 | it('should return true if the value is a plain object.', function() { 56 | utils.isPlainObject(obj).should.be.true; 57 | utils.isPlainObject([]).should.be.false; 58 | utils.isPlainObject(/foo/).should.be.false; 59 | utils.isPlainObject('foo').should.be.false; 60 | }); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /test/math.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * utils 3 | * 4 | * Copyright (c) 2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | require('should'); 11 | var utils = require('../index').math; 12 | 13 | describe('math utils:', function() { 14 | describe('sum', function() { 15 | it('should reduce-sum the numbers in the array.', function() { 16 | utils.sum([1, 2, 3, 4, 5]).should.equal(15); 17 | }); 18 | it('should ignore non-numbers.', function() { 19 | utils.sum([1, 2, 'foo', 3, 4, 5]).should.equal(15); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /test/object.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * utils 3 | * 4 | * Copyright (c) 2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | require('should'); 11 | var utils = require('../index').object; 12 | 13 | var obj = {a: 'a', b: 'b', c: {d: {e: 'e'}}}; 14 | 15 | describe('object utils:', function() { 16 | describe('hasOwn', function() { 17 | it('should return true when an object has own property `key`.', function() { 18 | utils.hasOwn(obj, 'a').should.be.true; 19 | utils.hasOwn(obj, 'k').should.be.false; 20 | }); 21 | }); 22 | 23 | describe('keys', function() { 24 | it('should return the keys of an object.', function() { 25 | utils.keys(obj).should.eql(['a', 'b', 'c']); 26 | }); 27 | }); 28 | 29 | describe('omit', function() { 30 | it('should omit keys from an object.', function() { 31 | utils.omit(obj, ['b', 'c']).should.eql({a: 'a'}); 32 | }); 33 | }); 34 | 35 | describe('defaults', function() { 36 | var ctx = {}; 37 | beforeEach(function () { 38 | ctx.foo = {aaa: 'bbb', ccc: 'ddd'}; 39 | ctx.bar = {ccc: 'eee', fff: 'ggg'}; 40 | }); 41 | 42 | it('should return an empty string when undefined.', function() { 43 | utils.defaults().should.eql({}); 44 | }); 45 | 46 | it('should extend the first object with missing properties from the second.', function() { 47 | utils.defaults(ctx.foo, ctx.bar).should.eql({aaa:'bbb',ccc:'ddd',fff:'ggg'}); 48 | }); 49 | 50 | it('should ignore non-objects.', function() { 51 | utils.defaults(ctx.foo, ctx.bar, 'baz').should.eql({aaa:'bbb',ccc:'ddd',fff:'ggg'}); 52 | }); 53 | 54 | it('should use the default object as context.', function() { 55 | ctx.bar = {aaa: 'ddd'}; 56 | utils.defaults(ctx.foo, ctx.bar).should.eql({aaa:'bbb',ccc:'ddd'}, 'should not overwrite `aaa`'); 57 | }); 58 | }); 59 | 60 | describe('extend', function() { 61 | var ctx = {}; 62 | beforeEach(function () { 63 | ctx.foo = {aaa: 'bbb'}; 64 | ctx.bar = {ccc: 'ddd'}; 65 | }); 66 | 67 | it('should return an empty string when undefined.', function() { 68 | utils.extend().should.eql({}); 69 | }); 70 | 71 | it('should extend the first object with the second.', function() { 72 | utils.extend(ctx.foo, ctx.bar).should.eql({aaa:'bbb',ccc:'ddd'}); 73 | }); 74 | 75 | it('should ignore non-objects.', function() { 76 | utils.extend(ctx.foo, ctx.bar, 'baz').should.eql({aaa:'bbb',ccc:'ddd'}); 77 | }); 78 | 79 | it('should use the extended object as context.', function() { 80 | // overwrite `foo` 81 | ctx.bar = {aaa: 'ddd'}; 82 | utils.extend(ctx.foo, ctx.bar).should.eql({aaa:'ddd'}); 83 | }); 84 | }); 85 | 86 | describe('merge', function() { 87 | var ctx = {}; 88 | beforeEach(function () { 89 | ctx.foo = {aaa: 'bbb', bbb: {ccc: {ddd: 'eee'}}}; 90 | ctx.bar = {aaa: 'bbb', bbb: {ccc: {eee: 'fff'}}}; 91 | }); 92 | 93 | it('should return an empty string when undefined.', function() { 94 | utils.merge().should.eql({}); 95 | }); 96 | 97 | it('should deeply merge the first object with the second.', function() { 98 | utils.merge(ctx.foo, ctx.bar).should.eql({ aaa: 'bbb', bbb: { ccc: { ddd: 'eee', eee: 'fff' } } }); 99 | }); 100 | }); 101 | }); 102 | -------------------------------------------------------------------------------- /test/string.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * utils 3 | * 4 | * Copyright (c) 2015, Jon Schlinkert. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | require('should'); 11 | var utils = require('../index').string; 12 | 13 | describe('string utils:', function() { 14 | describe('chop', function() { 15 | it('should return an empty string when undefined.', function() { 16 | utils.chop().should.equal(''); 17 | }); 18 | it('should strip leading whitespace from a string.', function() { 19 | utils.chop(' abc').should.equal('abc'); 20 | }); 21 | it('should strip trailing whitespace from a string.', function() { 22 | utils.chop('abc ').should.equal('abc'); 23 | }); 24 | it('should strip leading non-word characters from a string.', function() { 25 | utils.chop('_-abc').should.equal('abc'); 26 | }); 27 | it('should strip trailing non-word characters from a string.', function() { 28 | utils.chop('abc_-').should.equal('abc'); 29 | }); 30 | }); 31 | 32 | describe('camelcase', function() { 33 | it('should return an empty string when undefined.', function() { 34 | utils.camelcase().should.equal(''); 35 | }); 36 | it('should camel-case the characters in a string.', function() { 37 | utils.camelcase('foo bar baz').should.equal('fooBarBaz'); 38 | }); 39 | it('should camel-case the characters in a string.', function() { 40 | utils.camelcase('A').should.equal('a'); 41 | }); 42 | it('should work with hyphens.', function() { 43 | utils.camelcase('foo-bar-baz').should.equal('fooBarBaz'); 44 | utils.camelcase('-foo bar baz-').should.equal('fooBarBaz'); 45 | }); 46 | 47 | it('should work with other non-word characters.', function() { 48 | utils.camelcase('9foo-bar_baz').should.equal('9fooBarBaz'); 49 | utils.camelcase('_foo_bar_baz-').should.equal('fooBarBaz'); 50 | }); 51 | }); 52 | 53 | describe('pascalcase', function() { 54 | it('should return an empty string when undefined.', function() { 55 | utils.pascalcase().should.equal(''); 56 | }); 57 | it('should camel-case the characters in a string.', function() { 58 | utils.pascalcase('a').should.equal('A'); 59 | utils.pascalcase('A').should.equal('A'); 60 | }); 61 | it('should pascal-case the characters in a string.', function() { 62 | utils.pascalcase('foo bar baz').should.equal('FooBarBaz'); 63 | }); 64 | it('should work with hyphens.', function() { 65 | utils.pascalcase('foo-bar-baz').should.equal('FooBarBaz'); 66 | utils.pascalcase('-foo bar baz-').should.equal('FooBarBaz'); 67 | }); 68 | 69 | it('should work with other non-word characters.', function() { 70 | utils.pascalcase('9foo-bar_baz').should.equal('9fooBarBaz'); 71 | utils.pascalcase('_foo_bar_baz-').should.equal('FooBarBaz'); 72 | }); 73 | }); 74 | 75 | describe('snakecase', function() { 76 | it('should return an empty string when undefined.', function() { 77 | utils.snakecase().should.equal(''); 78 | }); 79 | it('should camel-case the characters in a string.', function() { 80 | utils.snakecase('A').should.equal('a'); 81 | }); 82 | it('should snake-case the characters in a string.', function() { 83 | utils.snakecase('foo bar baz').should.equal('foo_bar_baz'); 84 | }); 85 | it('should work with hyphens.', function() { 86 | utils.snakecase('foo-bar-baz').should.equal('foo_bar_baz'); 87 | utils.snakecase('-foo bar baz-').should.equal('foo_bar_baz'); 88 | }); 89 | 90 | it('should work with other non-word characters.', function() { 91 | utils.snakecase('9foo-bar_baz').should.equal('9foo_bar_baz'); 92 | utils.snakecase('_foo_bar_baz-').should.equal('foo_bar_baz'); 93 | }); 94 | }); 95 | 96 | describe('dotcase', function() { 97 | it('should return an empty string when undefined.', function() { 98 | utils.dotcase().should.equal(''); 99 | }); 100 | it('should camel-case the characters in a string.', function() { 101 | utils.dotcase('A').should.equal('a'); 102 | }); 103 | it('should dot-case the characters in a string.', function() { 104 | utils.dotcase('foo bar baz').should.equal('foo.bar.baz'); 105 | }); 106 | it('should work with hyphens.', function() { 107 | utils.dotcase('foo-bar-baz').should.equal('foo.bar.baz'); 108 | utils.dotcase('-foo bar baz-').should.equal('foo.bar.baz'); 109 | }); 110 | 111 | it('should work with other non-word characters.', function() { 112 | utils.dotcase('9foo-bar_baz').should.equal('9foo.bar.baz'); 113 | utils.dotcase('_foo_bar_baz-').should.equal('foo.bar.baz'); 114 | }); 115 | }); 116 | 117 | describe('dashcase', function() { 118 | it('should return an empty string when undefined.', function() { 119 | utils.dashcase().should.equal(''); 120 | }); 121 | it('should camel-case the characters in a string.', function() { 122 | utils.dashcase('A').should.equal('a'); 123 | }); 124 | it('should dash-case the characters in a string.', function() { 125 | utils.dashcase('foo bar baz').should.equal('foo-bar-baz'); 126 | }); 127 | it('should work with hyphens.', function() { 128 | utils.dashcase('foo-bar-baz').should.equal('foo-bar-baz'); 129 | utils.dashcase('-foo bar baz-').should.equal('foo-bar-baz'); 130 | }); 131 | 132 | it('should work with other non-word characters.', function() { 133 | utils.dashcase('9foo-bar_baz').should.equal('9foo-bar-baz'); 134 | utils.dashcase('_foo_bar_baz-').should.equal('foo-bar-baz'); 135 | }); 136 | }); 137 | 138 | describe('pathcase', function() { 139 | it('should return an empty string when undefined.', function() { 140 | utils.pathcase().should.equal(''); 141 | }); 142 | it('should camel-case the characters in a string.', function() { 143 | utils.pathcase('A').should.equal('a'); 144 | }); 145 | it('should path-case the characters in a string.', function() { 146 | utils.pathcase('foo bar baz').should.equal('foo/bar/baz'); 147 | }); 148 | it('should work with hyphens.', function() { 149 | utils.pathcase('foo-bar-baz').should.equal('foo/bar/baz'); 150 | utils.pathcase('-foo bar baz-').should.equal('foo/bar/baz'); 151 | }); 152 | 153 | it('should work with other non-word characters.', function() { 154 | utils.pathcase('9foo-bar_baz').should.equal('9foo/bar/baz'); 155 | utils.pathcase('_foo_bar_baz-').should.equal('foo/bar/baz'); 156 | }); 157 | }); 158 | 159 | describe('sentencecase', function() { 160 | it('should return an empty string when undefined.', function() { 161 | utils.sentencecase().should.equal(''); 162 | }); 163 | it('should camel-case the characters in a string.', function() { 164 | utils.sentencecase('A').should.equal('A'); 165 | utils.sentencecase('a').should.equal('A'); 166 | }); 167 | it('should sentence-case the characters in a string.', function() { 168 | utils.sentencecase('foo bar baz.').should.equal('Foo bar baz.'); 169 | utils.sentencecase('a').should.equal('A'); 170 | }); 171 | }); 172 | 173 | describe('hyphenate', function() { 174 | it('should return an empty string when undefined.', function() { 175 | utils.hyphenate().should.equal(''); 176 | }); 177 | it('should hyphenate the characters in a string.', function() { 178 | utils.hyphenate('foo bar baz').should.equal('foo-bar-baz'); 179 | }); 180 | it('should work with hyphens.', function() { 181 | utils.hyphenate('foo-bar-baz').should.equal('foo-bar-baz'); 182 | utils.hyphenate('-foo bar baz-').should.equal('foo-bar-baz'); 183 | }); 184 | 185 | it('should work with other non-word characters.', function() { 186 | utils.hyphenate('9foo-bar_baz').should.equal('9foo-bar_baz'); 187 | utils.hyphenate('_foo_bar_baz-').should.equal('foo_bar_baz'); 188 | }); 189 | }); 190 | 191 | describe('slugify', function() { 192 | it('should return an empty string when undefined.', function() { 193 | utils.slugify().should.equal(''); 194 | }); 195 | it('should slugify the characters in a string.', function() { 196 | utils.slugify('foo bar baz').should.equal('foo-bar-baz'); 197 | }); 198 | it('should work with hyphens.', function() { 199 | utils.slugify('foo-bar-baz').should.equal('foo-bar-baz'); 200 | utils.slugify('-foo bar baz-').should.equal('foo-bar-baz'); 201 | }); 202 | 203 | it('should work with other non-word characters.', function() { 204 | utils.slugify('9foo-bar_baz').should.equal('9foo-bar-baz'); 205 | utils.slugify('_foo_bar_baz-').should.equal('foo-bar-baz'); 206 | }); 207 | }); 208 | 209 | describe('count', function() { 210 | it('should return an empty string when undefined.', function() { 211 | utils.count().should.equal(''); 212 | }); 213 | it('should return zero when the substring is undefined.', function() { 214 | utils.count('ababa').should.equal('0'); 215 | }); 216 | it('should count the occurrances of a substring.', function() { 217 | utils.count('ababa', 'a').should.equal(3); 218 | utils.count('abab', 'a').should.equal(2); 219 | utils.count('ababaa', 'a').should.equal(4); 220 | }); 221 | }); 222 | 223 | describe('reverse', function() { 224 | it('should return an empty string when undefined.', function() { 225 | utils.reverse().should.equal(''); 226 | }); 227 | it('should reverse the characters in a string.', function() { 228 | utils.reverse('abc').should.equal('cba'); 229 | }); 230 | }); 231 | 232 | describe('wordwrap', function() { 233 | it('should return an empty string when undefined.', function() { 234 | utils.wordwrap().should.equal(''); 235 | }); 236 | it('should wrap words to the specified width.', function() { 237 | var actual = utils.wordwrap('a b c d e f', {width: 5}) 238 | actual.should.equal(' a b c \n d e f'); 239 | }); 240 | 241 | it('should use custom newline characters.', function() { 242 | var actual = utils.wordwrap('a b c d e f', {width: 5, newline: '
'}) 243 | actual.should.equal(' a b c
d e f'); 244 | }); 245 | }); 246 | 247 | describe('align', function() { 248 | it('should return an empty string when undefined.', function() { 249 | utils.rightAlign().should.equal(''); 250 | utils.centerAlign().should.equal(''); 251 | }); 252 | it('should right align the characters in a string.', function() { 253 | utils.rightAlign('foo\nbarbazb').should.equal(' foo\nbarbazb'); 254 | }); 255 | it('should center align the characters in a string.', function() { 256 | utils.centerAlign('foo\nbarbazb').should.equal(' foo\nbarbazb'); 257 | }); 258 | }); 259 | 260 | describe('replace', function() { 261 | it('should return an empty string when undefined.', function() { 262 | utils.replace().should.equal(''); 263 | }) 264 | it('should return the string when no replacement pattern is passed.', function() { 265 | var actual = utils.replace('abcabc') 266 | actual.should.equal('abcabc'); 267 | }); 268 | it('should replace characters in a string with nothing.', function() { 269 | var actual = utils.replace('abcabc', 'a') 270 | actual.should.equal('bcbc'); 271 | }); 272 | it('should replace characters in a string with a string', function() { 273 | var actual = utils.replace('abcabc', 'a', 'z') 274 | actual.should.equal('zbczbc'); 275 | }); 276 | }); 277 | 278 | describe('truncate', function() { 279 | it('should return an empty string when undefined.', function() { 280 | utils.truncate().should.equal(''); 281 | }); 282 | it('should truncate a string to the specified `length`', function() { 283 | utils.truncate('foo bar baz', 7).should.equal('foo bar'); 284 | }); 285 | it('should truncate a string and remove all HTML tags', function() { 286 | utils.truncate('foo bar baz', 5).should.equal('foo b'); 287 | }); 288 | }); 289 | 290 | describe('ellipsis', function() { 291 | it('should return an empty string when undefined.', function() { 292 | utils.ellipsis().should.equal(''); 293 | }); 294 | it('should truncate a string to the specified `length` and add an ellipsis.', function() { 295 | utils.ellipsis('foo bar baz', 7).should.equal('foo bar…'); 296 | }); 297 | it('should truncate a string, remove all HTML tags and add an ellipsis', function() { 298 | utils.ellipsis('foo bar baz', 7).should.equal('foo bar…'); 299 | }); 300 | }); 301 | }); 302 | -------------------------------------------------------------------------------- /verbfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var util = require('util'); 5 | var verb = require('verb'); 6 | var plugin = require('./support/plugins'); 7 | 8 | verb.helper('utils_methods', function (fp) { 9 | var obj = require(path.resolve(process.cwd(), fp)); 10 | return util.inspect(obj, null, 10); 11 | }); 12 | 13 | verb.task('readme', function () { 14 | return verb.src(['.verb.md', 'docs/*.md']) 15 | .pipe(verb.dest('.')); 16 | }); 17 | 18 | verb.task('names', function () { 19 | return verb.src(['lib/**/*.js']) 20 | .pipe(plugin.names()) 21 | .pipe(verb.dest('lib/')); 22 | }); 23 | 24 | verb.task('modularize', function () { 25 | return verb.src(['lib/string/index.js']) 26 | .pipe(plugin.modularize()) 27 | .pipe(verb.dest('lib/temp')); 28 | }); 29 | 30 | verb.task('default', ['readme']); 31 | --------------------------------------------------------------------------------