├── .editorconfig ├── .eslintrc.json ├── .gitattributes ├── .gitignore ├── .npmrc ├── .travis.yml ├── .verb.md ├── LICENSE ├── index.js ├── package.json ├── readme.md └── test ├── actual ├── ansi-colors.js ├── bottom.js ├── many.js ├── markdown-toc.js ├── non-lazy.js ├── normal.js ├── separate.js └── top.js ├── fixtures ├── ansi-colors.js ├── bottom.js ├── many.js ├── markdown-toc.js ├── non-lazy.js ├── normal.js ├── separate.js └── top.js └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | end_of_line = lf 6 | charset = utf-8 7 | indent_size = 2 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{**/{actual,fixtures,expected,templates}/**,*.md}] 12 | trim_trailing_whitespace = false 13 | insert_final_newline = false -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": false, 4 | "es6": true, 5 | "node": true, 6 | "mocha": true 7 | }, 8 | 9 | "globals": { 10 | "document": false, 11 | "navigator": false, 12 | "window": false 13 | }, 14 | 15 | "rules": { 16 | "accessor-pairs": 2, 17 | "arrow-spacing": [2, { "before": true, "after": true }], 18 | "block-spacing": [2, "always"], 19 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 20 | "comma-dangle": [2, "never"], 21 | "comma-spacing": [2, { "before": false, "after": true }], 22 | "comma-style": [2, "last"], 23 | "constructor-super": 2, 24 | "curly": [2, "multi-line"], 25 | "dot-location": [2, "property"], 26 | "eol-last": 2, 27 | "eqeqeq": [2, "allow-null"], 28 | "generator-star-spacing": [2, { "before": true, "after": true }], 29 | "handle-callback-err": [2, "^(err|error)$" ], 30 | "indent": [2, 2, { "SwitchCase": 1 }], 31 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 32 | "keyword-spacing": [2, { "before": true, "after": true }], 33 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }], 34 | "new-parens": 2, 35 | "no-array-constructor": 2, 36 | "no-caller": 2, 37 | "no-class-assign": 2, 38 | "no-cond-assign": 2, 39 | "no-const-assign": 2, 40 | "no-control-regex": 2, 41 | "no-debugger": 2, 42 | "no-delete-var": 2, 43 | "no-dupe-args": 2, 44 | "no-dupe-class-members": 2, 45 | "no-dupe-keys": 2, 46 | "no-duplicate-case": 2, 47 | "no-empty-character-class": 2, 48 | "no-eval": 2, 49 | "no-ex-assign": 2, 50 | "no-extend-native": 2, 51 | "no-extra-bind": 2, 52 | "no-extra-boolean-cast": 2, 53 | "no-extra-parens": [2, "functions"], 54 | "no-fallthrough": 2, 55 | "no-floating-decimal": 2, 56 | "no-func-assign": 2, 57 | "no-implied-eval": 2, 58 | "no-inner-declarations": [2, "functions"], 59 | "no-invalid-regexp": 2, 60 | "no-irregular-whitespace": 2, 61 | "no-iterator": 2, 62 | "no-label-var": 2, 63 | "no-labels": 2, 64 | "no-lone-blocks": 2, 65 | "no-mixed-spaces-and-tabs": 2, 66 | "no-multi-spaces": 2, 67 | "no-multi-str": 2, 68 | "no-multiple-empty-lines": [2, { "max": 1 }], 69 | "no-native-reassign": 0, 70 | "no-negated-in-lhs": 2, 71 | "no-new": 2, 72 | "no-new-func": 2, 73 | "no-new-object": 2, 74 | "no-new-require": 2, 75 | "no-new-wrappers": 2, 76 | "no-obj-calls": 2, 77 | "no-octal": 2, 78 | "no-octal-escape": 2, 79 | "no-proto": 0, 80 | "no-redeclare": 2, 81 | "no-regex-spaces": 2, 82 | "no-return-assign": 2, 83 | "no-self-compare": 2, 84 | "no-sequences": 2, 85 | "no-shadow-restricted-names": 2, 86 | "no-spaced-func": 2, 87 | "no-sparse-arrays": 2, 88 | "no-this-before-super": 2, 89 | "no-throw-literal": 2, 90 | "no-trailing-spaces": 0, 91 | "no-undef": 2, 92 | "no-undef-init": 2, 93 | "no-unexpected-multiline": 2, 94 | "no-unneeded-ternary": [2, { "defaultAssignment": false }], 95 | "no-unreachable": 2, 96 | "no-unused-vars": [2, { "vars": "all", "args": "none" }], 97 | "no-useless-call": 0, 98 | "no-with": 2, 99 | "one-var": [0, { "initialized": "never" }], 100 | "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }], 101 | "padded-blocks": [0, "never"], 102 | "quotes": [2, "single", "avoid-escape"], 103 | "radix": 2, 104 | "semi": [2, "always"], 105 | "semi-spacing": [2, { "before": false, "after": true }], 106 | "space-before-blocks": [2, "always"], 107 | "space-before-function-paren": [2, "never"], 108 | "space-in-parens": [2, "never"], 109 | "space-infix-ops": 2, 110 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 111 | "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], 112 | "use-isnan": 2, 113 | "valid-typeof": 2, 114 | "wrap-iife": [2, "any"], 115 | "yoda": [2, "never"] 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /.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 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # always ignore files 2 | *.DS_Store 3 | *.sublime-* 4 | 5 | # test related, or directories generated by tests 6 | test/actual 7 | actual 8 | coverage 9 | .nyc* 10 | 11 | # npm 12 | node_modules 13 | npm-debug.log 14 | 15 | # yarn 16 | yarn.lock 17 | yarn-error.log 18 | 19 | # misc 20 | _gh_pages 21 | _draft 22 | _drafts 23 | bower_components 24 | vendor 25 | temp 26 | tmp 27 | TODO.md 28 | package-lock.json -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | os: 3 | - linux 4 | - osx 5 | language: node_js 6 | node_js: 7 | - node 8 | - '10' 9 | - '8' 10 | - '6' 11 | - '4' 12 | - '0.12' 13 | - '0.10' 14 | matrix: 15 | fast_finish: true 16 | allow_failures: 17 | - node_js: "0.10" 18 | -------------------------------------------------------------------------------- /.verb.md: -------------------------------------------------------------------------------- 1 | # {%= name %} {%= badge("fury") %} 2 | 3 | > {%= description %} 4 | 5 | ## Install 6 | {%= include("install-npm", {save: true}) %} 7 | 8 | ## Usage 9 | 10 | This loader is intended to be used with [webpack][webpack] to transform files using [lazy-cache][lazy-cache] into files that require modules directly. 11 | Use this like any other [webpack loader](http://webpack.github.io/docs/using-loaders.html); 12 | 13 | ```js 14 | var webpackConfig = { 15 | module: { 16 | loaders: [ 17 | { 18 | test: /\.js$/, 19 | loader: 'unlazy' 20 | } 21 | ] 22 | } 23 | } 24 | ``` 25 | 26 | ## API 27 | {%= apidocs("index.js") %} 28 | 29 | ## Related projects 30 | {%= related(verb.related.list) %} 31 | 32 | ## Running tests 33 | {%= include("tests") %} 34 | 35 | ## Contributing 36 | {%= include("contributing") %} 37 | 38 | ## Author 39 | {%= include("author") %} 40 | 41 | ## License 42 | {%= copyright() %} 43 | {%= license %} 44 | 45 | *** 46 | 47 | {%= include("footer") %} 48 | 49 | {%= reflinks(['webpack', 'lazy-cache']) %} 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-present, Brian Woodward. 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 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * unlazy-loader 3 | * 4 | * Copyright (c) 2015-present, Brian Woodward. 5 | * Released under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var regex = require('requires-regex'); 11 | 12 | /** 13 | * Webpack loader used for transforming files that contain `lazy-cache` into files 14 | * that require modules directly. 15 | * 16 | * @param {String} `source` Source code to inspect. 17 | * @return {String} Transformed source code. 18 | * @api public 19 | * @name `unlazy-loader` 20 | */ 21 | 22 | module.exports = function(str) { 23 | if (this && this.resource && !isLazy(this.resource, str)) { 24 | return str; 25 | } 26 | return transform(str); 27 | }; 28 | 29 | /** 30 | * Determine if the source code contains lazy-cache. 31 | * 32 | * @param {String} `fp` File path of the source code to inspect. 33 | * @param {String} `source` Source code to inspect. 34 | * @return {Boolean} `true` if has lazy-cache 35 | */ 36 | 37 | function isLazy(fp, source) { 38 | return fp.indexOf('lazy-cache') === -1; 39 | } 40 | 41 | /** 42 | * Transform source code containing lazy-cache statements into a requirable file usable with webpack. 43 | * 44 | * @param {String} `source` Source code. 45 | * @return {String} Transformed source code. 46 | */ 47 | 48 | function transform(str) { 49 | str = str.split(/^lazy\(/gm).join('require('); 50 | var lines = str.split(/\r\n|\n/); 51 | var len = lines.length; 52 | var re = regex(); 53 | var idx = 0; 54 | 55 | var start = false; 56 | var isExported = false; 57 | var namespace; 58 | var res = ''; 59 | 60 | while (idx < len) { 61 | var line = lines[idx++]; 62 | res += '\n'; 63 | 64 | if (/(?:var fn = require|require = utils)/.test(line)) { 65 | continue; 66 | } 67 | if (/^require = fn/.test(line)) { 68 | continue; 69 | } 70 | // adding this line to catch other variable names than the more specific cases above 71 | if (/^require = (?:.*)/.test(line)) { 72 | continue; 73 | } 74 | 75 | var match = re.exec(line); 76 | if (!match) { 77 | res += line; 78 | continue; 79 | } 80 | 81 | if (match && (match[2] === 'lazy-cache' || match[3] === 'lazy-cache')) { 82 | namespace = toNamespace(match[1]); 83 | if (/module\.exports/.test(match[1])) { 84 | isExported = true; 85 | } 86 | line = 'var ' + namespace + ' = {};'; 87 | start = true; 88 | res += line; 89 | continue; 90 | } 91 | 92 | if (!start) { 93 | res += line; 94 | continue; 95 | } 96 | 97 | var variable = toVariable(match); 98 | var prefix = toProperty(namespace, variable, match[2]); 99 | line = line.split(match[0]).join(prefix); 100 | res += line; 101 | } 102 | 103 | if (isExported) { 104 | res += '\nmodule.exports = ' + namespace + ';'; 105 | } 106 | return res.replace(/^\s+/, ''); 107 | } 108 | 109 | function toVariable(match) { 110 | return camelcase(match[3] || match[2]); 111 | } 112 | 113 | function toNamespace(str) { 114 | str = str.replace(/var\s*/, ''); 115 | return str.split(/[^\w]/).shift(); 116 | } 117 | 118 | function toProperty(namespace, prop, val) { 119 | return namespace + '.' + prop + ' = ' + toRequire(val); 120 | } 121 | 122 | function toRequire(name) { 123 | return 'require(\'' + name + '\');'; 124 | } 125 | 126 | /** 127 | * Used to camelcase the module if a variable is not defined. 128 | * 129 | * @param {String} `str` String containing `_`, `.`, `-` or whitespace that will be camelcased. 130 | * @return {String} camelcased string. 131 | */ 132 | 133 | function camelcase(str) { 134 | if (!/[\s\W]/.test(str)) return str; 135 | if (str.length === 1) { 136 | return str.toLowerCase(); 137 | } 138 | str = str.replace(/^[\W_]+|[\W_]+$/g, '').toLowerCase(); 139 | return str.replace(/[\W_]+(\w|$)/g, function(_, ch) { 140 | return ch.toUpperCase(); 141 | }); 142 | } 143 | 144 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "unlazy-loader", 3 | "description": "Webpack loader to transform lazy-cache files into unlazy cached files.", 4 | "version": "0.1.3", 5 | "homepage": "https://github.com/doowb/unlazy-loader", 6 | "author": "Brian Woodward (https://github.com/doowb)", 7 | "contributors": [ 8 | "Brian Woodward (https://twitter.com/doowb)", 9 | "Jon Schlinkert (http://twitter.com/jonschlinkert)" 10 | ], 11 | "repository": "doowb/unlazy-loader", 12 | "bugs": { 13 | "url": "https://github.com/doowb/unlazy-loader/issues" 14 | }, 15 | "license": "MIT", 16 | "files": [ 17 | "index.js" 18 | ], 19 | "main": "index.js", 20 | "engines": { 21 | "node": ">=0.10.0" 22 | }, 23 | "scripts": { 24 | "test": "mocha" 25 | }, 26 | "dependencies": { 27 | "requires-regex": "^0.3.3" 28 | }, 29 | "devDependencies": { 30 | "mocha": "*", 31 | "should": "*" 32 | }, 33 | "keywords": [ 34 | "cache", 35 | "lazy", 36 | "lazy-cache", 37 | "loader", 38 | "loading", 39 | "unlazy", 40 | "webpack" 41 | ], 42 | "verb": { 43 | "related": { 44 | "list": [ 45 | "lazy-cache", 46 | "webpack" 47 | ] 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # unlazy-loader [![NPM version](https://img.shields.io/npm/v/unlazy-loader.svg)](https://www.npmjs.com/package/unlazy-loader) 2 | 3 | > Webpack loader to transform lazy-cache files into unlazy cached files. 4 | 5 | ## Install 6 | Install with [npm](https://www.npmjs.com/): 7 | 8 | ```sh 9 | $ npm i unlazy-loader --save 10 | ``` 11 | 12 | ## Usage 13 | 14 | This loader is intended to be used with [webpack][webpack] to transform files using [lazy-cache][lazy-cache] into files that require modules directly. 15 | Use this like any other [webpack loader](http://webpack.github.io/docs/using-loaders.html); 16 | 17 | ```js 18 | var webpackConfig = { 19 | module: { 20 | loaders: [ 21 | { 22 | test: /\.js$/, 23 | loader: 'unlazy-loader' 24 | } 25 | ] 26 | } 27 | } 28 | ``` 29 | 30 | ## API 31 | 32 | ### [.`unlazy-loader`](index.js#L22) 33 | 34 | Webpack loader used for transforming files that contain `lazy-cache` into files 35 | that require modules directly. 36 | 37 | **Params** 38 | 39 | * `source` **{String}**: Source code to inspect. 40 | * `returns` **{String}**: Transformed source code. 41 | 42 | 43 | 44 | 45 | ## Related projects 46 | * [lazy-cache](https://www.npmjs.com/package/lazy-cache): Cache requires to be lazy-loaded when needed. | [homepage](https://github.com/jonschlinkert/lazy-cache) 47 | * [webpack](https://www.npmjs.com/package/webpack): Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which… [more](https://www.npmjs.com/package/webpack) | [homepage](https://github.com/webpack/webpack) 48 | 49 | ## Running tests 50 | Install dev dependencies: 51 | 52 | ```sh 53 | $ npm i -d && npm test 54 | ``` 55 | 56 | ## Contributing 57 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/doowb/unlazy-loader/issues/new). 58 | 59 | ## Author 60 | **Brian Woodward** 61 | 62 | + [github/doowb](https://github.com/doowb) 63 | + [twitter/doowb](http://twitter.com/doowb) 64 | 65 | ## License 66 | Copyright © 2016 [Brian Woodward](https://github.com/doowb) 67 | Released under the MIT license. 68 | 69 | *** 70 | 71 | _This file was generated by [verb](https://github.com/verbose/verb) on January 14, 2016._ 72 | 73 | [webpack]: https://github.com/webpack/webpack 74 | [lazy-cache]: https://github.com/jonschlinkert/lazy-cache 75 | 76 | -------------------------------------------------------------------------------- /test/actual/ansi-colors.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ansi-colors 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | /** 11 | * Module dependencies 12 | */ 13 | 14 | var colors = {}; 15 | 16 | /** 17 | * Temporarily re-assign `require` to trick browserify and 18 | * webpack into reconizing lazy dependencies. 19 | * 20 | * This tiny bit of ugliness has the huge dual advantage of 21 | * only loading modules that are actually called at some 22 | * point in the lifecycle of the application, whilst also 23 | * allowing browserify and webpack to find modules that 24 | * are depended on but never actually called. 25 | */ 26 | 27 | 28 | 29 | 30 | /** 31 | * Lazily required module dependencies 32 | */ 33 | 34 | /** 35 | * Wrap a string with ansi codes to create a black background. 36 | * 37 | * ```js 38 | * console.log(colors.bgblack('some string')); 39 | * ``` 40 | * 41 | * @param {String} `str` String to wrap with ansi codes. 42 | * @return {String} Wrapped string 43 | * @api public 44 | * @name bgblack 45 | */ 46 | 47 | colors.bgblack = require('ansi-bgblack'); 48 | 49 | /** 50 | * Wrap a string with ansi codes to create a blue background. 51 | * 52 | * ```js 53 | * console.log(colors.bgblue('some string')); 54 | * ``` 55 | * 56 | * @param {String} `str` String to wrap with ansi codes. 57 | * @return {String} Wrapped string 58 | * @api public 59 | * @name bgblue 60 | */ 61 | 62 | colors.bgblue = require('ansi-bgblue'); 63 | 64 | /** 65 | * Wrap a string with ansi codes to create a cyan background. 66 | * 67 | * ```js 68 | * console.log(colors.bgcyan('some string')); 69 | * ``` 70 | * 71 | * @param {String} `str` String to wrap with ansi codes. 72 | * @return {String} Wrapped string 73 | * @api public 74 | * @name bgcyan 75 | */ 76 | 77 | colors.bgcyan = require('ansi-bgcyan'); 78 | 79 | /** 80 | * Wrap a string with ansi codes to create a green background. 81 | * 82 | * ```js 83 | * console.log(colors.bggreen('some string')); 84 | * ``` 85 | * 86 | * @param {String} `str` String to wrap with ansi codes. 87 | * @return {String} Wrapped string 88 | * @api public 89 | * @name bggreen 90 | */ 91 | 92 | colors.bggreen = require('ansi-bggreen'); 93 | 94 | /** 95 | * Wrap a string with ansi codes to create a magenta background. 96 | * 97 | * ```js 98 | * console.log(colors.bgmagenta('some string')); 99 | * ``` 100 | * 101 | * @param {String} `str` String to wrap with ansi codes. 102 | * @return {String} Wrapped string 103 | * @api public 104 | * @name bgmagenta 105 | */ 106 | 107 | colors.bgmagenta = require('ansi-bgmagenta'); 108 | 109 | /** 110 | * Wrap a string with ansi codes to create a red background. 111 | * 112 | * ```js 113 | * console.log(colors.bgred('some string')); 114 | * ``` 115 | * 116 | * @param {String} `str` String to wrap with ansi codes. 117 | * @return {String} Wrapped string 118 | * @api public 119 | * @name bgred 120 | */ 121 | 122 | colors.bgred = require('ansi-bgred'); 123 | 124 | /** 125 | * Wrap a string with ansi codes to create a white background. 126 | * 127 | * ```js 128 | * console.log(colors.bgwhite('some string')); 129 | * ``` 130 | * 131 | * @param {String} `str` String to wrap with ansi codes. 132 | * @return {String} Wrapped string 133 | * @api public 134 | * @name bgwhite 135 | */ 136 | 137 | colors.bgwhite = require('ansi-bgwhite'); 138 | 139 | /** 140 | * Wrap a string with ansi codes to create a yellow background. 141 | * 142 | * ```js 143 | * console.log(colors.bgyellow('some string')); 144 | * ``` 145 | * 146 | * @param {String} `str` String to wrap with ansi codes. 147 | * @return {String} Wrapped string 148 | * @api public 149 | * @name bgyellow 150 | */ 151 | 152 | colors.bgyellow = require('ansi-bgyellow'); 153 | 154 | /** 155 | * Wrap a string with ansi codes to create black text. 156 | * 157 | * ```js 158 | * console.log(colors.black('some string')); 159 | * ``` 160 | * 161 | * @param {String} `str` String to wrap with ansi codes. 162 | * @return {String} Wrapped string 163 | * @api public 164 | * @name black 165 | */ 166 | 167 | colors.black = require('ansi-black'); 168 | 169 | /** 170 | * Wrap a string with ansi codes to create blue text. 171 | * 172 | * ```js 173 | * console.log(colors.blue('some string')); 174 | * ``` 175 | * 176 | * @param {String} `str` String to wrap with ansi codes. 177 | * @return {String} Wrapped string 178 | * @api public 179 | * @name blue 180 | */ 181 | 182 | colors.blue = require('ansi-blue'); 183 | 184 | /** 185 | * Wrap a string with ansi codes to create bold text. 186 | * 187 | * ```js 188 | * console.log(colors.bold('some string')); 189 | * ``` 190 | * 191 | * @param {String} `str` String to wrap with ansi codes. 192 | * @return {String} Wrapped string 193 | * @api public 194 | * @name bold 195 | */ 196 | 197 | colors.bold = require('ansi-bold'); 198 | 199 | /** 200 | * Wrap a string with ansi codes to create cyan text. 201 | * 202 | * ```js 203 | * console.log(colors.cyan('some string')); 204 | * ``` 205 | * 206 | * @param {String} `str` String to wrap with ansi codes. 207 | * @return {String} Wrapped string 208 | * @api public 209 | * @name cyan 210 | */ 211 | 212 | colors.cyan = require('ansi-cyan'); 213 | 214 | /** 215 | * Wrap a string with ansi codes to create dim text. 216 | * 217 | * ```js 218 | * console.log(colors.dim('some string')); 219 | * ``` 220 | * 221 | * @param {String} `str` String to wrap with ansi codes. 222 | * @return {String} Wrapped string 223 | * @api public 224 | * @name dim 225 | */ 226 | 227 | colors.dim = require('ansi-dim'); 228 | 229 | /** 230 | * Wrap a string with ansi codes to create gray text. 231 | * 232 | * ```js 233 | * console.log(colors.gray('some string')); 234 | * ``` 235 | * 236 | * @param {String} `str` String to wrap with ansi codes. 237 | * @return {String} Wrapped string 238 | * @api public 239 | * @name gray 240 | */ 241 | 242 | colors.gray = require('ansi-gray'); 243 | 244 | /** 245 | * Wrap a string with ansi codes to create green text. 246 | * 247 | * ```js 248 | * console.log(colors.green('some string')); 249 | * ``` 250 | * 251 | * @param {String} `str` String to wrap with ansi codes. 252 | * @return {String} Wrapped string 253 | * @api public 254 | * @name green 255 | */ 256 | 257 | colors.green = require('ansi-green'); 258 | 259 | /** 260 | * Wrap a string with ansi codes to create grey text. 261 | * 262 | * ```js 263 | * console.log(colors.grey('some string')); 264 | * ``` 265 | * 266 | * @param {String} `str` String to wrap with ansi codes. 267 | * @return {String} Wrapped string 268 | * @api public 269 | * @name grey 270 | */ 271 | 272 | colors.grey = require('ansi-grey'); 273 | 274 | /** 275 | * Wrap a string with ansi codes to create hidden text. 276 | * 277 | * ```js 278 | * console.log(colors.hidden('some string')); 279 | * ``` 280 | * 281 | * @param {String} `str` String to wrap with ansi codes. 282 | * @return {String} Wrapped string 283 | * @api public 284 | * @name hidden 285 | */ 286 | 287 | colors.hidden = require('ansi-hidden'); 288 | 289 | /** 290 | * Wrap a string with ansi codes to create inverse text. 291 | * 292 | * ```js 293 | * console.log(colors.inverse('some string')); 294 | * ``` 295 | * 296 | * @param {String} `str` String to wrap with ansi codes. 297 | * @return {String} Wrapped string 298 | * @api public 299 | * @name inverse 300 | */ 301 | 302 | colors.inverse = require('ansi-inverse'); 303 | 304 | /** 305 | * Wrap a string with ansi codes to create italic text. 306 | * 307 | * ```js 308 | * console.log(colors.italic('some string')); 309 | * ``` 310 | * 311 | * @param {String} `str` String to wrap with ansi codes. 312 | * @return {String} Wrapped string 313 | * @api public 314 | * @name italic 315 | */ 316 | 317 | colors.italic = require('ansi-italic'); 318 | 319 | /** 320 | * Wrap a string with ansi codes to create magenta text. 321 | * 322 | * ```js 323 | * console.log(colors.magenta('some string')); 324 | * ``` 325 | * 326 | * @param {String} `str` String to wrap with ansi codes. 327 | * @return {String} Wrapped string 328 | * @api public 329 | * @name magenta 330 | */ 331 | 332 | colors.magenta = require('ansi-magenta'); 333 | 334 | /** 335 | * Wrap a string with ansi codes to create red text. 336 | * 337 | * ```js 338 | * console.log(colors.red('some string')); 339 | * ``` 340 | * 341 | * @param {String} `str` String to wrap with ansi codes. 342 | * @return {String} Wrapped string 343 | * @api public 344 | * @name red 345 | */ 346 | 347 | colors.red = require('ansi-red'); 348 | 349 | /** 350 | * Wrap a string with ansi codes to reset ansi colors currently on the string. 351 | * 352 | * ```js 353 | * console.log(colors.reset('some string')); 354 | * ``` 355 | * 356 | * @param {String} `str` String to wrap with ansi codes. 357 | * @return {String} Wrapped string 358 | * @api public 359 | * @name reset 360 | */ 361 | 362 | colors.reset = require('ansi-reset'); 363 | 364 | /** 365 | * Wrap a string with ansi codes to add a strikethrough to the text. 366 | * 367 | * ```js 368 | * console.log(colors.strikethrough('some string')); 369 | * ``` 370 | * 371 | * @param {String} `str` String to wrap with ansi codes. 372 | * @return {String} Wrapped string 373 | * @api public 374 | * @name strikethrough 375 | */ 376 | 377 | colors.strikethrough = require('ansi-strikethrough'); 378 | 379 | /** 380 | * Wrap a string with ansi codes to underline the text. 381 | * 382 | * ```js 383 | * console.log(colors.underline('some string')); 384 | * ``` 385 | * 386 | * @param {String} `str` String to wrap with ansi codes. 387 | * @return {String} Wrapped string 388 | * @api public 389 | * @name underline 390 | */ 391 | 392 | colors.underline = require('ansi-underline'); 393 | 394 | /** 395 | * Wrap a string with ansi codes to create white text. 396 | * 397 | * ```js 398 | * console.log(colors.white('some string')); 399 | * ``` 400 | * 401 | * @param {String} `str` String to wrap with ansi codes. 402 | * @return {String} Wrapped string 403 | * @api public 404 | * @name white 405 | */ 406 | 407 | colors.white = require('ansi-white'); 408 | 409 | /** 410 | * Wrap a string with ansi codes to create yellow text. 411 | * 412 | * ```js 413 | * console.log(colors.yellow('some string')); 414 | * ``` 415 | * 416 | * @param {String} `str` String to wrap with ansi codes. 417 | * @return {String} Wrapped string 418 | * @api public 419 | * @name yellow 420 | */ 421 | 422 | colors.yellow = require('ansi-yellow'); 423 | 424 | /** 425 | * Restore `require` 426 | */ 427 | 428 | 429 | 430 | /** 431 | * Expose `colors` modules 432 | */ 433 | 434 | module.exports = colors; 435 | -------------------------------------------------------------------------------- /test/actual/bottom.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | 7 | var lazy = {}; 8 | lazy.merge = require('mixin-deep'); 9 | lazy.through = require('through2'); 10 | lazy.File = require('vinyl'); 11 | module.exports = lazy; 12 | -------------------------------------------------------------------------------- /test/actual/many.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | 5 | /** 6 | * Lazily required module dependencies 7 | */ 8 | 9 | var lazy = {}; 10 | 11 | // object/array/type utils 12 | lazy.clone = require('clone'); 13 | lazy.isBuffer = require('is-buffer'); 14 | lazy.paginationator = require('paginationator'); 15 | lazy.sortBy = require('array-sort'); 16 | lazy.groupBy = require('group-array'); 17 | lazy.define = require('define-property'); 18 | lazy.merge = require('mixin-deep'); 19 | lazy.extend = require('extend-shallow'); 20 | lazy.reduce = require('object.reduce'); 21 | 22 | // routing 23 | lazy.router = require('en-route'); 24 | 25 | // engines, templates and helpers 26 | lazy.loader = require('load-helpers'); 27 | lazy.engine = require('engine-base'); 28 | lazy.Engines = require('engine-cache'); 29 | lazy.Helpers = require('helper-cache'); 30 | lazy.rethrow = require('template-error'); 31 | lazy.inflect = require('inflection'); 32 | lazy.layouts = require('layouts'); 33 | 34 | // glob/matching utils 35 | lazy.globby = require('globby'); 36 | lazy.mm = require('micromatch'); 37 | lazy.isValidGlob = require('is-valid-glob'); 38 | lazy.hasGlob = require('has-glob'); 39 | 40 | /** 41 | * Utils 42 | */ 43 | 44 | var utils = lazy; 45 | 46 | /** 47 | * Default router methods used in all Template instances 48 | */ 49 | 50 | utils.methods = [ 51 | 'onLoad', 52 | 'preCompile', 53 | 'preLayout', 54 | 'onLayout', 55 | 'postLayout', 56 | 'onMerge', 57 | 'postCompile', 58 | 'preRender', 59 | 'postRender' 60 | ]; 61 | 62 | /** 63 | * FILE / GLOB UTILS 64 | * -------------------------------- 65 | */ 66 | 67 | /** 68 | * Resolve the absolute file paths for a glob of files. 69 | */ 70 | 71 | utils.resolveGlob = function resolveGlob(patterns, options) { 72 | var opts = utils.extend({cwd: process.cwd()}, options); 73 | return utils.globby.sync(patterns, opts).map(function (fp) { 74 | return path.resolve(opts.cwd, fp); 75 | }); 76 | }; 77 | 78 | /** 79 | * Require a glob of files 80 | */ 81 | 82 | utils.requireGlob = function requireGlob(patterns, options) { 83 | return utils.resolveGlob(patterns, options).reduce(function (acc, fp) { 84 | if (/\.(js(?:on)?)/.test(fp)) { 85 | acc[utils.rename(fp, options)] = utils.tryRequire(fp); 86 | } 87 | return acc; 88 | }, {}); 89 | }; 90 | 91 | /** 92 | * Attempt to require a file. Fail silently. 93 | */ 94 | 95 | utils.tryRequire = function tryRequire(fp, opts) { 96 | try { 97 | return require(fp); 98 | } catch(err) { 99 | try { 100 | opts = opts || {}; 101 | fp = path.resolve(fp); 102 | return require(fp); 103 | } catch(err) {} 104 | } 105 | return null; 106 | }; 107 | 108 | /** 109 | * OBJECT / ARRAY / TYPE UTILS 110 | * -------------------------------- 111 | */ 112 | 113 | /** 114 | * Format an error object. 115 | */ 116 | 117 | utils.error = function error(msg, val) { 118 | return new Error(msg + JSON.stringify(val)); 119 | }; 120 | 121 | /** 122 | * Do nothing. 123 | */ 124 | 125 | utils.noop = function noop() {}; 126 | 127 | /** 128 | * Return the given value as-is. 129 | */ 130 | 131 | utils.identity = function identity(val) { 132 | return val; 133 | }; 134 | 135 | /** 136 | * Arrayify the given value by casting it to an array. 137 | */ 138 | 139 | utils.arrayify = function arrayify(val) { 140 | return val ? (Array.isArray(val) ? val : [val]) : []; 141 | }; 142 | 143 | /** 144 | * Returns true if an array have the given element 145 | * @return {Boolean} 146 | */ 147 | 148 | utils.has = function has(keys, key) { 149 | return keys.indexOf(key) > -1; 150 | }; 151 | 152 | /** 153 | * Return true if the given value is an object. 154 | * @return {Boolean} 155 | */ 156 | 157 | utils.isObject = function isObject(val) { 158 | return val && (typeof val === 'function' || typeof val === 'object') 159 | && !Array.isArray(val); 160 | }; 161 | 162 | /** 163 | * Return true if the given value is a stream. 164 | */ 165 | 166 | utils.isStream = function isStream(val) { 167 | return val && (typeof val === 'function' || typeof val === 'object') 168 | && !Array.isArray(val) 169 | && (typeof val.pipe === 'function') 170 | && (typeof val.on === 'function'); 171 | }; 172 | 173 | /** 174 | * Bind a `thisArg` to all the functions on the target 175 | * 176 | * @param {Object|Array} `target` Object or Array with functions as values that will be bound. 177 | * @param {Object} `thisArg` Object to bind to the functions 178 | * @return {Object|Array} Object or Array with bound functions. 179 | */ 180 | 181 | utils.bindAll = function bindAll(target, thisArg) { 182 | return utils.reduce(target, function (acc, fn, key) { 183 | if (typeof fn === 'object') { 184 | acc[key] = utils.bindAll(fn, thisArg); 185 | } else if (typeof fn === 'function') { 186 | acc[key] = fn.bind(thisArg); 187 | // get `async` flag or any other helper options on `fn` 188 | for (var k in fn) acc[key][k] = fn[k]; 189 | } 190 | return acc; 191 | }, {}); 192 | }; 193 | 194 | 195 | /** 196 | * VIEW UTILS 197 | * -------------------------------- 198 | */ 199 | 200 | /** 201 | * Rename a file 202 | */ 203 | 204 | utils.rename = function rename(fp, options) { 205 | var opts = utils.extend({renameFn: name}, options); 206 | return opts.renameFn(fp); 207 | }; 208 | 209 | /** 210 | * Singularize the given `name` 211 | */ 212 | 213 | utils.single = function single(name) { 214 | return utils.inflect.singularize(name); 215 | }; 216 | 217 | /** 218 | * Pluralize the given `name` 219 | */ 220 | 221 | utils.plural = function plural(name) { 222 | return utils.inflect.pluralize(name); 223 | }; 224 | 225 | /** 226 | * Return true if the given value is a view. 227 | */ 228 | 229 | utils.isView = function isView(val) { 230 | return val && val.hasOwnProperty('content') 231 | || val.hasOwnProperty('contents') 232 | || val.hasOwnProperty('path'); 233 | }; 234 | 235 | * 236 | * Return true if the given value is a view. 237 | 238 | 239 | utils.hasView = function hasView(val) { 240 | var keys = Object.keys(val); 241 | if (keys.length > 1) return false; 242 | return utils.isView(val[keys[0]]); 243 | }; 244 | 245 | /** 246 | * Return the first object with a key that matches 247 | * the given glob pattern. 248 | * 249 | * @param {Object} `object` 250 | * @param {String|Array} `patterns` 251 | * @param {Object} `options` 252 | * @return {Object} 253 | */ 254 | 255 | utils.matchKey = function matchKey(obj, patterns, options) { 256 | if (!utils.isObject(obj)) return null; 257 | var keys = utils.mm(Object.keys(obj), patterns, options); 258 | return obj[keys[0]]; 259 | }; 260 | 261 | /** 262 | * Return all objects with keys that match 263 | * the given glob pattern. 264 | * 265 | * @param {Object} `object` 266 | * @param {String|Array} `patterns` 267 | * @param {Object} `options` 268 | * @return {Object} 269 | */ 270 | 271 | utils.matchKeys = function matchKeys(obj, patterns, options) { 272 | var keys = utils.mm(Object.keys(obj), patterns, options).sort(); 273 | var len = keys.length, i = 0; 274 | var res = {}; 275 | 276 | while (len--) { 277 | var key = keys[i++]; 278 | res[key] = obj[key]; 279 | } 280 | return res; 281 | }; 282 | 283 | /** 284 | * Sync the _content and _contents properties on a view to ensure 285 | * both are set when setting one. 286 | * 287 | * @param {Object} `view` instance of a `View` 288 | * @param {String|Buffer|Stream|null} `contents` contents to set on both properties 289 | */ 290 | 291 | utils.syncContents = function syncContents(view, contents) { 292 | if (contents === null) { 293 | view._contents = null; 294 | view._content = null; 295 | } 296 | if (typeof contents === 'string') { 297 | view._contents = new Buffer(contents); 298 | view._content = contents; 299 | } 300 | if (utils.isBuffer(contents)) { 301 | view._contents = contents; 302 | view._content = contents.toString(); 303 | } 304 | if (utils.isStream(contents)) { 305 | view._contents = contents; 306 | // what should be done here? 307 | view._content = contents; 308 | } 309 | }; 310 | 311 | /** 312 | * Return true if the given value is a view. 313 | */ 314 | 315 | utils.renameKey = function(app) { 316 | utils.define(app, 'renameKey', function renameKey(key, fn) { 317 | if (typeof key === 'function') { 318 | fn = key; 319 | key = null; 320 | } 321 | 322 | if (this.option && typeof fn !== 'function') { 323 | fn = this.option('renameKey'); 324 | } 325 | if (typeof fn !== 'function') { 326 | fn = utils.identity; 327 | } 328 | 329 | this.options.renameKey = fn; 330 | if (typeof key === 'string') { 331 | return fn(key); 332 | } 333 | return fn; 334 | }.bind(app)); 335 | }; 336 | 337 | /** 338 | * Set or get an option value. This is a factory for 339 | * adding an `option` method to a class 340 | */ 341 | 342 | utils.option = function option(app, prop) { 343 | utils.define(app, 'option', function(key, value) { 344 | if (typeof key === 'string') { 345 | if (arguments.length === 1) { 346 | return this.get('options.' + key); 347 | } 348 | this.set('options.' + key, value); 349 | this.emit('option', key, value); 350 | return this; 351 | } 352 | if (typeof key !== 'object') { 353 | throw new TypeError('expected a string or object.'); 354 | } 355 | this.visit('option', key); 356 | return this; 357 | }.bind(app)); 358 | }; 359 | 360 | /** 361 | * Ensure file extensions are formatted properly for lookups. 362 | * 363 | * ```js 364 | * utils.formatExt('hbs'); 365 | * //=> '.hbs' 366 | * 367 | * utils.formatExt('.hbs'); 368 | * //=> '.hbs' 369 | * ``` 370 | * 371 | * @param {String} `ext` File extension 372 | * @return {String} 373 | * @api public 374 | */ 375 | 376 | utils.formatExt = function formatExt(ext) { 377 | if (typeof ext !== 'string') { 378 | throw new Error('utils.formatExt() expects `ext` to be a string.'); 379 | } 380 | if (ext.charAt(0) !== '.') { 381 | return '.' + ext; 382 | } 383 | return ext; 384 | }; 385 | 386 | /** 387 | * Strip the dot from a file extension 388 | * 389 | * ```js 390 | * utils.stripDot('.hbs'); 391 | * //=> 'hbs' 392 | * ``` 393 | * 394 | * @param {String} `ext` extension 395 | * @return {String} 396 | * @api public 397 | */ 398 | 399 | utils.stripDot = function stripDot(ext) { 400 | if (typeof ext !== 'string') { 401 | throw new Error('utils.stripDot() expects `ext` to be a string.'); 402 | } 403 | if (ext.charAt(0) === '.') { 404 | return ext.slice(1); 405 | } 406 | return ext; 407 | }; 408 | 409 | /** 410 | * Get locals from helper arguments. 411 | * 412 | * @param {Object} `locals` 413 | * @param {Object} `options` 414 | */ 415 | 416 | utils.getLocals = function getLocals(locals, options) { 417 | options = options || {}; 418 | locals = locals || {}; 419 | var ctx = {}; 420 | 421 | if (options.hasOwnProperty('hash')) { 422 | utils.extend(ctx, locals); 423 | utils.extend(ctx, options.hash); 424 | 425 | } else if (locals.hasOwnProperty('hash')) { 426 | utils.extend(ctx, locals.hash); 427 | 428 | } else if (!locals.hasOwnProperty('hash') && !options.hasOwnProperty('hash')) { 429 | utils.extend(ctx, options); 430 | utils.extend(ctx, locals); 431 | } 432 | return ctx; 433 | }; 434 | 435 | /** 436 | * Get the basename from a filepath, excluding extension. 437 | */ 438 | 439 | function name(fp) { 440 | return path.basename(fp, path.extname(fp)); 441 | } 442 | 443 | /** 444 | * Expose utils 445 | */ 446 | 447 | module.exports = lazy; 448 | -------------------------------------------------------------------------------- /test/actual/markdown-toc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | 7 | var utils = {}; 8 | 9 | 10 | 11 | /** 12 | * Lazily required module dependencies 13 | */ 14 | 15 | utils.minimist = require('minimist'); 16 | utils.Remarkable = require('remarkable'); 17 | utils.repeat = require('repeat-string'); 18 | utils.mdlink = require('markdown-link'); 19 | utils.concat = require('concat-stream'); 20 | utils.matter = require('gray-matter'); 21 | utils.pick = require('object.pick'); 22 | utils.merge = require('mixin-deep'); 23 | utils.li = require('list-item'); 24 | 25 | 26 | /** 27 | * Expose `utils` modules 28 | */ 29 | 30 | module.exports = utils; 31 | -------------------------------------------------------------------------------- /test/actual/non-lazy.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | 5 | /** 6 | * Module dependencies 7 | */ 8 | 9 | var utils = {}; 10 | 11 | 12 | 13 | utils.merge = require('mixin-deep'); 14 | utils.through = require('through2'); 15 | utils.File = require('vinyl'); 16 | 17 | utils.foo = function() { 18 | 19 | }; 20 | 21 | module.exports = utils; 22 | -------------------------------------------------------------------------------- /test/actual/normal.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | 5 | /** 6 | * Utils 7 | */ 8 | 9 | var utils = {}; 10 | 11 | // object/array/type utils 12 | utils.clone = require('clone'); 13 | utils.isBuffer = require('is-buffer'); 14 | utils.paginationator = require('paginationator'); 15 | utils.sortBy = require('array-sort'); 16 | utils.groupBy = require('group-array'); 17 | utils.define = require('define-property'); 18 | utils.merge = require('mixin-deep'); 19 | utils.extend = require('extend-shallow'); 20 | utils.reduce = require('object.reduce'); 21 | 22 | // routing 23 | utils.router = require('en-route'); 24 | 25 | // engines, templates and helpers 26 | utils.loader = require('load-helpers'); 27 | utils.engine = require('engine-base'); 28 | utils.Engines = require('engine-cache'); 29 | utils.Helpers = require('helper-cache'); 30 | utils.rethrow = require('template-error'); 31 | utils.inflect = require('inflection'); 32 | utils.layouts = require('layouts'); 33 | 34 | // glob/matching utils 35 | utils.globby = require('globby'); 36 | utils.mm = require('micromatch'); 37 | utils.isValidGlob = require('is-valid-glob'); 38 | utils.hasGlob = require('has-glob'); 39 | 40 | /** 41 | * Default router methods used in all Template instances 42 | */ 43 | 44 | utils.methods = [ 45 | 'onLoad', 46 | 'preCompile', 47 | 'preLayout', 48 | 'onLayout', 49 | 'postLayout', 50 | 'onMerge', 51 | 'postCompile', 52 | 'preRender', 53 | 'postRender' 54 | ]; 55 | 56 | /** 57 | * FILE / GLOB UTILS 58 | * -------------------------------- 59 | */ 60 | 61 | /** 62 | * Resolve the absolute file paths for a glob of files. 63 | */ 64 | 65 | utils.resolveGlob = function resolveGlob(patterns, options) { 66 | var opts = utils.extend({cwd: process.cwd()}, options); 67 | return utils.globby.sync(patterns, opts).map(function (fp) { 68 | return path.resolve(opts.cwd, fp); 69 | }); 70 | }; 71 | 72 | /** 73 | * Require a glob of files 74 | */ 75 | 76 | utils.requireGlob = function requireGlob(patterns, options) { 77 | return utils.resolveGlob(patterns, options).reduce(function (acc, fp) { 78 | if (/\.(js(?:on)?)/.test(fp)) { 79 | acc[utils.rename(fp, options)] = utils.tryRequire(fp); 80 | } 81 | return acc; 82 | }, {}); 83 | }; 84 | 85 | /** 86 | * Attempt to require a file. Fail silently. 87 | */ 88 | 89 | utils.tryRequire = function tryRequire(fp, opts) { 90 | try { 91 | return require(fp); 92 | } catch(err) { 93 | try { 94 | opts = opts || {}; 95 | fp = path.resolve(fp); 96 | return require(fp); 97 | } catch(err) {} 98 | } 99 | return null; 100 | }; 101 | 102 | /** 103 | * OBJECT / ARRAY / TYPE UTILS 104 | * -------------------------------- 105 | */ 106 | 107 | /** 108 | * Format an error object. 109 | */ 110 | 111 | utils.error = function error(msg, val) { 112 | return new Error(msg + JSON.stringify(val)); 113 | }; 114 | 115 | /** 116 | * Do nothing. 117 | */ 118 | 119 | utils.noop = function noop() {}; 120 | 121 | /** 122 | * Return the given value as-is. 123 | */ 124 | 125 | utils.identity = function identity(val) { 126 | return val; 127 | }; 128 | 129 | /** 130 | * Arrayify the given value by casting it to an array. 131 | */ 132 | 133 | utils.arrayify = function arrayify(val) { 134 | return val ? (Array.isArray(val) ? val : [val]) : []; 135 | }; 136 | 137 | /** 138 | * Returns true if an array have the given element 139 | * @return {Boolean} 140 | */ 141 | 142 | utils.has = function has(keys, key) { 143 | return keys.indexOf(key) > -1; 144 | }; 145 | 146 | /** 147 | * Return true if the given value is an object. 148 | * @return {Boolean} 149 | */ 150 | 151 | utils.isObject = function isObject(val) { 152 | return val && (typeof val === 'function' || typeof val === 'object') 153 | && !Array.isArray(val); 154 | }; 155 | 156 | /** 157 | * Return true if the given value is a stream. 158 | */ 159 | 160 | utils.isStream = function isStream(val) { 161 | return val && (typeof val === 'function' || typeof val === 'object') 162 | && !Array.isArray(val) 163 | && (typeof val.pipe === 'function') 164 | && (typeof val.on === 'function'); 165 | }; 166 | 167 | /** 168 | * Bind a `thisArg` to all the functions on the target 169 | * 170 | * @param {Object|Array} `target` Object or Array with functions as values that will be bound. 171 | * @param {Object} `thisArg` Object to bind to the functions 172 | * @return {Object|Array} Object or Array with bound functions. 173 | */ 174 | 175 | utils.bindAll = function bindAll(target, thisArg) { 176 | return utils.reduce(target, function (acc, fn, key) { 177 | if (typeof fn === 'object') { 178 | acc[key] = utils.bindAll(fn, thisArg); 179 | } else if (typeof fn === 'function') { 180 | acc[key] = fn.bind(thisArg); 181 | // get `async` flag or any other helper options on `fn` 182 | for (var k in fn) acc[key][k] = fn[k]; 183 | } 184 | return acc; 185 | }, {}); 186 | }; 187 | 188 | /** 189 | * VIEW UTILS 190 | * -------------------------------- 191 | */ 192 | 193 | /** 194 | * Rename a file 195 | */ 196 | 197 | utils.rename = function rename(fp, options) { 198 | var opts = utils.extend({renameFn: name}, options); 199 | return opts.renameFn(fp); 200 | }; 201 | 202 | /** 203 | * Singularize the given `name` 204 | */ 205 | 206 | utils.single = function single(name) { 207 | return utils.inflect.singularize(name); 208 | }; 209 | 210 | /** 211 | * Pluralize the given `name` 212 | */ 213 | 214 | utils.plural = function plural(name) { 215 | return utils.inflect.pluralize(name); 216 | }; 217 | 218 | /** 219 | * Return true if the given value is a view. 220 | */ 221 | 222 | utils.isView = function isView(val) { 223 | return val && val.hasOwnProperty('content') 224 | || val.hasOwnProperty('contents') 225 | || val.hasOwnProperty('path'); 226 | }; 227 | 228 | /** 229 | * Return true if the given value is a view. 230 | */ 231 | 232 | utils.hasView = function hasView(val) { 233 | var keys = Object.keys(val); 234 | if (keys.length > 1) return false; 235 | return utils.isView(val[keys[0]]); 236 | }; 237 | 238 | /** 239 | * Return the first object with a key that matches 240 | * the given glob pattern. 241 | * 242 | * @param {Object} `object` 243 | * @param {String|Array} `patterns` 244 | * @param {Object} `options` 245 | * @return {Object} 246 | */ 247 | 248 | utils.matchKey = function matchKey(obj, patterns, options) { 249 | if (!utils.isObject(obj)) return null; 250 | var keys = utils.mm(Object.keys(obj), patterns, options); 251 | return obj[keys[0]]; 252 | }; 253 | 254 | /** 255 | * Return all objects with keys that match 256 | * the given glob pattern. 257 | * 258 | * @param {Object} `object` 259 | * @param {String|Array} `patterns` 260 | * @param {Object} `options` 261 | * @return {Object} 262 | */ 263 | 264 | utils.matchKeys = function matchKeys(obj, patterns, options) { 265 | var keys = utils.mm(Object.keys(obj), patterns, options).sort(); 266 | var len = keys.length, i = 0; 267 | var res = {}; 268 | 269 | while (len--) { 270 | var key = keys[i++]; 271 | res[key] = obj[key]; 272 | } 273 | return res; 274 | }; 275 | 276 | /** 277 | * Sync the _content and _contents properties on a view to ensure 278 | * both are set when setting one. 279 | * 280 | * @param {Object} `view` instance of a `View` 281 | * @param {String|Buffer|Stream|null} `contents` contents to set on both properties 282 | */ 283 | 284 | utils.syncContents = function syncContents(view, contents) { 285 | if (contents === null) { 286 | view._contents = null; 287 | view._content = null; 288 | } 289 | if (typeof contents === 'string') { 290 | view._contents = new Buffer(contents); 291 | view._content = contents; 292 | } 293 | if (utils.isBuffer(contents)) { 294 | view._contents = contents; 295 | view._content = contents.toString(); 296 | } 297 | if (utils.isStream(contents)) { 298 | view._contents = contents; 299 | // what should be done here? 300 | view._content = contents; 301 | } 302 | }; 303 | 304 | /** 305 | * Return true if the given value is a view. 306 | */ 307 | 308 | utils.renameKey = function(app) { 309 | utils.define(app, 'renameKey', function renameKey(key, fn) { 310 | if (typeof key === 'function') { 311 | fn = key; 312 | key = null; 313 | } 314 | 315 | if (this.option && typeof fn !== 'function') { 316 | fn = this.option('renameKey'); 317 | } 318 | if (typeof fn !== 'function') { 319 | fn = utils.identity; 320 | } 321 | 322 | this.options.renameKey = fn; 323 | if (typeof key === 'string') { 324 | return fn(key); 325 | } 326 | return fn; 327 | }.bind(app)); 328 | }; 329 | 330 | /** 331 | * Set or get an option value. This is a factory for 332 | * adding an `option` method to a class 333 | */ 334 | 335 | utils.option = function option(app, prop) { 336 | utils.define(app, 'option', function(key, value) { 337 | if (typeof key === 'string') { 338 | if (arguments.length === 1) { 339 | return this.get('options.' + key); 340 | } 341 | this.set('options.' + key, value); 342 | this.emit('option', key, value); 343 | return this; 344 | } 345 | if (typeof key !== 'object') { 346 | throw new TypeError('expected a string or object.'); 347 | } 348 | this.visit('option', key); 349 | return this; 350 | }.bind(app)); 351 | }; 352 | 353 | /** 354 | * Ensure file extensions are formatted properly for lookups. 355 | * 356 | * ```js 357 | * utils.formatExt('hbs'); 358 | * //=> '.hbs' 359 | * 360 | * utils.formatExt('.hbs'); 361 | * //=> '.hbs' 362 | * ``` 363 | * 364 | * @param {String} `ext` File extension 365 | * @return {String} 366 | * @api public 367 | */ 368 | 369 | utils.formatExt = function formatExt(ext) { 370 | if (typeof ext !== 'string') { 371 | throw new Error('utils.formatExt() expects `ext` to be a string.'); 372 | } 373 | if (ext.charAt(0) !== '.') { 374 | return '.' + ext; 375 | } 376 | return ext; 377 | }; 378 | 379 | /** 380 | * Strip the dot from a file extension 381 | * 382 | * ```js 383 | * utils.stripDot('.hbs'); 384 | * //=> 'hbs' 385 | * ``` 386 | * 387 | * @param {String} `ext` extension 388 | * @return {String} 389 | * @api public 390 | */ 391 | 392 | utils.stripDot = function stripDot(ext) { 393 | if (typeof ext !== 'string') { 394 | throw new Error('utils.stripDot() expects `ext` to be a string.'); 395 | } 396 | if (ext.charAt(0) === '.') { 397 | return ext.slice(1); 398 | } 399 | return ext; 400 | }; 401 | 402 | /** 403 | * Get locals from helper arguments. 404 | * 405 | * @param {Object} `locals` 406 | * @param {Object} `options` 407 | */ 408 | 409 | utils.getLocals = function getLocals(locals, options) { 410 | options = options || {}; 411 | locals = locals || {}; 412 | var ctx = {}; 413 | 414 | if (options.hasOwnProperty('hash')) { 415 | utils.extend(ctx, locals); 416 | utils.extend(ctx, options.hash); 417 | 418 | } else if (locals.hasOwnProperty('hash')) { 419 | utils.extend(ctx, locals.hash); 420 | 421 | } else if (!locals.hasOwnProperty('hash') && !options.hasOwnProperty('hash')) { 422 | utils.extend(ctx, options); 423 | utils.extend(ctx, locals); 424 | } 425 | return ctx; 426 | }; 427 | 428 | /** 429 | * Get the basename from a filepath, excluding extension. 430 | */ 431 | 432 | function name(fp) { 433 | return path.basename(fp, path.extname(fp)); 434 | } 435 | 436 | /** 437 | * Expose utils 438 | */ 439 | 440 | module.exports = utils; 441 | -------------------------------------------------------------------------------- /test/actual/separate.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | 7 | var lazy = {}; 8 | lazy.merge = require('mixin-deep'); 9 | lazy.through = require('through2'); 10 | lazy.File = require('vinyl'); 11 | 12 | var utils = lazy; 13 | 14 | utils.foo = function () { 15 | 16 | }; 17 | 18 | module.exports = utils; 19 | -------------------------------------------------------------------------------- /test/actual/top.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | 7 | var lazy = {}; 8 | lazy.merge = require('mixin-deep'); 9 | lazy.through = require('through2'); 10 | lazy.File = require('vinyl'); 11 | module.exports = lazy; -------------------------------------------------------------------------------- /test/fixtures/ansi-colors.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * ansi-colors 3 | * 4 | * Copyright (c) 2015, Brian Woodward. 5 | * Licensed under the MIT License. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | /** 11 | * Module dependencies 12 | */ 13 | 14 | var colors = require('lazy-cache')(require); 15 | 16 | /** 17 | * Temporarily re-assign `require` to trick browserify and 18 | * webpack into reconizing lazy dependencies. 19 | * 20 | * This tiny bit of ugliness has the huge dual advantage of 21 | * only loading modules that are actually called at some 22 | * point in the lifecycle of the application, whilst also 23 | * allowing browserify and webpack to find modules that 24 | * are depended on but never actually called. 25 | */ 26 | 27 | var fn = require; 28 | require = colors; 29 | 30 | /** 31 | * Lazily required module dependencies 32 | */ 33 | 34 | /** 35 | * Wrap a string with ansi codes to create a black background. 36 | * 37 | * ```js 38 | * console.log(colors.bgblack('some string')); 39 | * ``` 40 | * 41 | * @param {String} `str` String to wrap with ansi codes. 42 | * @return {String} Wrapped string 43 | * @api public 44 | * @name bgblack 45 | */ 46 | 47 | require('ansi-bgblack', 'bgblack'); 48 | 49 | /** 50 | * Wrap a string with ansi codes to create a blue background. 51 | * 52 | * ```js 53 | * console.log(colors.bgblue('some string')); 54 | * ``` 55 | * 56 | * @param {String} `str` String to wrap with ansi codes. 57 | * @return {String} Wrapped string 58 | * @api public 59 | * @name bgblue 60 | */ 61 | 62 | require('ansi-bgblue', 'bgblue'); 63 | 64 | /** 65 | * Wrap a string with ansi codes to create a cyan background. 66 | * 67 | * ```js 68 | * console.log(colors.bgcyan('some string')); 69 | * ``` 70 | * 71 | * @param {String} `str` String to wrap with ansi codes. 72 | * @return {String} Wrapped string 73 | * @api public 74 | * @name bgcyan 75 | */ 76 | 77 | require('ansi-bgcyan', 'bgcyan'); 78 | 79 | /** 80 | * Wrap a string with ansi codes to create a green background. 81 | * 82 | * ```js 83 | * console.log(colors.bggreen('some string')); 84 | * ``` 85 | * 86 | * @param {String} `str` String to wrap with ansi codes. 87 | * @return {String} Wrapped string 88 | * @api public 89 | * @name bggreen 90 | */ 91 | 92 | require('ansi-bggreen', 'bggreen'); 93 | 94 | /** 95 | * Wrap a string with ansi codes to create a magenta background. 96 | * 97 | * ```js 98 | * console.log(colors.bgmagenta('some string')); 99 | * ``` 100 | * 101 | * @param {String} `str` String to wrap with ansi codes. 102 | * @return {String} Wrapped string 103 | * @api public 104 | * @name bgmagenta 105 | */ 106 | 107 | require('ansi-bgmagenta', 'bgmagenta'); 108 | 109 | /** 110 | * Wrap a string with ansi codes to create a red background. 111 | * 112 | * ```js 113 | * console.log(colors.bgred('some string')); 114 | * ``` 115 | * 116 | * @param {String} `str` String to wrap with ansi codes. 117 | * @return {String} Wrapped string 118 | * @api public 119 | * @name bgred 120 | */ 121 | 122 | require('ansi-bgred', 'bgred'); 123 | 124 | /** 125 | * Wrap a string with ansi codes to create a white background. 126 | * 127 | * ```js 128 | * console.log(colors.bgwhite('some string')); 129 | * ``` 130 | * 131 | * @param {String} `str` String to wrap with ansi codes. 132 | * @return {String} Wrapped string 133 | * @api public 134 | * @name bgwhite 135 | */ 136 | 137 | require('ansi-bgwhite', 'bgwhite'); 138 | 139 | /** 140 | * Wrap a string with ansi codes to create a yellow background. 141 | * 142 | * ```js 143 | * console.log(colors.bgyellow('some string')); 144 | * ``` 145 | * 146 | * @param {String} `str` String to wrap with ansi codes. 147 | * @return {String} Wrapped string 148 | * @api public 149 | * @name bgyellow 150 | */ 151 | 152 | require('ansi-bgyellow', 'bgyellow'); 153 | 154 | /** 155 | * Wrap a string with ansi codes to create black text. 156 | * 157 | * ```js 158 | * console.log(colors.black('some string')); 159 | * ``` 160 | * 161 | * @param {String} `str` String to wrap with ansi codes. 162 | * @return {String} Wrapped string 163 | * @api public 164 | * @name black 165 | */ 166 | 167 | require('ansi-black', 'black'); 168 | 169 | /** 170 | * Wrap a string with ansi codes to create blue text. 171 | * 172 | * ```js 173 | * console.log(colors.blue('some string')); 174 | * ``` 175 | * 176 | * @param {String} `str` String to wrap with ansi codes. 177 | * @return {String} Wrapped string 178 | * @api public 179 | * @name blue 180 | */ 181 | 182 | require('ansi-blue', 'blue'); 183 | 184 | /** 185 | * Wrap a string with ansi codes to create bold text. 186 | * 187 | * ```js 188 | * console.log(colors.bold('some string')); 189 | * ``` 190 | * 191 | * @param {String} `str` String to wrap with ansi codes. 192 | * @return {String} Wrapped string 193 | * @api public 194 | * @name bold 195 | */ 196 | 197 | require('ansi-bold', 'bold'); 198 | 199 | /** 200 | * Wrap a string with ansi codes to create cyan text. 201 | * 202 | * ```js 203 | * console.log(colors.cyan('some string')); 204 | * ``` 205 | * 206 | * @param {String} `str` String to wrap with ansi codes. 207 | * @return {String} Wrapped string 208 | * @api public 209 | * @name cyan 210 | */ 211 | 212 | require('ansi-cyan', 'cyan'); 213 | 214 | /** 215 | * Wrap a string with ansi codes to create dim text. 216 | * 217 | * ```js 218 | * console.log(colors.dim('some string')); 219 | * ``` 220 | * 221 | * @param {String} `str` String to wrap with ansi codes. 222 | * @return {String} Wrapped string 223 | * @api public 224 | * @name dim 225 | */ 226 | 227 | require('ansi-dim', 'dim'); 228 | 229 | /** 230 | * Wrap a string with ansi codes to create gray text. 231 | * 232 | * ```js 233 | * console.log(colors.gray('some string')); 234 | * ``` 235 | * 236 | * @param {String} `str` String to wrap with ansi codes. 237 | * @return {String} Wrapped string 238 | * @api public 239 | * @name gray 240 | */ 241 | 242 | require('ansi-gray', 'gray'); 243 | 244 | /** 245 | * Wrap a string with ansi codes to create green text. 246 | * 247 | * ```js 248 | * console.log(colors.green('some string')); 249 | * ``` 250 | * 251 | * @param {String} `str` String to wrap with ansi codes. 252 | * @return {String} Wrapped string 253 | * @api public 254 | * @name green 255 | */ 256 | 257 | require('ansi-green', 'green'); 258 | 259 | /** 260 | * Wrap a string with ansi codes to create grey text. 261 | * 262 | * ```js 263 | * console.log(colors.grey('some string')); 264 | * ``` 265 | * 266 | * @param {String} `str` String to wrap with ansi codes. 267 | * @return {String} Wrapped string 268 | * @api public 269 | * @name grey 270 | */ 271 | 272 | require('ansi-grey', 'grey'); 273 | 274 | /** 275 | * Wrap a string with ansi codes to create hidden text. 276 | * 277 | * ```js 278 | * console.log(colors.hidden('some string')); 279 | * ``` 280 | * 281 | * @param {String} `str` String to wrap with ansi codes. 282 | * @return {String} Wrapped string 283 | * @api public 284 | * @name hidden 285 | */ 286 | 287 | require('ansi-hidden', 'hidden'); 288 | 289 | /** 290 | * Wrap a string with ansi codes to create inverse text. 291 | * 292 | * ```js 293 | * console.log(colors.inverse('some string')); 294 | * ``` 295 | * 296 | * @param {String} `str` String to wrap with ansi codes. 297 | * @return {String} Wrapped string 298 | * @api public 299 | * @name inverse 300 | */ 301 | 302 | require('ansi-inverse', 'inverse'); 303 | 304 | /** 305 | * Wrap a string with ansi codes to create italic text. 306 | * 307 | * ```js 308 | * console.log(colors.italic('some string')); 309 | * ``` 310 | * 311 | * @param {String} `str` String to wrap with ansi codes. 312 | * @return {String} Wrapped string 313 | * @api public 314 | * @name italic 315 | */ 316 | 317 | require('ansi-italic', 'italic'); 318 | 319 | /** 320 | * Wrap a string with ansi codes to create magenta text. 321 | * 322 | * ```js 323 | * console.log(colors.magenta('some string')); 324 | * ``` 325 | * 326 | * @param {String} `str` String to wrap with ansi codes. 327 | * @return {String} Wrapped string 328 | * @api public 329 | * @name magenta 330 | */ 331 | 332 | require('ansi-magenta', 'magenta'); 333 | 334 | /** 335 | * Wrap a string with ansi codes to create red text. 336 | * 337 | * ```js 338 | * console.log(colors.red('some string')); 339 | * ``` 340 | * 341 | * @param {String} `str` String to wrap with ansi codes. 342 | * @return {String} Wrapped string 343 | * @api public 344 | * @name red 345 | */ 346 | 347 | require('ansi-red', 'red'); 348 | 349 | /** 350 | * Wrap a string with ansi codes to reset ansi colors currently on the string. 351 | * 352 | * ```js 353 | * console.log(colors.reset('some string')); 354 | * ``` 355 | * 356 | * @param {String} `str` String to wrap with ansi codes. 357 | * @return {String} Wrapped string 358 | * @api public 359 | * @name reset 360 | */ 361 | 362 | require('ansi-reset', 'reset'); 363 | 364 | /** 365 | * Wrap a string with ansi codes to add a strikethrough to the text. 366 | * 367 | * ```js 368 | * console.log(colors.strikethrough('some string')); 369 | * ``` 370 | * 371 | * @param {String} `str` String to wrap with ansi codes. 372 | * @return {String} Wrapped string 373 | * @api public 374 | * @name strikethrough 375 | */ 376 | 377 | require('ansi-strikethrough', 'strikethrough'); 378 | 379 | /** 380 | * Wrap a string with ansi codes to underline the text. 381 | * 382 | * ```js 383 | * console.log(colors.underline('some string')); 384 | * ``` 385 | * 386 | * @param {String} `str` String to wrap with ansi codes. 387 | * @return {String} Wrapped string 388 | * @api public 389 | * @name underline 390 | */ 391 | 392 | require('ansi-underline', 'underline'); 393 | 394 | /** 395 | * Wrap a string with ansi codes to create white text. 396 | * 397 | * ```js 398 | * console.log(colors.white('some string')); 399 | * ``` 400 | * 401 | * @param {String} `str` String to wrap with ansi codes. 402 | * @return {String} Wrapped string 403 | * @api public 404 | * @name white 405 | */ 406 | 407 | require('ansi-white', 'white'); 408 | 409 | /** 410 | * Wrap a string with ansi codes to create yellow text. 411 | * 412 | * ```js 413 | * console.log(colors.yellow('some string')); 414 | * ``` 415 | * 416 | * @param {String} `str` String to wrap with ansi codes. 417 | * @return {String} Wrapped string 418 | * @api public 419 | * @name yellow 420 | */ 421 | 422 | require('ansi-yellow', 'yellow'); 423 | 424 | /** 425 | * Restore `require` 426 | */ 427 | 428 | require = fn; 429 | 430 | /** 431 | * Expose `colors` modules 432 | */ 433 | 434 | module.exports = colors; 435 | -------------------------------------------------------------------------------- /test/fixtures/bottom.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | 7 | var lazy = require('lazy-cache')(require); 8 | lazy('mixin-deep', 'merge'); 9 | lazy('through2', 'through'); 10 | lazy('vinyl', 'File'); 11 | module.exports = lazy; 12 | -------------------------------------------------------------------------------- /test/fixtures/many.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | 5 | /** 6 | * Lazily required module dependencies 7 | */ 8 | 9 | var lazy = require('lazy-cache')(require); 10 | 11 | // object/array/type utils 12 | lazy('clone'); 13 | lazy('is-buffer'); 14 | lazy('paginationator'); 15 | lazy('array-sort', 'sortBy'); 16 | lazy('group-array', 'groupBy'); 17 | lazy('define-property', 'define'); 18 | lazy('mixin-deep', 'merge'); 19 | lazy('extend-shallow', 'extend'); 20 | lazy('object.reduce', 'reduce'); 21 | 22 | // routing 23 | lazy('en-route', 'router'); 24 | 25 | // engines, templates and helpers 26 | lazy('load-helpers', 'loader'); 27 | lazy('engine-base', 'engine'); 28 | lazy('engine-cache', 'Engines'); 29 | lazy('helper-cache', 'Helpers'); 30 | lazy('template-error', 'rethrow'); 31 | lazy('inflection', 'inflect'); 32 | lazy('layouts'); 33 | 34 | // glob/matching utils 35 | lazy('globby'); 36 | lazy('micromatch', 'mm'); 37 | lazy('is-valid-glob'); 38 | lazy('has-glob'); 39 | 40 | /** 41 | * Utils 42 | */ 43 | 44 | var utils = lazy; 45 | 46 | /** 47 | * Default router methods used in all Template instances 48 | */ 49 | 50 | utils.methods = [ 51 | 'onLoad', 52 | 'preCompile', 53 | 'preLayout', 54 | 'onLayout', 55 | 'postLayout', 56 | 'onMerge', 57 | 'postCompile', 58 | 'preRender', 59 | 'postRender' 60 | ]; 61 | 62 | /** 63 | * FILE / GLOB UTILS 64 | * -------------------------------- 65 | */ 66 | 67 | /** 68 | * Resolve the absolute file paths for a glob of files. 69 | */ 70 | 71 | utils.resolveGlob = function resolveGlob(patterns, options) { 72 | var opts = utils.extend({cwd: process.cwd()}, options); 73 | return utils.globby.sync(patterns, opts).map(function (fp) { 74 | return path.resolve(opts.cwd, fp); 75 | }); 76 | }; 77 | 78 | /** 79 | * Require a glob of files 80 | */ 81 | 82 | utils.requireGlob = function requireGlob(patterns, options) { 83 | return utils.resolveGlob(patterns, options).reduce(function (acc, fp) { 84 | if (/\.(js(?:on)?)/.test(fp)) { 85 | acc[utils.rename(fp, options)] = utils.tryRequire(fp); 86 | } 87 | return acc; 88 | }, {}); 89 | }; 90 | 91 | /** 92 | * Attempt to require a file. Fail silently. 93 | */ 94 | 95 | utils.tryRequire = function tryRequire(fp, opts) { 96 | try { 97 | return require(fp); 98 | } catch(err) { 99 | try { 100 | opts = opts || {}; 101 | fp = path.resolve(fp); 102 | return require(fp); 103 | } catch(err) {} 104 | } 105 | return null; 106 | }; 107 | 108 | /** 109 | * OBJECT / ARRAY / TYPE UTILS 110 | * -------------------------------- 111 | */ 112 | 113 | /** 114 | * Format an error object. 115 | */ 116 | 117 | utils.error = function error(msg, val) { 118 | return new Error(msg + JSON.stringify(val)); 119 | }; 120 | 121 | /** 122 | * Do nothing. 123 | */ 124 | 125 | utils.noop = function noop() {}; 126 | 127 | /** 128 | * Return the given value as-is. 129 | */ 130 | 131 | utils.identity = function identity(val) { 132 | return val; 133 | }; 134 | 135 | /** 136 | * Arrayify the given value by casting it to an array. 137 | */ 138 | 139 | utils.arrayify = function arrayify(val) { 140 | return val ? (Array.isArray(val) ? val : [val]) : []; 141 | }; 142 | 143 | /** 144 | * Returns true if an array have the given element 145 | * @return {Boolean} 146 | */ 147 | 148 | utils.has = function has(keys, key) { 149 | return keys.indexOf(key) > -1; 150 | }; 151 | 152 | /** 153 | * Return true if the given value is an object. 154 | * @return {Boolean} 155 | */ 156 | 157 | utils.isObject = function isObject(val) { 158 | return val && (typeof val === 'function' || typeof val === 'object') 159 | && !Array.isArray(val); 160 | }; 161 | 162 | /** 163 | * Return true if the given value is a stream. 164 | */ 165 | 166 | utils.isStream = function isStream(val) { 167 | return val && (typeof val === 'function' || typeof val === 'object') 168 | && !Array.isArray(val) 169 | && (typeof val.pipe === 'function') 170 | && (typeof val.on === 'function'); 171 | }; 172 | 173 | /** 174 | * Bind a `thisArg` to all the functions on the target 175 | * 176 | * @param {Object|Array} `target` Object or Array with functions as values that will be bound. 177 | * @param {Object} `thisArg` Object to bind to the functions 178 | * @return {Object|Array} Object or Array with bound functions. 179 | */ 180 | 181 | utils.bindAll = function bindAll(target, thisArg) { 182 | return utils.reduce(target, function (acc, fn, key) { 183 | if (typeof fn === 'object') { 184 | acc[key] = utils.bindAll(fn, thisArg); 185 | } else if (typeof fn === 'function') { 186 | acc[key] = fn.bind(thisArg); 187 | // get `async` flag or any other helper options on `fn` 188 | for (var k in fn) acc[key][k] = fn[k]; 189 | } 190 | return acc; 191 | }, {}); 192 | }; 193 | 194 | 195 | /** 196 | * VIEW UTILS 197 | * -------------------------------- 198 | */ 199 | 200 | /** 201 | * Rename a file 202 | */ 203 | 204 | utils.rename = function rename(fp, options) { 205 | var opts = utils.extend({renameFn: name}, options); 206 | return opts.renameFn(fp); 207 | }; 208 | 209 | /** 210 | * Singularize the given `name` 211 | */ 212 | 213 | utils.single = function single(name) { 214 | return utils.inflect.singularize(name); 215 | }; 216 | 217 | /** 218 | * Pluralize the given `name` 219 | */ 220 | 221 | utils.plural = function plural(name) { 222 | return utils.inflect.pluralize(name); 223 | }; 224 | 225 | /** 226 | * Return true if the given value is a view. 227 | */ 228 | 229 | utils.isView = function isView(val) { 230 | return val && val.hasOwnProperty('content') 231 | || val.hasOwnProperty('contents') 232 | || val.hasOwnProperty('path'); 233 | }; 234 | 235 | * 236 | * Return true if the given value is a view. 237 | 238 | 239 | utils.hasView = function hasView(val) { 240 | var keys = Object.keys(val); 241 | if (keys.length > 1) return false; 242 | return utils.isView(val[keys[0]]); 243 | }; 244 | 245 | /** 246 | * Return the first object with a key that matches 247 | * the given glob pattern. 248 | * 249 | * @param {Object} `object` 250 | * @param {String|Array} `patterns` 251 | * @param {Object} `options` 252 | * @return {Object} 253 | */ 254 | 255 | utils.matchKey = function matchKey(obj, patterns, options) { 256 | if (!utils.isObject(obj)) return null; 257 | var keys = utils.mm(Object.keys(obj), patterns, options); 258 | return obj[keys[0]]; 259 | }; 260 | 261 | /** 262 | * Return all objects with keys that match 263 | * the given glob pattern. 264 | * 265 | * @param {Object} `object` 266 | * @param {String|Array} `patterns` 267 | * @param {Object} `options` 268 | * @return {Object} 269 | */ 270 | 271 | utils.matchKeys = function matchKeys(obj, patterns, options) { 272 | var keys = utils.mm(Object.keys(obj), patterns, options).sort(); 273 | var len = keys.length, i = 0; 274 | var res = {}; 275 | 276 | while (len--) { 277 | var key = keys[i++]; 278 | res[key] = obj[key]; 279 | } 280 | return res; 281 | }; 282 | 283 | /** 284 | * Sync the _content and _contents properties on a view to ensure 285 | * both are set when setting one. 286 | * 287 | * @param {Object} `view` instance of a `View` 288 | * @param {String|Buffer|Stream|null} `contents` contents to set on both properties 289 | */ 290 | 291 | utils.syncContents = function syncContents(view, contents) { 292 | if (contents === null) { 293 | view._contents = null; 294 | view._content = null; 295 | } 296 | if (typeof contents === 'string') { 297 | view._contents = new Buffer(contents); 298 | view._content = contents; 299 | } 300 | if (utils.isBuffer(contents)) { 301 | view._contents = contents; 302 | view._content = contents.toString(); 303 | } 304 | if (utils.isStream(contents)) { 305 | view._contents = contents; 306 | // what should be done here? 307 | view._content = contents; 308 | } 309 | }; 310 | 311 | /** 312 | * Return true if the given value is a view. 313 | */ 314 | 315 | utils.renameKey = function(app) { 316 | utils.define(app, 'renameKey', function renameKey(key, fn) { 317 | if (typeof key === 'function') { 318 | fn = key; 319 | key = null; 320 | } 321 | 322 | if (this.option && typeof fn !== 'function') { 323 | fn = this.option('renameKey'); 324 | } 325 | if (typeof fn !== 'function') { 326 | fn = utils.identity; 327 | } 328 | 329 | this.options.renameKey = fn; 330 | if (typeof key === 'string') { 331 | return fn(key); 332 | } 333 | return fn; 334 | }.bind(app)); 335 | }; 336 | 337 | /** 338 | * Set or get an option value. This is a factory for 339 | * adding an `option` method to a class 340 | */ 341 | 342 | utils.option = function option(app, prop) { 343 | utils.define(app, 'option', function(key, value) { 344 | if (typeof key === 'string') { 345 | if (arguments.length === 1) { 346 | return this.get('options.' + key); 347 | } 348 | this.set('options.' + key, value); 349 | this.emit('option', key, value); 350 | return this; 351 | } 352 | if (typeof key !== 'object') { 353 | throw new TypeError('expected a string or object.'); 354 | } 355 | this.visit('option', key); 356 | return this; 357 | }.bind(app)); 358 | }; 359 | 360 | /** 361 | * Ensure file extensions are formatted properly for lookups. 362 | * 363 | * ```js 364 | * utils.formatExt('hbs'); 365 | * //=> '.hbs' 366 | * 367 | * utils.formatExt('.hbs'); 368 | * //=> '.hbs' 369 | * ``` 370 | * 371 | * @param {String} `ext` File extension 372 | * @return {String} 373 | * @api public 374 | */ 375 | 376 | utils.formatExt = function formatExt(ext) { 377 | if (typeof ext !== 'string') { 378 | throw new Error('utils.formatExt() expects `ext` to be a string.'); 379 | } 380 | if (ext.charAt(0) !== '.') { 381 | return '.' + ext; 382 | } 383 | return ext; 384 | }; 385 | 386 | /** 387 | * Strip the dot from a file extension 388 | * 389 | * ```js 390 | * utils.stripDot('.hbs'); 391 | * //=> 'hbs' 392 | * ``` 393 | * 394 | * @param {String} `ext` extension 395 | * @return {String} 396 | * @api public 397 | */ 398 | 399 | utils.stripDot = function stripDot(ext) { 400 | if (typeof ext !== 'string') { 401 | throw new Error('utils.stripDot() expects `ext` to be a string.'); 402 | } 403 | if (ext.charAt(0) === '.') { 404 | return ext.slice(1); 405 | } 406 | return ext; 407 | }; 408 | 409 | /** 410 | * Get locals from helper arguments. 411 | * 412 | * @param {Object} `locals` 413 | * @param {Object} `options` 414 | */ 415 | 416 | utils.getLocals = function getLocals(locals, options) { 417 | options = options || {}; 418 | locals = locals || {}; 419 | var ctx = {}; 420 | 421 | if (options.hasOwnProperty('hash')) { 422 | utils.extend(ctx, locals); 423 | utils.extend(ctx, options.hash); 424 | 425 | } else if (locals.hasOwnProperty('hash')) { 426 | utils.extend(ctx, locals.hash); 427 | 428 | } else if (!locals.hasOwnProperty('hash') && !options.hasOwnProperty('hash')) { 429 | utils.extend(ctx, options); 430 | utils.extend(ctx, locals); 431 | } 432 | return ctx; 433 | }; 434 | 435 | /** 436 | * Get the basename from a filepath, excluding extension. 437 | */ 438 | 439 | function name(fp) { 440 | return path.basename(fp, path.extname(fp)); 441 | } 442 | 443 | /** 444 | * Expose utils 445 | */ 446 | 447 | module.exports = lazy; 448 | -------------------------------------------------------------------------------- /test/fixtures/markdown-toc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | 7 | var utils = require('lazy-cache')(require); 8 | var fn = require; 9 | require = utils; 10 | 11 | /** 12 | * Lazily required module dependencies 13 | */ 14 | 15 | require('minimist'); 16 | require('remarkable', 'Remarkable'); 17 | require('repeat-string', 'repeat'); 18 | require('markdown-link', 'mdlink'); 19 | require('concat-stream', 'concat'); 20 | require('gray-matter', 'matter'); 21 | require('object.pick', 'pick'); 22 | require('mixin-deep', 'merge'); 23 | require('list-item', 'li'); 24 | require = fn; 25 | 26 | /** 27 | * Expose `utils` modules 28 | */ 29 | 30 | module.exports = utils; 31 | -------------------------------------------------------------------------------- /test/fixtures/non-lazy.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | 5 | /** 6 | * Module dependencies 7 | */ 8 | 9 | var utils = require('lazy-cache')(require); 10 | var fn = require; 11 | require = utils; 12 | 13 | require('mixin-deep', 'merge'); 14 | require('through2', 'through'); 15 | require('vinyl', 'File'); 16 | 17 | utils.foo = function() { 18 | 19 | }; 20 | 21 | module.exports = utils; 22 | -------------------------------------------------------------------------------- /test/fixtures/normal.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | 5 | /** 6 | * Utils 7 | */ 8 | 9 | var utils = {}; 10 | 11 | // object/array/type utils 12 | utils.clone = require('clone'); 13 | utils.isBuffer = require('is-buffer'); 14 | utils.paginationator = require('paginationator'); 15 | utils.sortBy = require('array-sort'); 16 | utils.groupBy = require('group-array'); 17 | utils.define = require('define-property'); 18 | utils.merge = require('mixin-deep'); 19 | utils.extend = require('extend-shallow'); 20 | utils.reduce = require('object.reduce'); 21 | 22 | // routing 23 | utils.router = require('en-route'); 24 | 25 | // engines, templates and helpers 26 | utils.loader = require('load-helpers'); 27 | utils.engine = require('engine-base'); 28 | utils.Engines = require('engine-cache'); 29 | utils.Helpers = require('helper-cache'); 30 | utils.rethrow = require('template-error'); 31 | utils.inflect = require('inflection'); 32 | utils.layouts = require('layouts'); 33 | 34 | // glob/matching utils 35 | utils.globby = require('globby'); 36 | utils.mm = require('micromatch'); 37 | utils.isValidGlob = require('is-valid-glob'); 38 | utils.hasGlob = require('has-glob'); 39 | 40 | /** 41 | * Default router methods used in all Template instances 42 | */ 43 | 44 | utils.methods = [ 45 | 'onLoad', 46 | 'preCompile', 47 | 'preLayout', 48 | 'onLayout', 49 | 'postLayout', 50 | 'onMerge', 51 | 'postCompile', 52 | 'preRender', 53 | 'postRender' 54 | ]; 55 | 56 | /** 57 | * FILE / GLOB UTILS 58 | * -------------------------------- 59 | */ 60 | 61 | /** 62 | * Resolve the absolute file paths for a glob of files. 63 | */ 64 | 65 | utils.resolveGlob = function resolveGlob(patterns, options) { 66 | var opts = utils.extend({cwd: process.cwd()}, options); 67 | return utils.globby.sync(patterns, opts).map(function (fp) { 68 | return path.resolve(opts.cwd, fp); 69 | }); 70 | }; 71 | 72 | /** 73 | * Require a glob of files 74 | */ 75 | 76 | utils.requireGlob = function requireGlob(patterns, options) { 77 | return utils.resolveGlob(patterns, options).reduce(function (acc, fp) { 78 | if (/\.(js(?:on)?)/.test(fp)) { 79 | acc[utils.rename(fp, options)] = utils.tryRequire(fp); 80 | } 81 | return acc; 82 | }, {}); 83 | }; 84 | 85 | /** 86 | * Attempt to require a file. Fail silently. 87 | */ 88 | 89 | utils.tryRequire = function tryRequire(fp, opts) { 90 | try { 91 | return require(fp); 92 | } catch(err) { 93 | try { 94 | opts = opts || {}; 95 | fp = path.resolve(fp); 96 | return require(fp); 97 | } catch(err) {} 98 | } 99 | return null; 100 | }; 101 | 102 | /** 103 | * OBJECT / ARRAY / TYPE UTILS 104 | * -------------------------------- 105 | */ 106 | 107 | /** 108 | * Format an error object. 109 | */ 110 | 111 | utils.error = function error(msg, val) { 112 | return new Error(msg + JSON.stringify(val)); 113 | }; 114 | 115 | /** 116 | * Do nothing. 117 | */ 118 | 119 | utils.noop = function noop() {}; 120 | 121 | /** 122 | * Return the given value as-is. 123 | */ 124 | 125 | utils.identity = function identity(val) { 126 | return val; 127 | }; 128 | 129 | /** 130 | * Arrayify the given value by casting it to an array. 131 | */ 132 | 133 | utils.arrayify = function arrayify(val) { 134 | return val ? (Array.isArray(val) ? val : [val]) : []; 135 | }; 136 | 137 | /** 138 | * Returns true if an array have the given element 139 | * @return {Boolean} 140 | */ 141 | 142 | utils.has = function has(keys, key) { 143 | return keys.indexOf(key) > -1; 144 | }; 145 | 146 | /** 147 | * Return true if the given value is an object. 148 | * @return {Boolean} 149 | */ 150 | 151 | utils.isObject = function isObject(val) { 152 | return val && (typeof val === 'function' || typeof val === 'object') 153 | && !Array.isArray(val); 154 | }; 155 | 156 | /** 157 | * Return true if the given value is a stream. 158 | */ 159 | 160 | utils.isStream = function isStream(val) { 161 | return val && (typeof val === 'function' || typeof val === 'object') 162 | && !Array.isArray(val) 163 | && (typeof val.pipe === 'function') 164 | && (typeof val.on === 'function'); 165 | }; 166 | 167 | /** 168 | * Bind a `thisArg` to all the functions on the target 169 | * 170 | * @param {Object|Array} `target` Object or Array with functions as values that will be bound. 171 | * @param {Object} `thisArg` Object to bind to the functions 172 | * @return {Object|Array} Object or Array with bound functions. 173 | */ 174 | 175 | utils.bindAll = function bindAll(target, thisArg) { 176 | return utils.reduce(target, function (acc, fn, key) { 177 | if (typeof fn === 'object') { 178 | acc[key] = utils.bindAll(fn, thisArg); 179 | } else if (typeof fn === 'function') { 180 | acc[key] = fn.bind(thisArg); 181 | // get `async` flag or any other helper options on `fn` 182 | for (var k in fn) acc[key][k] = fn[k]; 183 | } 184 | return acc; 185 | }, {}); 186 | }; 187 | 188 | /** 189 | * VIEW UTILS 190 | * -------------------------------- 191 | */ 192 | 193 | /** 194 | * Rename a file 195 | */ 196 | 197 | utils.rename = function rename(fp, options) { 198 | var opts = utils.extend({renameFn: name}, options); 199 | return opts.renameFn(fp); 200 | }; 201 | 202 | /** 203 | * Singularize the given `name` 204 | */ 205 | 206 | utils.single = function single(name) { 207 | return utils.inflect.singularize(name); 208 | }; 209 | 210 | /** 211 | * Pluralize the given `name` 212 | */ 213 | 214 | utils.plural = function plural(name) { 215 | return utils.inflect.pluralize(name); 216 | }; 217 | 218 | /** 219 | * Return true if the given value is a view. 220 | */ 221 | 222 | utils.isView = function isView(val) { 223 | return val && val.hasOwnProperty('content') 224 | || val.hasOwnProperty('contents') 225 | || val.hasOwnProperty('path'); 226 | }; 227 | 228 | /** 229 | * Return true if the given value is a view. 230 | */ 231 | 232 | utils.hasView = function hasView(val) { 233 | var keys = Object.keys(val); 234 | if (keys.length > 1) return false; 235 | return utils.isView(val[keys[0]]); 236 | }; 237 | 238 | /** 239 | * Return the first object with a key that matches 240 | * the given glob pattern. 241 | * 242 | * @param {Object} `object` 243 | * @param {String|Array} `patterns` 244 | * @param {Object} `options` 245 | * @return {Object} 246 | */ 247 | 248 | utils.matchKey = function matchKey(obj, patterns, options) { 249 | if (!utils.isObject(obj)) return null; 250 | var keys = utils.mm(Object.keys(obj), patterns, options); 251 | return obj[keys[0]]; 252 | }; 253 | 254 | /** 255 | * Return all objects with keys that match 256 | * the given glob pattern. 257 | * 258 | * @param {Object} `object` 259 | * @param {String|Array} `patterns` 260 | * @param {Object} `options` 261 | * @return {Object} 262 | */ 263 | 264 | utils.matchKeys = function matchKeys(obj, patterns, options) { 265 | var keys = utils.mm(Object.keys(obj), patterns, options).sort(); 266 | var len = keys.length, i = 0; 267 | var res = {}; 268 | 269 | while (len--) { 270 | var key = keys[i++]; 271 | res[key] = obj[key]; 272 | } 273 | return res; 274 | }; 275 | 276 | /** 277 | * Sync the _content and _contents properties on a view to ensure 278 | * both are set when setting one. 279 | * 280 | * @param {Object} `view` instance of a `View` 281 | * @param {String|Buffer|Stream|null} `contents` contents to set on both properties 282 | */ 283 | 284 | utils.syncContents = function syncContents(view, contents) { 285 | if (contents === null) { 286 | view._contents = null; 287 | view._content = null; 288 | } 289 | if (typeof contents === 'string') { 290 | view._contents = new Buffer(contents); 291 | view._content = contents; 292 | } 293 | if (utils.isBuffer(contents)) { 294 | view._contents = contents; 295 | view._content = contents.toString(); 296 | } 297 | if (utils.isStream(contents)) { 298 | view._contents = contents; 299 | // what should be done here? 300 | view._content = contents; 301 | } 302 | }; 303 | 304 | /** 305 | * Return true if the given value is a view. 306 | */ 307 | 308 | utils.renameKey = function(app) { 309 | utils.define(app, 'renameKey', function renameKey(key, fn) { 310 | if (typeof key === 'function') { 311 | fn = key; 312 | key = null; 313 | } 314 | 315 | if (this.option && typeof fn !== 'function') { 316 | fn = this.option('renameKey'); 317 | } 318 | if (typeof fn !== 'function') { 319 | fn = utils.identity; 320 | } 321 | 322 | this.options.renameKey = fn; 323 | if (typeof key === 'string') { 324 | return fn(key); 325 | } 326 | return fn; 327 | }.bind(app)); 328 | }; 329 | 330 | /** 331 | * Set or get an option value. This is a factory for 332 | * adding an `option` method to a class 333 | */ 334 | 335 | utils.option = function option(app, prop) { 336 | utils.define(app, 'option', function(key, value) { 337 | if (typeof key === 'string') { 338 | if (arguments.length === 1) { 339 | return this.get('options.' + key); 340 | } 341 | this.set('options.' + key, value); 342 | this.emit('option', key, value); 343 | return this; 344 | } 345 | if (typeof key !== 'object') { 346 | throw new TypeError('expected a string or object.'); 347 | } 348 | this.visit('option', key); 349 | return this; 350 | }.bind(app)); 351 | }; 352 | 353 | /** 354 | * Ensure file extensions are formatted properly for lookups. 355 | * 356 | * ```js 357 | * utils.formatExt('hbs'); 358 | * //=> '.hbs' 359 | * 360 | * utils.formatExt('.hbs'); 361 | * //=> '.hbs' 362 | * ``` 363 | * 364 | * @param {String} `ext` File extension 365 | * @return {String} 366 | * @api public 367 | */ 368 | 369 | utils.formatExt = function formatExt(ext) { 370 | if (typeof ext !== 'string') { 371 | throw new Error('utils.formatExt() expects `ext` to be a string.'); 372 | } 373 | if (ext.charAt(0) !== '.') { 374 | return '.' + ext; 375 | } 376 | return ext; 377 | }; 378 | 379 | /** 380 | * Strip the dot from a file extension 381 | * 382 | * ```js 383 | * utils.stripDot('.hbs'); 384 | * //=> 'hbs' 385 | * ``` 386 | * 387 | * @param {String} `ext` extension 388 | * @return {String} 389 | * @api public 390 | */ 391 | 392 | utils.stripDot = function stripDot(ext) { 393 | if (typeof ext !== 'string') { 394 | throw new Error('utils.stripDot() expects `ext` to be a string.'); 395 | } 396 | if (ext.charAt(0) === '.') { 397 | return ext.slice(1); 398 | } 399 | return ext; 400 | }; 401 | 402 | /** 403 | * Get locals from helper arguments. 404 | * 405 | * @param {Object} `locals` 406 | * @param {Object} `options` 407 | */ 408 | 409 | utils.getLocals = function getLocals(locals, options) { 410 | options = options || {}; 411 | locals = locals || {}; 412 | var ctx = {}; 413 | 414 | if (options.hasOwnProperty('hash')) { 415 | utils.extend(ctx, locals); 416 | utils.extend(ctx, options.hash); 417 | 418 | } else if (locals.hasOwnProperty('hash')) { 419 | utils.extend(ctx, locals.hash); 420 | 421 | } else if (!locals.hasOwnProperty('hash') && !options.hasOwnProperty('hash')) { 422 | utils.extend(ctx, options); 423 | utils.extend(ctx, locals); 424 | } 425 | return ctx; 426 | }; 427 | 428 | /** 429 | * Get the basename from a filepath, excluding extension. 430 | */ 431 | 432 | function name(fp) { 433 | return path.basename(fp, path.extname(fp)); 434 | } 435 | 436 | /** 437 | * Expose utils 438 | */ 439 | 440 | module.exports = utils; 441 | -------------------------------------------------------------------------------- /test/fixtures/separate.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | 7 | var lazy = require('lazy-cache')(require); 8 | lazy('mixin-deep', 'merge'); 9 | lazy('through2', 'through'); 10 | lazy('vinyl', 'File'); 11 | 12 | var utils = lazy; 13 | 14 | utils.foo = function () { 15 | 16 | }; 17 | 18 | module.exports = utils; 19 | -------------------------------------------------------------------------------- /test/fixtures/top.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Module dependencies 5 | */ 6 | 7 | var lazy = module.exports = require('lazy-cache')(require); 8 | lazy('mixin-deep', 'merge'); 9 | lazy('through2', 'through'); 10 | lazy('vinyl', 'File'); -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('mocha'); 4 | require('should'); 5 | var fs = require('fs'); 6 | var path = require('path'); 7 | var assert = require('assert'); 8 | var unlazy = require('..'); 9 | 10 | function fixture(fp) { 11 | return fs.readFileSync(path.join('test/fixtures', fp), 'utf8'); 12 | } 13 | function actual(fp) { 14 | return fs.readFileSync(path.join('test/actual', fp), 'utf8'); 15 | } 16 | 17 | describe('unlazy', function() { 18 | it('should unlazy a lazy require', function() { 19 | assert.equal(unlazy(fixture('ansi-colors.js')), actual('ansi-colors.js')); 20 | assert.equal(unlazy(fixture('bottom.js')), actual('bottom.js')); 21 | assert.equal(unlazy(fixture('many.js')), actual('many.js')); 22 | assert.equal(unlazy(fixture('markdown-toc.js')), actual('markdown-toc.js')); 23 | assert.equal(unlazy(fixture('non-lazy.js')), actual('non-lazy.js')); 24 | assert.equal(unlazy(fixture('separate.js')), actual('separate.js')); 25 | assert.equal(unlazy(fixture('top.js')), actual('top.js')); 26 | }); 27 | 28 | it('should not unlazy a normal file require', function() { 29 | assert.equal(unlazy(fixture('normal.js')), actual('normal.js')); 30 | }); 31 | }); 32 | --------------------------------------------------------------------------------