├── .gitignore ├── .jshintrc ├── .travis.yml ├── LICENSE ├── lib ├── default-file-types.js ├── detect-dependencies.js ├── helpers.js └── inject-dependencies.js ├── package.json ├── readme.md ├── test ├── fixture │ ├── bower.json │ ├── bower_after_uninstall.json │ ├── bower_after_uninstall_all.json │ ├── bower_components │ │ ├── 3l │ │ │ ├── 3L │ │ │ │ └── 3L.less │ │ │ └── bower.json │ │ ├── bootstrap │ │ │ ├── bower.json │ │ │ └── dist │ │ │ │ ├── css │ │ │ │ └── bootstrap.css │ │ │ │ └── js │ │ │ │ └── bootstrap.js │ │ ├── codecode │ │ │ ├── component.json │ │ │ └── dist │ │ │ │ ├── codecode.css │ │ │ │ └── codecode.js │ │ ├── fake-package-with-override │ │ │ ├── bower.json │ │ │ └── dist │ │ │ │ ├── fake-package-with-override.css │ │ │ │ └── fake-package-with-override.js │ │ ├── fake-package-without-dependencies │ │ │ ├── bower.json │ │ │ └── fake-package-without-dependencies.js │ │ ├── fake-package-without-main-and-confusing-file-tree │ │ │ ├── bower.json │ │ │ └── dist │ │ │ │ ├── fake-package-without-main-and-confusing-file-tree.css │ │ │ │ └── fake-package-without-main-and-confusing-file-tree.js │ │ ├── fake-package-without-main │ │ │ ├── bower.json │ │ │ ├── fake-package-without-main.css │ │ │ └── fake-package-without-main.js │ │ ├── jquery │ │ │ ├── bower.json │ │ │ └── jquery.js │ │ ├── karma │ │ │ ├── bower.json │ │ │ └── dist │ │ │ │ └── karma.styl │ │ ├── modular-scale │ │ │ ├── bower.json │ │ │ └── stylesheets │ │ │ │ ├── _modular-scale-tests.scss │ │ │ │ ├── _modular-scale.scss │ │ │ │ └── modular-scale │ │ │ │ ├── _calc.scss │ │ │ │ ├── _function-list.scss │ │ │ │ ├── _function.scss │ │ │ │ ├── _generate-list.scss │ │ │ │ ├── _pow.scss │ │ │ │ ├── _ratios.scss │ │ │ │ ├── _sort-list.scss │ │ │ │ └── _tests.scss │ │ └── things │ │ │ ├── bower.json │ │ │ └── things.js │ ├── bower_packages_without_dependencies.json │ ├── bower_packages_without_main.json │ ├── bower_with_main.json │ ├── bower_with_main_glob.json │ ├── bower_with_missing_component.json │ ├── bowerrc │ │ ├── .bowerrc │ │ ├── bower.json │ │ └── custom │ │ │ └── .gitkeep │ ├── cwd_includeself │ │ ├── bower.json │ │ ├── bower_components │ │ │ ├── bootstrap │ │ │ │ ├── bower.json │ │ │ │ └── dist │ │ │ │ │ ├── css │ │ │ │ │ └── bootstrap.css │ │ │ │ │ └── js │ │ │ │ │ └── bootstrap.js │ │ │ └── jquery │ │ │ │ ├── bower.json │ │ │ │ └── jquery.js │ │ ├── sample-main.css │ │ └── sample-main.js │ ├── glob_main │ │ ├── .bowerrc │ │ ├── bower.json │ │ └── custom │ │ │ └── glob │ │ │ ├── app │ │ │ ├── app.js │ │ │ └── service │ │ │ │ └── service.js │ │ │ └── bower.json │ ├── haml │ │ ├── index-actual.haml │ │ ├── index-after-uninstall-actual.haml │ │ ├── index-after-uninstall-all-actual.haml │ │ ├── index-after-uninstall-all-expected.haml │ │ ├── index-after-uninstall-expected.haml │ │ ├── index-custom-format-actual.haml │ │ ├── index-custom-format-expected.haml │ │ ├── index-excluded-files-actual.haml │ │ ├── index-excluded-files-expected.haml │ │ ├── index-expected.haml │ │ ├── index-second-run-actual.haml │ │ └── index-second-run-expected.haml │ ├── html │ │ ├── deep │ │ │ └── nested │ │ │ │ ├── index-actual.html │ │ │ │ └── index-expected.html │ │ ├── index-actual.html │ │ ├── index-after-uninstall-actual.html │ │ ├── index-after-uninstall-all-actual.html │ │ ├── index-after-uninstall-all-expected.html │ │ ├── index-after-uninstall-expected.html │ │ ├── index-custom-format-actual.html │ │ ├── index-custom-format-expected.html │ │ ├── index-cwd-include-self-actual.html │ │ ├── index-cwd-include-self-expected.html │ │ ├── index-detect-quotation-marks-actual.html │ │ ├── index-detect-quotation-marks-expected.html │ │ ├── index-emitter.html │ │ ├── index-excluded-files-actual.html │ │ ├── index-excluded-files-expected.html │ │ ├── index-expected.html │ │ ├── index-include-glob-actual.html │ │ ├── index-include-glob-expected.html │ │ ├── index-include-self-actual.html │ │ ├── index-include-self-expected.html │ │ ├── index-include-self-glob-actual.html │ │ ├── index-include-self-glob-expected.html │ │ ├── index-override-dependencies-actual.html │ │ ├── index-override-dependencies-expected.html │ │ ├── index-packages-without-main-actual.html │ │ ├── index-packages-without-main-expected.html │ │ ├── index-second-run-actual.html │ │ ├── index-second-run-expected.html │ │ ├── index-with-custom-bower-directory-actual.html │ │ ├── index-with-custom-bower-directory-expected.html │ │ ├── index-with-custom-replace-function-actual.html │ │ ├── index-with-custom-replace-function-expected.html │ │ ├── index-with-dev-dependencies-actual.html │ │ └── index-with-dev-dependencies-expected.html │ ├── invalid.json │ ├── jade │ │ ├── index-actual.jade │ │ ├── index-after-uninstall-actual.jade │ │ ├── index-after-uninstall-all-actual.jade │ │ ├── index-after-uninstall-all-expected.jade │ │ ├── index-after-uninstall-expected.jade │ │ ├── index-custom-format-actual.jade │ │ ├── index-custom-format-expected.jade │ │ ├── index-excluded-files-actual.jade │ │ ├── index-excluded-files-expected.jade │ │ ├── index-expected.jade │ │ ├── index-second-run-actual.jade │ │ ├── index-second-run-expected.jade │ │ ├── index-unbuffered-comments-actual.jade │ │ └── index-unbuffered-comments-expected.jade │ ├── js │ │ ├── index-actual.js │ │ └── index-expected.js │ ├── less │ │ ├── index-actual.less │ │ ├── index-expected.less │ │ ├── index-second-run-actual.less │ │ └── index-second-run-expected.less │ ├── pug │ │ ├── index-actual.pug │ │ ├── index-after-uninstall-actual.pug │ │ ├── index-after-uninstall-all-actual.pug │ │ ├── index-after-uninstall-all-expected.pug │ │ ├── index-after-uninstall-expected.pug │ │ ├── index-custom-format-actual.pug │ │ ├── index-custom-format-expected.pug │ │ ├── index-excluded-files-actual.pug │ │ ├── index-excluded-files-expected.pug │ │ ├── index-expected.pug │ │ ├── index-second-run-actual.pug │ │ ├── index-second-run-expected.pug │ │ ├── index-unbuffered-comments-actual.pug │ │ └── index-unbuffered-comments-expected.pug │ ├── sample-main.css │ ├── sample-main.js │ ├── sass │ │ ├── index-actual.sass │ │ ├── index-expected.sass │ │ ├── index-second-run-actual.sass │ │ └── index-second-run-expected.sass │ ├── scss │ │ ├── index-actual.scss │ │ ├── index-expected.scss │ │ ├── index-second-run-actual.scss │ │ └── index-second-run-expected.scss │ ├── slim │ │ ├── index-actual.slim │ │ ├── index-after-uninstall-actual.slim │ │ ├── index-after-uninstall-all-actual.slim │ │ ├── index-after-uninstall-all-expected.slim │ │ ├── index-after-uninstall-expected.slim │ │ ├── index-custom-format-actual.slim │ │ ├── index-custom-format-expected.slim │ │ ├── index-excluded-files-actual.slim │ │ ├── index-excluded-files-expected.slim │ │ ├── index-expected.slim │ │ ├── index-second-run-actual.slim │ │ └── index-second-run-expected.slim │ ├── styl │ │ ├── index-actual.styl │ │ ├── index-expected.styl │ │ ├── index-second-run-actual.styl │ │ └── index-second-run-expected.styl │ ├── unrecognized │ │ ├── index-actual.unrecognized │ │ └── index-expected.unrecognized │ └── yml │ │ ├── index-actual.yml │ │ ├── index-custom-format-actual.yml │ │ ├── index-custom-format-expected.yml │ │ ├── index-excluded-files-actual.yml │ │ ├── index-excluded-files-expected.yml │ │ ├── index-expected.yml │ │ ├── index-second-run-actual.yml │ │ └── index-second-run-expected.yml └── wiredep_test.js └── wiredep.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | .tmp 3 | *.log 4 | /coverage 5 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "newcap": true, 6 | "noarg": true, 7 | "sub": true, 8 | "undef": true, 9 | "unused": true, 10 | "boss": true, 11 | "eqnull": true, 12 | "node": true, 13 | "laxbreak": true 14 | } 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - v0.10 5 | - v0.12 6 | - v4 7 | - v5 8 | script: npm run coverage 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Stephen Sawchuk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /lib/default-file-types.js: -------------------------------------------------------------------------------- 1 | var regex = { 2 | block: { 3 | '//': /(([ \t]*)\/\/\s*bower:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi 4 | } 5 | }; 6 | 7 | module.exports = { 8 | html: { 9 | block: /(([ \t]*))(\n|\r|.)*?()/gi, 10 | detect: { 11 | js: /', 16 | css: '' 17 | } 18 | }, 19 | 20 | js: { 21 | block: regex.block['//'], 22 | detect: { 23 | js: /['"]([^'"]+\.js)['"],?/gi, 24 | css: /['"]([^'"]+\.js)['"],?/gi 25 | }, 26 | replace: { 27 | js: '"{{filePath}}",', 28 | css: '"{{filePath}}",' 29 | } 30 | }, 31 | 32 | jade: { 33 | block: /(([ \t]*)\/\/-?\s*bower:*(\S*))(\n|\r|.)*?(\/\/-?\s*endbower)/gi, 34 | detect: { 35 | js: /script\(.*src=['"]([^'"]+)/gi, 36 | css: /link\(.*href=['"]([^'"]+)/gi 37 | }, 38 | replace: { 39 | js: 'script(src=\'{{filePath}}\')', 40 | css: 'link(rel=\'stylesheet\', href=\'{{filePath}}\')' 41 | } 42 | }, 43 | 44 | pug: { 45 | block: /(([ \t]*)\/\/-?\s*bower:*(\S*))(\n|\r|.)*?(\/\/-?\s*endbower)/gi, 46 | detect: { 47 | js: /script\(.*src=['"]([^'"]+)/gi, 48 | css: /link\(.*href=['"]([^'"]+)/gi 49 | }, 50 | replace: { 51 | js: 'script(src=\'{{filePath}}\')', 52 | css: 'link(rel=\'stylesheet\', href=\'{{filePath}}\')' 53 | } 54 | }, 55 | 56 | slim: { 57 | block: /(([ \t]*)\/!?\s*bower:(\S*))(\n|\r|.)*?(\/!?\s*endbower)/gi, 58 | detect: { 59 | js: /script.*src=['"]([^'"]+)/gi, 60 | css: /link.*href=['"]([^'"]+)/gi 61 | }, 62 | replace: { 63 | js: 'script src=\'{{filePath}}\'', 64 | css: 'link rel=\'stylesheet\' href=\'{{filePath}}\'' 65 | } 66 | }, 67 | 68 | less: { 69 | block: regex.block['//'], 70 | detect: { 71 | css: /@import\s['"](.+css)['"]/gi, 72 | less: /@import\s['"](.+less)['"]/gi 73 | }, 74 | replace: { 75 | css: '@import "{{filePath}}";', 76 | less: '@import "{{filePath}}";' 77 | } 78 | }, 79 | 80 | sass: { 81 | block: regex.block['//'], 82 | detect: { 83 | css: /@import\s(.+css)/gi, 84 | sass: /@import\s(.+sass)/gi, 85 | scss: /@import\s(.+scss)/gi 86 | }, 87 | replace: { 88 | css: '@import {{filePath}}', 89 | sass: '@import {{filePath}}', 90 | scss: '@import {{filePath}}' 91 | } 92 | }, 93 | 94 | scss: { 95 | block: regex.block['//'], 96 | detect: { 97 | css: /@import\s['"](.+css)['"]/gi, 98 | sass: /@import\s['"](.+sass)['"]/gi, 99 | scss: /@import\s['"](.+scss)['"]/gi 100 | }, 101 | replace: { 102 | css: '@import "{{filePath}}";', 103 | sass: '@import "{{filePath}}";', 104 | scss: '@import "{{filePath}}";' 105 | } 106 | }, 107 | 108 | styl: { 109 | block: regex.block['//'], 110 | detect: { 111 | css: /@import\s['"](.+css)['"]/gi, 112 | styl: /@import\s['"](.+styl)['"]/gi 113 | }, 114 | replace: { 115 | css: '@import "{{filePath}}"', 116 | styl: '@import "{{filePath}}"' 117 | } 118 | }, 119 | 120 | yaml: { 121 | block: /(([ \t]*)#\s*bower:*(\S*))(\n|\r|.)*?(#\s*endbower)/gi, 122 | detect: { 123 | js: /-\s(.+js)/gi, 124 | css: /-\s(.+css)/gi 125 | }, 126 | replace: { 127 | js: '- {{filePath}}', 128 | css: '- {{filePath}}' 129 | } 130 | }, 131 | 132 | haml: { 133 | block: /(([ \t]*)-#\s*bower:*(\S*))(\n|\r|.)*?(-#\s*endbower)/gi, 134 | detect: { 135 | js: /\%script\{.*src:['"]([^'"]+)/gi, 136 | css: /\%link\{.*href:['"]([^'"]+)/gi 137 | }, 138 | replace: { 139 | js: '%script{src:\'{{filePath}}\'}', 140 | css: '%link{rel:\'stylesheet\', href:\'{{filePath}}\'}' 141 | } 142 | } 143 | }; 144 | 145 | 146 | module.exports['default'] = module.exports.html; 147 | module.exports.htm = module.exports.html; 148 | module.exports.yml = module.exports.yaml; 149 | -------------------------------------------------------------------------------- /lib/detect-dependencies.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var $ = { 4 | _: require('lodash'), 5 | fs: require('fs'), 6 | lodash: require('lodash'), 7 | path: require('path'), 8 | glob: require('glob'), 9 | propprop: require('propprop') 10 | }; 11 | 12 | 13 | /** 14 | * Detect dependencies of the components from `bower.json`. 15 | * 16 | * @param {object} config the global configuration object. 17 | * @return {object} config 18 | */ 19 | function detectDependencies(config) { 20 | var allDependencies = {}; 21 | 22 | if (config.get('dependencies')) { 23 | $._.assign(allDependencies, config.get('bower.json').dependencies); 24 | } 25 | 26 | if (config.get('dev-dependencies')) { 27 | $._.assign(allDependencies, config.get('bower.json').devDependencies); 28 | } 29 | 30 | if (config.get('include-self')) { 31 | allDependencies[config.get('bower.json').name] = config.get('bower.json').version; 32 | } 33 | 34 | $._.each(allDependencies, gatherInfo(config)); 35 | 36 | config.set('global-dependencies-sorted', filterExcludedDependencies( 37 | config.get('detectable-file-types'). 38 | reduce(function (acc, fileType) { 39 | if (!acc[fileType]) { 40 | acc[fileType] = prioritizeDependencies(config, '.' + fileType); 41 | } 42 | return acc; 43 | }, {}), 44 | config.get('exclude') 45 | )); 46 | 47 | return config; 48 | } 49 | 50 | 51 | /** 52 | * Find the component's JSON configuration file. 53 | * 54 | * @param {object} config the global configuration object 55 | * @param {string} component the name of the component to dig for 56 | * @return {object} the component's config file 57 | */ 58 | function findComponentConfigFile(config, component) { 59 | var componentConfigFile; 60 | 61 | if (config.get('include-self') && component === config.get('bower.json').name) { 62 | return config.get('bower.json'); 63 | } 64 | 65 | ['bower.json', '.bower.json', 'component.json', 'package.json']. 66 | forEach(function (configFile) { 67 | configFile = $.path.join(config.get('bower-directory'), component, configFile); 68 | 69 | if (!$._.isObject(componentConfigFile) && $.fs.existsSync(configFile)) { 70 | componentConfigFile = JSON.parse($.fs.readFileSync(configFile)); 71 | } 72 | }); 73 | 74 | return componentConfigFile; 75 | } 76 | 77 | 78 | /** 79 | * Find the main file the component refers to. It's not always `main` :( 80 | * 81 | * @param {object} config the global configuration object 82 | * @param {string} component the name of the component to dig for 83 | * @param {componentConfigFile} the component's config file 84 | * @return {array} the array of paths to the component's primary file(s) 85 | */ 86 | function findMainFiles(config, component, componentConfigFile) { 87 | var filePaths = []; 88 | var file = {}; 89 | var self = config.get('include-self') && component === config.get('bower.json').name; 90 | var cwd = self ? config.get('cwd') : $.path.join(config.get('bower-directory'), component); 91 | 92 | if ($._.isString(componentConfigFile.main)) { 93 | // start by looking for what every component should have: config.main 94 | filePaths = [componentConfigFile.main]; 95 | } else if ($._.isArray(componentConfigFile.main)) { 96 | filePaths = componentConfigFile.main; 97 | } else if ($._.isArray(componentConfigFile.scripts)) { 98 | // still haven't found it. is it stored in config.scripts, then? 99 | filePaths = componentConfigFile.scripts; 100 | } else { 101 | ['js', 'css'] 102 | .forEach(function (type) { 103 | file[type] = $.path.join(config.get('bower-directory'), component, componentConfigFile.name + '.' + type); 104 | 105 | if ($.fs.existsSync(file[type])) { 106 | filePaths.push(componentConfigFile.name + '.' + type); 107 | } 108 | }); 109 | } 110 | 111 | return $._.uniq(filePaths.reduce(function (acc, filePath) { 112 | acc = acc.concat( 113 | $.glob.sync(filePath, { cwd: cwd, root: '/' }) 114 | .map(function (path) { 115 | return $.path.join(cwd, path); 116 | }) 117 | ); 118 | return acc; 119 | }, [])); 120 | } 121 | 122 | 123 | /** 124 | * Store the information our prioritizer will need to determine rank. 125 | * 126 | * @param {object} config the global configuration object 127 | * @return {function} the iterator function, called on every component 128 | */ 129 | function gatherInfo(config) { 130 | /** 131 | * The iterator function, which is called on each component. 132 | * 133 | * @param {string} version the version of the component 134 | * @param {string} component the name of the component 135 | * @return {undefined} 136 | */ 137 | return function (version, component) { 138 | var dep = config.get('global-dependencies').get(component) || { 139 | main: '', 140 | type: '', 141 | name: '', 142 | dependencies: {} 143 | }; 144 | 145 | var componentConfigFile = findComponentConfigFile(config, component); 146 | if (!componentConfigFile) { 147 | var error = new Error(component + ' is not installed. Try running `bower install` or remove the component from your bower.json file.'); 148 | error.code = 'PKG_NOT_INSTALLED'; 149 | config.get('on-error')(error); 150 | return; 151 | } 152 | 153 | var overrides = config.get('overrides'); 154 | 155 | if (overrides && overrides[component]) { 156 | if (overrides[component].dependencies) { 157 | componentConfigFile.dependencies = overrides[component].dependencies; 158 | } 159 | 160 | if (overrides[component].main) { 161 | componentConfigFile.main = overrides[component].main; 162 | } 163 | } 164 | 165 | var mains = findMainFiles(config, component, componentConfigFile); 166 | var fileTypes = $._.chain(mains).map($.path.extname).uniq().value(); 167 | 168 | dep.main = mains; 169 | dep.type = fileTypes; 170 | dep.name = componentConfigFile.name; 171 | 172 | var depIsExcluded = $._.find(config.get('exclude'), function (pattern) { 173 | return $.path.join(config.get('bower-directory'), component).match(pattern); 174 | }); 175 | 176 | if (dep.main.length === 0 && !depIsExcluded) { 177 | config.get('on-main-not-found')(component); 178 | } 179 | 180 | if (componentConfigFile.dependencies) { 181 | dep.dependencies = componentConfigFile.dependencies; 182 | 183 | $._.each(componentConfigFile.dependencies, gatherInfo(config)); 184 | } 185 | 186 | config.get('global-dependencies').set(component, dep); 187 | }; 188 | } 189 | 190 | 191 | /** 192 | * Compare two dependencies to determine priority. 193 | * 194 | * @param {object} a dependency a 195 | * @param {object} b dependency b 196 | * @return {number} the priority of dependency a in comparison to dependency b 197 | */ 198 | function dependencyComparator(a, b) { 199 | var aNeedsB = false; 200 | var bNeedsA = false; 201 | 202 | aNeedsB = Object. 203 | keys(a.dependencies). 204 | some(function (dependency) { 205 | return dependency === b.name; 206 | }); 207 | 208 | if (aNeedsB) { 209 | return 1; 210 | } 211 | 212 | bNeedsA = Object. 213 | keys(b.dependencies). 214 | some(function (dependency) { 215 | return dependency === a.name; 216 | }); 217 | 218 | if (bNeedsA) { 219 | return -1; 220 | } 221 | 222 | return 0; 223 | } 224 | 225 | 226 | /** 227 | * Take two arrays, sort based on their dependency relationship, then merge them 228 | * together. 229 | * 230 | * @param {array} left 231 | * @param {array} right 232 | * @return {array} the sorted, merged array 233 | */ 234 | function merge(left, right) { 235 | var result = []; 236 | var leftIndex = 0; 237 | var rightIndex = 0; 238 | 239 | while (leftIndex < left.length && rightIndex < right.length) { 240 | if (dependencyComparator(left[leftIndex], right[rightIndex]) < 1) { 241 | result.push(left[leftIndex++]); 242 | } else { 243 | result.push(right[rightIndex++]); 244 | } 245 | } 246 | 247 | return result. 248 | concat(left.slice(leftIndex)). 249 | concat(right.slice(rightIndex)); 250 | } 251 | 252 | 253 | /** 254 | * Take an array and slice it in halves, sorting each half along the way. 255 | * 256 | * @param {array} items 257 | * @return {array} the sorted array 258 | */ 259 | function mergeSort(items) { 260 | if (items.length < 2) { 261 | return items; 262 | } 263 | 264 | var middle = Math.floor(items.length / 2); 265 | 266 | return merge( 267 | mergeSort(items.slice(0, middle)), 268 | mergeSort(items.slice(middle)) 269 | ); 270 | } 271 | 272 | 273 | /** 274 | * Sort the dependencies in the order we can best determine they're needed. 275 | * 276 | * @param {object} config the global configuration object 277 | * @param {string} fileType the type of file to prioritize 278 | * @return {array} the sorted items of 'path/to/main/files.ext' sorted by type 279 | */ 280 | function prioritizeDependencies(config, fileType) { 281 | var globalDependencies = $._.toArray(config.get('global-dependencies').get()); 282 | 283 | var dependencies = globalDependencies.filter(function (dependency) { 284 | return $._.includes(dependency.type, fileType); 285 | }); 286 | 287 | return $._(mergeSort(dependencies)). 288 | map($.propprop('main')). 289 | flatten(). 290 | value(). 291 | filter(function (main) { 292 | return $.path.extname(main) === fileType; 293 | }); 294 | } 295 | 296 | 297 | /** 298 | * Excludes dependencies that match any of the patterns. 299 | * 300 | * @param {array} allDependencies array of dependencies to filter 301 | * @param {array} patterns array of patterns to match against 302 | * @return {array} items that don't match any of the patterns 303 | */ 304 | function filterExcludedDependencies(allDependencies, patterns) { 305 | return $._.transform(allDependencies, function (result, dependencies, fileType) { 306 | result[fileType] = $._.reject(dependencies, function (dependency) { 307 | return $._.find(patterns, function (pattern) { 308 | return dependency.replace(/\\/g, '/').match(pattern); 309 | }); 310 | }); 311 | }); 312 | } 313 | 314 | 315 | module.exports = detectDependencies; 316 | -------------------------------------------------------------------------------- /lib/helpers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Returns a set/get style internal storage bucket. 5 | * 6 | * @return {object} the API to set and retrieve data 7 | */ 8 | module.exports.createStore = function () { 9 | var bucket = {}; 10 | 11 | /** 12 | * Sets a property on the store, with the given value. 13 | * 14 | * @param {string} property an identifier for the data 15 | * @param {*} value the value of the data being stored 16 | * @return {function} the set function itself to allow chaining 17 | */ 18 | var set = function (property, value) { 19 | bucket[property] = value; 20 | return set; 21 | }; 22 | 23 | /** 24 | * Returns the store item asked for, otherwise all of the items. 25 | * 26 | * @param {string|undefined} property the property being requested 27 | * @return {*} the store item that was matched 28 | */ 29 | var get = function (property) { 30 | if (!property) { 31 | return bucket; 32 | } 33 | 34 | return bucket[property]; 35 | }; 36 | 37 | return { 38 | set: set, 39 | get: get 40 | }; 41 | }; 42 | -------------------------------------------------------------------------------- /lib/inject-dependencies.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var $ = { 4 | fs: require('fs'), 5 | path: require('path') 6 | }; 7 | 8 | var config; 9 | var fileTypes; 10 | var globalDependenciesSorted; 11 | var ignorePath; 12 | 13 | 14 | /** 15 | * Inject dependencies into the specified source file. 16 | * 17 | * @param {object} globalConfig the global configuration object. 18 | * @return {object} config 19 | */ 20 | function injectDependencies(globalConfig) { 21 | config = globalConfig; 22 | var stream = config.get('stream'); 23 | 24 | globalDependenciesSorted = config.get('global-dependencies-sorted'); 25 | ignorePath = config.get('ignore-path'); 26 | fileTypes = config.get('file-types'); 27 | 28 | if (stream.src) { 29 | config.set('stream', { 30 | src: injectScriptsStream(stream.path, stream.src, stream.fileType), 31 | fileType: stream.fileType 32 | }); 33 | } else { 34 | config.get('src').forEach(injectScripts); 35 | } 36 | 37 | return config; 38 | } 39 | 40 | 41 | function replaceIncludes(file, fileType, returnType) { 42 | /** 43 | * Callback function after matching our regex from the source file. 44 | * 45 | * @param {array} match strings that were matched 46 | * @param {string} startBlock the opening comment 47 | * @param {string} spacing the type and size of indentation 48 | * @param {string} blockType the type of block (js/css) 49 | * @param {string} oldScripts the old block of scripts we'll remove 50 | * @param {string} endBlock the closing comment 51 | * @return {string} the new file contents 52 | */ 53 | return function (match, startBlock, spacing, blockType, oldScripts, endBlock, offset, string) { 54 | blockType = blockType || 'js'; 55 | 56 | var newFileContents = startBlock; 57 | var dependencies = globalDependenciesSorted[blockType] || []; 58 | var quoteMark = ''; 59 | 60 | (string.substr(0, offset) + string.substr(offset + match.length)). 61 | replace(oldScripts, ''). 62 | replace(fileType.block, ''). 63 | replace(fileType.detect[blockType], function (match) { 64 | quoteMark = match.match(/['"]/) && match.match(/['"]/)[0]; 65 | }); 66 | 67 | if (!quoteMark) { 68 | // What the heck. Check if there's anything in the oldScripts block. 69 | match.replace(fileType.detect[blockType], function (match) { 70 | quoteMark = match.match(/['"]/) && match.match(/['"]/)[0]; 71 | }); 72 | } 73 | 74 | spacing = returnType + spacing.replace(/\r|\n/g, ''); 75 | 76 | dependencies. 77 | map(function (filePath) { 78 | return $.path.join( 79 | $.path.relative($.path.dirname(file), $.path.dirname(filePath)), 80 | $.path.basename(filePath) 81 | ).replace(/\\/g, '/').replace(ignorePath, ''); 82 | }). 83 | forEach(function (filePath) { 84 | if (typeof fileType.replace[blockType] === 'function') { 85 | newFileContents += spacing + fileType.replace[blockType](filePath); 86 | } else if (typeof fileType.replace[blockType] === 'string') { 87 | newFileContents += spacing + fileType.replace[blockType].replace('{{filePath}}', filePath); 88 | } 89 | if (quoteMark) { 90 | newFileContents = newFileContents.replace(/"/g, quoteMark); 91 | } 92 | config.get('on-path-injected')({ 93 | block: blockType, 94 | file: file, 95 | path: filePath 96 | }); 97 | }); 98 | 99 | return newFileContents + spacing + endBlock; 100 | }; 101 | } 102 | 103 | 104 | /** 105 | * Take a file path, read its contents, inject the Bower packages, then write 106 | * the new file to disk. 107 | * 108 | * @param {string} filePath path to the source file 109 | */ 110 | function injectScripts(filePath) { 111 | var contents = String($.fs.readFileSync(filePath)); 112 | var fileExt = $.path.extname(filePath).substr(1); 113 | var fileType = fileTypes[fileExt] || fileTypes['default']; 114 | var returnType = /\r\n/.test(contents) ? '\r\n' : '\n'; 115 | 116 | var newContents = contents.replace( 117 | fileType.block, 118 | replaceIncludes(filePath, fileType, returnType) 119 | ); 120 | 121 | if (contents !== newContents) { 122 | $.fs.writeFileSync(filePath, newContents); 123 | 124 | config.get('on-file-updated')(filePath); 125 | } 126 | } 127 | 128 | 129 | function injectScriptsStream(filePath, contents, fileExt) { 130 | var returnType = /\r\n/.test(contents) ? '\r\n' : '\n'; 131 | var fileType = fileTypes[fileExt] || fileTypes['default']; 132 | 133 | var newContents = contents.replace( 134 | fileType.block, 135 | replaceIncludes(filePath, fileType, returnType) 136 | ); 137 | 138 | config.get('on-file-updated')(filePath); 139 | 140 | return newContents; 141 | } 142 | 143 | 144 | module.exports = injectDependencies; 145 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep", 3 | "version": "4.0.0", 4 | "main": "./wiredep.js", 5 | "description": "Wire Bower dependencies to your source code.", 6 | "repository": "taptapship/wiredep", 7 | "author": { 8 | "name": "Stephen Sawchuk", 9 | "email": "sawchuk@gmail.com" 10 | }, 11 | "keywords": [ 12 | "bower", 13 | "package", 14 | "management", 15 | "inject", 16 | "script", 17 | "dependencies" 18 | ], 19 | "files": [ 20 | "lib/", 21 | "LICENSE", 22 | "wiredep.js" 23 | ], 24 | "license": "MIT", 25 | "scripts": { 26 | "test": "jshint *.js lib/*.js test/*.js && NODE_ENV=test mocha -R spec", 27 | "coverage": "istanbul cover _mocha -- -R spec" 28 | }, 29 | "dependencies": { 30 | "bower-config": "^1.3.0", 31 | "glob": "^7.0.3", 32 | "lodash": "^4.6.1", 33 | "propprop": "^0.3.0", 34 | "through2": "^2.0.1", 35 | "wiredep-cli": "^0.1.0" 36 | }, 37 | "devDependencies": { 38 | "chai": "^3.5.0", 39 | "fs-extra": "^0.26.7", 40 | "istanbul": "^0.4.2", 41 | "jshint": "*", 42 | "mocha": "*" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # wiredep [![npm](https://badge.fury.io/js/wiredep.svg)](http://badge.fury.io/js/wiredep) [![Build Status](https://travis-ci.org/taptapship/wiredep.svg?branch=master)](https://travis-ci.org/taptapship/wiredep) 2 | > Wire [Bower](http://bower.io) dependencies to your source code. 3 | 4 | ## Getting Started 5 | Install the module with [npm](https://npmjs.org): 6 | 7 | ```bash 8 | $ npm install --save wiredep 9 | ``` 10 | 11 | Install your dependencies (if you haven't already): 12 | 13 | ```bash 14 | $ bower install --save jquery 15 | ``` 16 | 17 | Insert placeholders in your code where your dependencies will be injected: 18 | 19 | ```html 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | ``` 31 | 32 | Let `wiredep` work its magic: 33 | 34 | ```bash 35 | $ node 36 | > require('wiredep')({ src: 'index.html' }); 37 | 38 | index.html modified. 39 | { packages: 40 | { jquery: 41 | { main: [Object], 42 | type: [Object], 43 | name: 'jquery', 44 | dependencies: {} } }, 45 | js: [ 'bower_components/jquery/dist/jquery.js' ] } 46 | ``` 47 | 48 | 49 | ```html 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | ``` 62 | 63 | ## How it Works 64 | Installing a Bower package with `--save` will add the package as a `dependency` in your project's `bower.json` file. This library reads that file, then reads the `bower.json` files for each of those dependencies. Based on these connections, it determines the order your scripts must be included before injecting them between placeholders in your source code. 65 | 66 | ## What can go wrong? 67 | 68 | - A Bower package may not properly list its `dependencies` in its bower.json file. 69 | 70 | - A Bower package may not specify a `main` property in its bower.json file. 71 | 72 | In both of these cases, it is most helpful to send a PR to the offending repository with a solution. This isn't just a fix for wiredep, but for other tools which conform to the Bower specification. Most often it's just an author's oversight, so they will welcome the contribution and clarity. 73 | 74 | If that solution doesn't work, you can get around these problems by [overriding properties](#bower-overrides). 75 | 76 | ## Build Chain Integration 77 | 78 | ### [gulp.js](http://gulpjs.com/) 79 | 80 | wiredep works with [streams](https://github.com/substack/stream-handbook) and integrates with gulp.js out of the box: 81 | 82 | ```js 83 | var wiredep = require('wiredep').stream; 84 | 85 | gulp.task('bower', function () { 86 | gulp.src('./src/footer.html') 87 | .pipe(wiredep({ 88 | optional: 'configuration', 89 | goes: 'here' 90 | })) 91 | .pipe(gulp.dest('./dest')); 92 | }); 93 | ``` 94 | 95 | ### [Grunt](http://gruntjs.com) 96 | 97 | See [`grunt-wiredep`](https://github.com/stephenplusplus/grunt-wiredep). 98 | 99 | 100 | ## Programmatic Access 101 | You can run `wiredep` without manipulating any files. 102 | 103 | ```js 104 | require('wiredep')(); 105 | ``` 106 | 107 | ...returns... 108 | ```js 109 | { 110 | js: [ 111 | 'paths/to/your/js/files.js', 112 | 'in/their/order/of/dependency.js' 113 | ], 114 | css: [ 115 | 'paths/to/your/css/files.css' 116 | ], 117 | // etc. 118 | } 119 | ``` 120 | 121 | 122 | ## Command Line 123 | ** wiredep-cli has been split into its own module. In a future release it will not be included in this package anymore ** 124 | 125 | Install [wiredep-cli](https://github.com/taptapship/wiredep-cli) to use the CLI. 126 | 127 | ```sh 128 | $ npm install -g wiredep-cli 129 | ``` 130 | 131 | ## Configuration 132 | 133 | ```js 134 | require('wiredep')({ 135 | directory: 'the directory of your Bower packages.', // default: '.bowerrc'.directory || bower_components 136 | bowerJson: 'your bower.json file contents.', // default: require('./bower.json') 137 | src: ['filepaths', 'and/even/globs/*.html', 'to take', 'control of.'], 138 | 139 | // ----- Advanced Configuration ----- 140 | // All of the below settings are for advanced configuration, to 141 | // give your project support for additional file types and more 142 | // control. 143 | // 144 | // Out of the box, wiredep will handle HTML files just fine for 145 | // JavaScript and CSS injection. 146 | 147 | cwd: 'path/to/where/we/are/pretending/to/be', 148 | 149 | dependencies: true, // default: true 150 | devDependencies: true, // default: false 151 | includeSelf: true, // default: false 152 | 153 | exclude: [ /jquery/, 'bower_components/modernizr/modernizr.js' ], 154 | 155 | ignorePath: /string or regexp to ignore from the injected filepath/, 156 | 157 | overrides: { 158 | // see `Bower Overrides` section below. 159 | // 160 | // This inline object offers another way to define your overrides if 161 | // modifying your project's `bower.json` isn't an option. 162 | }, 163 | 164 | onError: function(err) { 165 | // If not overridden, an error will throw. 166 | 167 | // err = Error object. 168 | // err.code can be: 169 | // - "PKG_NOT_INSTALLED" (a Bower package was not found) 170 | // - "BOWER_COMPONENTS_MISSING" (cannot find the `bower_components` directory) 171 | }, 172 | 173 | onFileUpdated: function(filePath) { 174 | // filePath = 'name-of-file-that-was-updated' 175 | }, 176 | 177 | onPathInjected: function(fileObject) { 178 | // fileObject.block = 'type-of-wiredep-block' ('js', 'css', etc) 179 | // fileObject.file = 'name-of-file-that-was-updated' 180 | // fileObject.path = 'path-to-file-that-was-injected' 181 | }, 182 | 183 | onMainNotFound: function(pkg) { 184 | // pkg = 'name-of-bower-package-without-main' 185 | }, 186 | 187 | fileTypes: { 188 | fileExtension: { 189 | block: /match the beginning-to-end of a bower block in this type of file/, 190 | detect: { 191 | typeOfBowerFile: /match the way this type of file is included/ 192 | }, 193 | replace: { 194 | typeOfBowerFile: '', 195 | anotherTypeOfBowerFile: function (filePath) { 196 | return ''; 197 | } 198 | } 199 | }, 200 | 201 | // defaults: 202 | html: { 203 | block: /(([ \t]*))(\n|\r|.)*?()/gi, 204 | detect: { 205 | js: /', 210 | css: '' 211 | } 212 | }, 213 | 214 | jade: { 215 | block: /(([ \t]*)\/\/\s*bower:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi, 216 | detect: { 217 | js: /script\(.*src=['"]([^'"]+)/gi, 218 | css: /link\(.*href=['"]([^'"]+)/gi 219 | }, 220 | replace: { 221 | js: 'script(src=\'{{filePath}}\')', 222 | css: 'link(rel=\'stylesheet\', href=\'{{filePath}}\')' 223 | } 224 | }, 225 | 226 | less: { 227 | block: /(([ \t]*)\/\/\s*bower:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi, 228 | detect: { 229 | css: /@import\s['"](.+css)['"]/gi, 230 | less: /@import\s['"](.+less)['"]/gi 231 | }, 232 | replace: { 233 | css: '@import "{{filePath}}";', 234 | less: '@import "{{filePath}}";' 235 | } 236 | }, 237 | 238 | sass: { 239 | block: /(([ \t]*)\/\/\s*bower:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi, 240 | detect: { 241 | css: /@import\s(.+css)/gi, 242 | sass: /@import\s(.+sass)/gi, 243 | scss: /@import\s(.+scss)/gi 244 | }, 245 | replace: { 246 | css: '@import {{filePath}}', 247 | sass: '@import {{filePath}}', 248 | scss: '@import {{filePath}}' 249 | } 250 | }, 251 | 252 | scss: { 253 | block: /(([ \t]*)\/\/\s*bower:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi, 254 | detect: { 255 | css: /@import\s['"](.+css)['"]/gi, 256 | sass: /@import\s['"](.+sass)['"]/gi, 257 | scss: /@import\s['"](.+scss)['"]/gi 258 | }, 259 | replace: { 260 | css: '@import "{{filePath}}";', 261 | sass: '@import "{{filePath}}";', 262 | scss: '@import "{{filePath}}";' 263 | } 264 | }, 265 | 266 | styl: { 267 | block: /(([ \t]*)\/\/\s*bower:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi, 268 | detect: { 269 | css: /@import\s['"](.+css)['"]/gi, 270 | styl: /@import\s['"](.+styl)['"]/gi 271 | }, 272 | replace: { 273 | css: '@import "{{filePath}}"', 274 | styl: '@import "{{filePath}}"' 275 | } 276 | }, 277 | 278 | yaml: { 279 | block: /(([ \t]*)#\s*bower:*(\S*))(\n|\r|.)*?(#\s*endbower)/gi, 280 | detect: { 281 | js: /-\s(.+js)/gi, 282 | css: /-\s(.+css)/gi 283 | }, 284 | replace: { 285 | js: '- {{filePath}}', 286 | css: '- {{filePath}}' 287 | } 288 | } 289 | ``` 290 | 291 | 292 | ## Bower Overrides 293 | To override a property, or lack of, in one of your dependency's `bower.json` file, you may specify an `overrides` object in your own `bower.json`. 294 | 295 | As an example, this is what your `bower.json` may look like if you wanted to override `package-without-main`'s `main` file (the path is relative to your dependency's folder): 296 | 297 | ```js 298 | { 299 | ... 300 | "dependencies": { 301 | "package-without-main": "1.0.0" 302 | }, 303 | "overrides": { 304 | "package-without-main": { 305 | "main": "dist/package-without-main.js" 306 | } 307 | } 308 | } 309 | ``` 310 | 311 | If the project has multiple files, such as a javascript and a css file, `main` can be an array, as such: 312 | 313 | ```js 314 | { 315 | ... 316 | "dependencies": { 317 | "package-without-main": "1.0.0" 318 | }, 319 | "overrides": { 320 | "package-without-main": { 321 | "main": ["dist/package-without-main.css", "dist/package-without-main.js"] 322 | } 323 | } 324 | } 325 | ``` 326 | 327 | ## Contributing 328 | In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using `npm test`. 329 | 330 | 331 | ## License 332 | Copyright (c) 2014 Stephen Sawchuk. Licensed under the MIT license. 333 | -------------------------------------------------------------------------------- /test/fixture/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "codecode": "0.0.3", 6 | "bootstrap": "3.0.0", 7 | "modular-scale": "2.0.3", 8 | "3l": "1.4.4", 9 | "karma": "0.2.1" 10 | }, 11 | "devDependencies": { 12 | "things": "0.1.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/fixture/bower_after_uninstall.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "bootstrap": "~3.0.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixture/bower_after_uninstall_all.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixture/bower_components/3l/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "3l", 3 | "version": "1.4.4", 4 | "main": "3L/3L.less", 5 | "description": "Lots of Love for LESS - the up-to-date mixins library for the LESS preprocessor", 6 | "homepage": "http://mateuszkocz.github.io/3l/", 7 | "author": { 8 | "name": "Mateusz Kocz", 9 | "web": "http://mateusz.kocz.pl" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/mateuszkocz/3l.git" 14 | }, 15 | "keywords": ["css", "css3", "less", "mixins"], 16 | "licenses": [ 17 | { 18 | "type": "MIT", 19 | "url": "https://github.com/mateuszkocz/3l/blob/master/3L/LICENCES.md" 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /test/fixture/bower_components/bootstrap/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap", 3 | "version": "3.0.0", 4 | "main": ["./dist/js/bootstrap.js", "./dist/css/bootstrap.css"], 5 | "ignore": [ 6 | "**/.*" 7 | ], 8 | "dependencies": { 9 | "jquery": ">= 1.9.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/fixture/bower_components/codecode/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codecode", 3 | "version": "0.0.3", 4 | "author": "Stephen Sawchuk", 5 | "description": "codecode allows your readers to dock your syntax-highlighted code blocks to the bottom of the page, allowing them to refer back without losing their place in your article.", 6 | "homepage": "http://stephenplusplus.github.com/codecode", 7 | "main": [ 8 | "./dist/codecode.js", 9 | "./dist/codecode.css" 10 | ], 11 | "readme": "./readme.md", 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/stephenplusplus/codecode.git" 15 | }, 16 | "dependencies": { 17 | "jquery": ">= 1.8.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/fixture/bower_components/codecode/dist/codecode.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-size: 900px; 3 | } -------------------------------------------------------------------------------- /test/fixture/bower_components/codecode/dist/codecode.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * codecode. 3 | * v0.0.3 @stephenplusplus 4/1/13 4 | * github.com/stephenplusplus/codecode 5 | */ 6 | (function($, win, doc) { 7 | var styles 8 | ='.acodecode {' 9 | + 'cursor: pointer;' 10 | +'}' 11 | 12 | +'.acodecodeactive {' 13 | + 'cursor: default;' 14 | +'}' 15 | 16 | +'.codecodecode {' 17 | + 'position: fixed;' 18 | + 'z-index: 100;' 19 | + 'left: 2%;' 20 | + 'bottom: -30px;' 21 | + 'width: 96%;' 22 | + 'height: 0;' 23 | + 'max-height: 270px;' 24 | + 'text-align: left;' 25 | +'}' 26 | 27 | +'.codecodecode > div {' 28 | +' box-shadow: 0 0 3px #444;' 29 | +'}' 30 | 31 | +'.codecodecontrols {' 32 | + 'height: 30px;' 33 | + 'margin-top: -30px;' 34 | + 'background-color: #fff;' 35 | + 'background-color: rgba(255, 255, 255, .8);' 36 | + 'border-radius: 8px 8px 0 0;' 37 | +'}' 38 | 39 | +'.codecodecontrols a {' 40 | + 'float: left;' 41 | + 'line-height: 30px;' 42 | + 'margin-left: 6px;' 43 | + 'font-family: Arial;' 44 | + 'font-size: 12px;' 45 | +'}' 46 | 47 | +'.codecodecontrols .closecodecode {' 48 | + 'float: right;' 49 | + 'margin-right: 6px;' 50 | +'}' 51 | 52 | +'.codecode {' 53 | + 'border-radius: 0 !important;' 54 | + 'position: relative !important;' 55 | + 'width: 100% !important;' 56 | + 'margin: 0 !important;' 57 | + 'overflow: auto !important;' 58 | + 'cursor: default !important;' 59 | +'}' 60 | 61 | +'div.codecode [id^=highlighter] div.bar.show,' 62 | +'div.codecode [id^=highlighter] div.toolbar {' 63 | + 'display: none !important;' 64 | +'}'; 65 | 66 | var el = {}; 67 | el.body 68 | = $(doc.body); 69 | 70 | el.codecodecode 71 | = $('
' 72 | + '
' 73 | + 'go back to the code.' 74 | + 'close.' 75 | + '
' 76 | + '
' 77 | +'
'); 78 | 79 | el.gobacktothecode 80 | = el.codecodecode.find('.gobacktothecode'); 81 | 82 | el.closecodecode 83 | = el.codecodecode.find('.closecodecode'); 84 | 85 | el.codecode 86 | = el.codecodecode.find('.codecode'); 87 | 88 | el.body 89 | .append('') 90 | .append(el.codecodecode); 91 | 92 | var codeposition; 93 | 94 | var gobacktothecode = function(e) { 95 | e.preventDefault(); 96 | 97 | closecodecode(); 98 | 99 | el.body.animate({ scrollTop: codeposition - 20 }, 2000); 100 | }; 101 | 102 | var closecodecode = function(e, callback) { 103 | if ($.type(e) === 'object') 104 | e.preventDefault(); 105 | 106 | el.body.off('keyup'); 107 | 108 | el.codecodecode 109 | .animate({ bottom: '-300px' }, 300, callback || $.noop); 110 | 111 | $('.acodecodeactive').removeClass('acodecodeactive'); 112 | }; 113 | 114 | var opencodecode = function(codeblock) { 115 | el.codecodecode 116 | .animate({ bottom: 0 }, 500); 117 | 118 | el.body.on('keyup', function(e) { 119 | if (e.which === 27) 120 | closecodecode(); 121 | }); 122 | 123 | codeblock 124 | .addClass('acodecodeactive'); 125 | }; 126 | 127 | var bindcodecodeclick = function(selector) { 128 | el.body.on('click', selector, function() { 129 | var codeblock = $(this); 130 | 131 | if (codeblock.hasClass('acodecodeactive') || codeblock.hasClass('codecode')) 132 | return; 133 | 134 | codeposition = $(this).position().top; 135 | 136 | var clone = 137 | codeblock 138 | .clone() 139 | .addClass('codecode'); 140 | 141 | closecodecode(null, function() { 142 | el.codecode 143 | .empty() 144 | .append(clone.css('margin', '0 !important')) 145 | .height('auto'); 146 | 147 | el.codecodecode 148 | .height(el.codecode.height() >= 270 ? 270 : el.codecode.height()); 149 | 150 | el.codecode 151 | .height('100%'); 152 | }); 153 | 154 | opencodecode(codeblock); 155 | }); 156 | }; 157 | 158 | el.gobacktothecode 159 | .on('click', gobacktothecode); 160 | 161 | el.closecodecode 162 | .on('click', closecodecode); 163 | 164 | $.fn.codecode = function() { 165 | bindcodecodeclick(this.selector); 166 | 167 | return this.addClass('acodecode'); 168 | }; 169 | 170 | if (typeof SyntaxHighlighter !== 'undefined') 171 | SyntaxHighlighter.all = (function() { 172 | var callsyntaxhighlighter = SyntaxHighlighter.all 173 | , syntaxactivated = false 174 | , checkforsyntaxels 175 | , tried = 0; 176 | 177 | var hassyntaxbeenhighlighted = function() { 178 | if ($('.syntaxhighlighter').length > 0) 179 | $('.syntaxhighlighter').codecode(), 180 | syntaxactivated = true; 181 | 182 | if (syntaxactivated || tried++ > 50) 183 | win.clearInterval(checkforsyntaxels); 184 | }; 185 | 186 | return function() { 187 | callsyntaxhighlighter(); 188 | 189 | checkforsyntaxels = win.setInterval(hassyntaxbeenhighlighted, 50); 190 | } 191 | })(); 192 | 193 | })(jQuery, window, document); 194 | -------------------------------------------------------------------------------- /test/fixture/bower_components/fake-package-with-override/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fake-package-without-main", 3 | "version": "1.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /test/fixture/bower_components/fake-package-with-override/dist/fake-package-with-override.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* this should be injected! */ 3 | } 4 | -------------------------------------------------------------------------------- /test/fixture/bower_components/fake-package-with-override/dist/fake-package-with-override.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // this should be injected! 3 | })(); 4 | -------------------------------------------------------------------------------- /test/fixture/bower_components/fake-package-without-dependencies/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fake-package-without-dependencies", 3 | "version": "1.0.0", 4 | "main": "fake-package-without-dependencies.js" 5 | } 6 | -------------------------------------------------------------------------------- /test/fixture/bower_components/fake-package-without-dependencies/fake-package-without-dependencies.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // this should still be injected! 3 | })(); 4 | -------------------------------------------------------------------------------- /test/fixture/bower_components/fake-package-without-main-and-confusing-file-tree/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fake-package-without-main-and-confusing-file-tree", 3 | "version": "1.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /test/fixture/bower_components/fake-package-without-main-and-confusing-file-tree/dist/fake-package-without-main-and-confusing-file-tree.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* this file should not be injected. */ 3 | } 4 | -------------------------------------------------------------------------------- /test/fixture/bower_components/fake-package-without-main-and-confusing-file-tree/dist/fake-package-without-main-and-confusing-file-tree.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // this file should not be injected. 3 | })(); 4 | -------------------------------------------------------------------------------- /test/fixture/bower_components/fake-package-without-main/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fake-package-without-main", 3 | "version": "1.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /test/fixture/bower_components/fake-package-without-main/fake-package-without-main.css: -------------------------------------------------------------------------------- 1 | body { 2 | /* this should still be injected! */ 3 | } 4 | -------------------------------------------------------------------------------- /test/fixture/bower_components/fake-package-without-main/fake-package-without-main.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // this should still be injected! 3 | })(); 4 | -------------------------------------------------------------------------------- /test/fixture/bower_components/jquery/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "version": "2.0.3", 4 | "description": "jQuery component", 5 | "keywords": [ 6 | "jquery", 7 | "component" 8 | ], 9 | "main": "jquery.js", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /test/fixture/bower_components/karma/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Karma.gs", 3 | "version": "0.2.1", 4 | "authors": [ 5 | "Nathan Kot " 6 | ], 7 | "description": "A Stylus grid system for savvy developers.", 8 | "main": "dist/karma.styl", 9 | "keywords": [ 10 | "grid", 11 | "system", 12 | "stylus", 13 | "typographic" 14 | ], 15 | "license": "Apache 2.0", 16 | "homepage": "https://github.com/nathankot/Karma.gs" 17 | } 18 | -------------------------------------------------------------------------------- /test/fixture/bower_components/karma/dist/karma.styl: -------------------------------------------------------------------------------- 1 | _goldilocks ?= 30em 2 | _goldilocks_padding ?= 0.809em 3 | _grid_columns ?= 6 4 | _gutter_width ?= 1.2em 5 | _grid_expand_min_proportion ?= .2 6 | 7 | _base_size ?= 125% 8 | 9 | baby ?= s("screen and (max-width: %s)", ((_goldilocks + 4*_goldilocks_padding) * _base_size/100)) 10 | mummy ?= s("screen and (min-width: %s) and (max-width: %s)", ((_goldilocks + 4*_goldilocks_padding) * _base_size/100), ((_goldilocks*2 + 4*_goldilocks_padding) * _base_size/100)) 11 | daddy ?= s("screen and (min-width: %s)", ((_goldilocks + 4*_goldilocks_padding) * _base_size/100)) 12 | daddyOnly ?= s("screen and (min-width: %s)", ((_goldilocks*2 + 4*_goldilocks_padding) * _base_size/100)) 13 | 14 | _sequence_fibonacci ?= 0.6154 0.6154 0.6154 0.6154 1 1.6154 2.6154 3.6154 3.6154 3.6154 15 | _sequence_traditional ?= 0.666 0.75 0.8333 0.9167 1 1.1667 1.333 1.5 1.75 2 3 4 5 6 16 | _sequence_lecobusier ?= 0.6154 0.6154 0.6154 0.8077 1 1.3077 1.6154 2.1154 2.615 3.4231 17 | _sequence_center ?= 4 18 | 19 | _line_height ?= 1.6 20 | _typographic_scale ?= _sequence_traditional 21 | 22 | expand_for(size) 23 | -kgs-expand-for size 24 | 25 | ignore_media_queries() 26 | -kgs-ignore-media 1 27 | 28 | always_expand() 29 | -kgs-always-expand 1 30 | 31 | container() 32 | padding 0 unit(_goldilocks_padding, 'em') 0 unit(_goldilocks_padding, 'em') 33 | max-width unit(_goldilocks, 'em') 34 | margin auto 35 | 36 | @media daddy 37 | padding 0 unit(_goldilocks_padding*2, 'em') 0 unit(_goldilocks_padding*2, 'em') 38 | margin-left auto 39 | margin-right auto 40 | max-width unit(_goldilocks*2, 'em') 41 | 42 | @media mummy 43 | width unit(_goldilocks, 'em') 44 | 45 | row(columns = _grid_columns) 46 | clearfix() 47 | display block 48 | width 100% 49 | padding 0 50 | margin 0 51 | @media daddy 52 | _generate_row(2, columns) 53 | @media mummy 54 | _generate_row(1, _grid_columns) if @-kgs-expand-for == 'mummy' 55 | _generate_row(1, columns) if @-kgs-expand-for != 'mummy' 56 | 57 | columns(span = 1) 58 | float left 59 | margin-right 0 unless @margin-right == 0 60 | padding-left 0 unless @padding-left == 0 61 | padding-right 0 unless @padding-right == 0 62 | 63 | -kgs-always-expand 1 if @-kgs-expand-for is defined 64 | 65 | if @-kgs-always-expand != 1 && span <= (_grid_columns * _grid_expand_min_proportion) 66 | width round(((span / _grid_columns)*100)%) 67 | else 68 | width 100% 69 | 70 | unless @-kgs-ignore-media == 1 71 | & 72 | 73 | @media daddy 74 | _generate_column(span, 2) 75 | 76 | @media mummy 77 | // I can explain... well.. no.. 78 | // but doesn't work any other way... 79 | margin-left 0 if @-kgs-expand-for == 'mummy' 80 | box-sizing border-box if @-kgs-expand-for == 'mummy' 81 | padding-left _gutter_width if @-kgs-expand-for == 'mummy' 82 | width 100% if @-kgs-expand-for == 'mummy' 83 | _generate_column(span) unless @-kgs-expand-for == 'mummy' 84 | 85 | offset(span = 1) 86 | @media daddy 87 | margin-left (_get_span_width(span, 2) + _gutter_width * 2)!important 88 | @media mummy 89 | margin-left (_get_span_width(span) + _gutter_width * 2)!important 90 | 91 | pull_right() 92 | float right 93 | 94 | _get_column_width(size_multiple = 1) 95 | ( (_goldilocks * size_multiple) - (_grid_columns - 1) * _gutter_width ) / (_grid_columns) 96 | 97 | _get_span_width(columns, size_multiple = 1) 98 | columns * _get_column_width(size_multiple) + (columns - 1) * _gutter_width 99 | 100 | _generate_row(size_multiple = 1, columns = _grid_columns) 101 | width (_get_span_width(columns, size_multiple) + _gutter_width) 102 | margin-left (_gutter_width * -1) 103 | 104 | _generate_column(size, size_multiple = 1) 105 | // Fix for unpredictable rounding in some browsers 106 | width (_get_span_width(size, size_multiple) - 0.01em) 107 | margin-left _gutter_width 108 | 109 | rotate(degrees) 110 | transform 'rotate(%s)' % degrees 111 | 112 | scale(ratio) 113 | transform 'scale(%s)' % ratio 114 | 115 | translate(x, y) 116 | transform 'translate(%s, %s)' % (x y) 117 | 118 | skew(x, y) 119 | transform 'skew(%s, %s)' % (x y) 120 | 121 | translate3d(x, y, z) 122 | transform 'translate(%s, %s, %s)' % (x y z) 123 | 124 | html 125 | font-size _base_size 126 | 127 | html, body 128 | line-height _line_height 129 | 130 | /** 131 | * Based upon http://lamb.cc/typograph/ 132 | */ 133 | 134 | scale_type(position) 135 | position = _sequence_center + position 136 | font_size = (_typographic_scale[position])rem 137 | line_height = unit(_line_height, '') 138 | 139 | lines_req = font_size / line_height 140 | if lines_req > .9 && lines_req < 1 141 | lines_req = lines_req + 1 142 | lines_req = ceil(lines_req) 143 | 144 | font-size unit(font_size, 'em') 145 | font-size unit(font_size, 'rem') 146 | line-height (lines_req * _line_height)rem 147 | 148 | line_breaks(n = 1) 149 | return (_line_height*n)rem 150 | 151 | -------------------------------------------------------------------------------- /test/fixture/bower_components/modular-scale/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "modular-scale", 3 | "version": "2.0.3", 4 | "main": "stylesheets/_modular-scale.scss", 5 | "ignore": [ 6 | "lib", 7 | "test-compass", 8 | "test-node-sass" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /test/fixture/bower_components/modular-scale/stylesheets/_modular-scale-tests.scss: -------------------------------------------------------------------------------- 1 | @if "#{ms(2, 16, $minor-sixth)}" != "40.96" { 2 | @debug ""; 3 | @warn "function ms(): FAIL!"; 4 | @debug "function ms(2, 16, $minor-sixth)"; 5 | @debug "Result: #{ms(2, 16, $minor-sixth)}"; 6 | @debug "Intended: 40.96"; 7 | @debug ""; 8 | }@else { 9 | @warn "function ms(+): pass"; 10 | } 11 | 12 | @if "#{ms(-2, 16, $minor-sixth)}" != "6.25" { 13 | @debug ""; 14 | @warn "function ms(): FAIL!"; 15 | @debug "function ms(-2, 16, $minor-sixth)"; 16 | @debug "Result: #{ms(-2, 16, $minor-sixth)}"; 17 | @debug "Intended: 6.25"; 18 | @debug ""; 19 | }@else { 20 | @warn "function ms(-): pass"; 21 | } 22 | 23 | @if ms(2, 14 18, $major-second) != 15.75 { 24 | @debug ""; 25 | @warn "function ms() multi-base: FAIL!"; 26 | @debug "function ms(2, 14 18, $major-second)"; 27 | @debug "Result: #{ms(2, 14 18, $major-second)}"; 28 | @debug "Intended: 15.75"; 29 | @debug ""; 30 | }@else { 31 | @warn "function ms(+) multi-base: pass"; 32 | } 33 | 34 | @if ms(-1, 14 18, $major-third) != 11.52 { 35 | @debug ""; 36 | @warn "function ms() multi-base: FAIL!"; 37 | @debug "function ms(-1, 14 18, $major-third)"; 38 | @debug "Result: #{ms(-1, 14 18, $major-third)}"; 39 | @debug "Intended: 11.52"; 40 | @debug ""; 41 | }@else { 42 | @warn "function ms(-) multi-base: pass"; 43 | } 44 | 45 | @if "#{ms(-4, 12, $major-tenth $octave)}" != "1.92" { 46 | @debug ""; 47 | @warn "function ms() multi-ratio: FAIL!"; 48 | @debug "function ms(-4, 12, $major-tenth $octave)"; 49 | @debug "Result: #{ms(-4, 12, $major-tenth $octave)}"; 50 | @debug "Intended: 1.92"; 51 | @debug ""; 52 | }@else { 53 | @warn "function ms(+) multi-ratio: pass"; 54 | } 55 | 56 | @if ms(-4, 12, $major-tenth $octave) != 1.92 { 57 | @debug ""; 58 | @warn "function ms() multi-ratio: FAIL!"; 59 | @debug "function ms(-4, 12, $major-tenth $octave)"; 60 | @debug "Result: #{ms(-4, 12, $major-tenth $octave)}"; 61 | @debug "Intended: 1.92"; 62 | @debug ""; 63 | }@else { 64 | @warn "function ms(-) multi-ratio: pass"; 65 | } 66 | 67 | @if ms-list(-3, 3, 10 16, $major-third) != (6.5536 8 8.192 10 10.24 12.5 12.8) { 68 | @debug "function ms-list(): FAIL!"; 69 | @warn "function ms-list(-3, 3, 10 16, $major-third)"; 70 | @debug "Result: (#{ms-list(-3, 3, 10 16, $major-third)})"; 71 | @debug "Intended: (6.5536 8 8.192 10 10.24 12.5 12.8)"; 72 | }@else { 73 | @warn "function ms-list(): pass"; 74 | } -------------------------------------------------------------------------------- /test/fixture/bower_components/modular-scale/stylesheets/_modular-scale.scss: -------------------------------------------------------------------------------- 1 | @import "modular-scale/ratios"; 2 | 3 | $ms-base: 1em !default; 4 | $ms-ratio: $golden !default; 5 | 6 | @import "modular-scale/tests"; 7 | 8 | @import "modular-scale/pow"; 9 | @import "modular-scale/calc"; 10 | @import "modular-scale/generate-list"; 11 | @import "modular-scale/sort-list"; 12 | @import "modular-scale/function"; 13 | @import "modular-scale/function-list"; 14 | -------------------------------------------------------------------------------- /test/fixture/bower_components/modular-scale/stylesheets/modular-scale/_calc.scss: -------------------------------------------------------------------------------- 1 | @function ms-calc($Value, $Base: $ms-base, $Ratio: $ms-ratio) { 2 | 3 | // If pow exists use it. 4 | // It supports non-interger values! 5 | @if $MS-pow-exists { 6 | 7 | // The formula for figuring out modular scales is: 8 | // (r^v)*b 9 | @return pow($Ratio, $Value) * $Base; 10 | } 11 | 12 | // If not, use ms-pow(). 13 | // Not as fast or capable of non-integer exponents. 14 | @else { 15 | @return ms-pow($Ratio, $Value) * $Base; 16 | } 17 | } -------------------------------------------------------------------------------- /test/fixture/bower_components/modular-scale/stylesheets/modular-scale/_function-list.scss: -------------------------------------------------------------------------------- 1 | // Outputs a list of values instead of a single value 2 | @function ms-list($Start: 0, $End: 0, $Bases: $ms-base, $Ratios: $ms-ratio) { 3 | 4 | // Seed results 5 | $Positive-return: (); 6 | $Negitive-return: (); 7 | $Return: (); 8 | 9 | @if $End >= 0 { 10 | // Generate a list of all possible values 11 | $Positive-return: ms-generate-list($End, $Bases, $Ratios); 12 | 13 | // Sort the generated lists 14 | $Positive-return: ms-sort-list($Positive-return); 15 | 16 | // Trim list 17 | $Trim-list: (); 18 | // If the starting value is a positive number 19 | // trim the positive return from that 20 | @if $Start >= 0 { 21 | @for $i from ($Start + 1) through $End + 1 { 22 | $Trim-list: join($Trim-list, nth($Positive-return, $i)); 23 | } 24 | } 25 | // If not, then include everything up to the end. 26 | @else { 27 | @for $i from 1 through $End + 1 { 28 | $Trim-list: join($Trim-list, nth($Positive-return, $i)); 29 | } 30 | } 31 | $Positive-return: $Trim-list; 32 | } 33 | 34 | // Generate a negitive list 35 | @if $Start < 0 { 36 | // Generate a list of all possible values 37 | $Negitive-return: ms-generate-list($Start, $Bases, $Ratios); 38 | 39 | // Sort the generated lists 40 | $Negitive-return: ms-sort-list($Negitive-return); 41 | 42 | // Reverse negitive list results. 43 | $MS-new-return: (); 44 | @each $i in $Negitive-return { 45 | $MS-new-return: join($i, $MS-new-return); 46 | } 47 | $Negitive-return: $MS-new-return; 48 | 49 | // Trim list 50 | $Trim-list: (); 51 | @if $End < 0 { 52 | @for $i from abs($End) through (abs($Start) + 2) { 53 | $Trim-list: join(nth($Negitive-return, $i), $Trim-list); 54 | } 55 | } 56 | @else { 57 | @for $i from 2 through (abs($Start) + 1) { 58 | $Trim-list: join(nth($Negitive-return, $i), $Trim-list); 59 | } 60 | } 61 | $Negitive-return: $Trim-list; 62 | } 63 | 64 | // Join both positive and negitive possibilities. 65 | $Return: join($Negitive-return, $Positive-return); 66 | 67 | @return $Return; 68 | } 69 | -------------------------------------------------------------------------------- /test/fixture/bower_components/modular-scale/stylesheets/modular-scale/_function.scss: -------------------------------------------------------------------------------- 1 | // The main function that brings it all together 2 | @function ms($Value: 0, $Bases: $ms-base, $Ratios: $ms-ratio) { 3 | 4 | // If no multi-base or multi-ratio stuff is going on 5 | // then just retrn the basic calculaiton 6 | @if length($Bases) == 1 and length($Ratios) == 1 { 7 | @return ms-calc($Value, $Bases, $Ratios); 8 | } 9 | 10 | // Do calculations directly in Ruby when avalible 11 | @if $MS-gem-exists { 12 | 13 | // Remove units from bases 14 | $Unit: nth($Bases, 1) * 0 + 1; // Extracts the unit from the base 15 | $Unitless-Bases: (); 16 | @each $Base in $Bases { 17 | $Base: $Base/$Unit; 18 | $Unitless-Bases: join($Unitless-Bases, $Base); 19 | } 20 | 21 | // Calculate natively in Ruby 22 | @return ms-gem-func($Value, $Unitless-Bases, $Ratios) * $Unit; 23 | } 24 | 25 | // Generate a list of all possible values 26 | $Return: ms-generate-list($Value, $Bases, $Ratios); 27 | 28 | // Sort the generated lists 29 | $Return: ms-sort-list($Return); 30 | 31 | // Reverse list if its negitive. 32 | @if $Value < 0 { 33 | $MS-new-return: (); 34 | @each $i in $Return { 35 | $MS-new-return: join($i, $MS-new-return); 36 | } 37 | $Return: $MS-new-return; 38 | } 39 | 40 | // Normalize value for counting from 1 41 | // Because CSS counts things from 1 42 | // So Sass does as well 43 | // So I get to write fun stuff like this 44 | $Value: abs($Value) + 1; 45 | 46 | // Find the correct value in the list 47 | $Return: nth($Return, $Value); 48 | 49 | @return $Return; 50 | } 51 | 52 | // Same function, different name, for good measure. 53 | @function modular-scale($Value: 0, $Bases: $ms-base, $Ratios: $ms-ratio) { 54 | @return ms($Value, $Bases, $Ratios); 55 | } -------------------------------------------------------------------------------- /test/fixture/bower_components/modular-scale/stylesheets/modular-scale/_generate-list.scss: -------------------------------------------------------------------------------- 1 | @function ms-reverse-list($list) { 2 | @if length($list) > 1 { 3 | @if nth($list, 1) > nth($list, length($list)) { 4 | $MS-reversed-list: (); 5 | @each $Value in $list { 6 | $MS-reversed-list: join($Value, $MS-reversed-list); 7 | } 8 | @return $MS-reversed-list; 9 | } 10 | } 11 | @return $list; 12 | } 13 | 14 | 15 | @function ms-generate-list($Value: 0, $Bases: $ms-base, $Ratios: $ms-ratio) { 16 | 17 | // Create blank lists 18 | $MS-list: (); 19 | $MS-base-list: (); 20 | 21 | // Loop through each ratio AND each base 22 | // to generate all possibilities. 23 | @each $Ratio in $Ratios { 24 | @each $Base in $Bases { 25 | 26 | // Set base variables 27 | $MS-base-list: (); 28 | $Base-counter: 0; 29 | 30 | // Seed list with an initial value 31 | $MS-base-list: $Base; 32 | 33 | // Find values on a positive scale 34 | @if $Value >= 0 { 35 | 36 | // Find lower values on the scale 37 | $Base-counter: -1; 38 | @while ms-calc($Base-counter, $Base, $Ratio) >= nth($Bases, 1) { 39 | $MS-base-list: join($MS-base-list, ms-calc($Base-counter, $Base, $Ratio)); 40 | $Base-counter: $Base-counter - 1; 41 | } 42 | 43 | // Ensure the list is smallest to largest 44 | $MS-base-list: ms-reverse-list($MS-base-list); 45 | 46 | // Find higher possible values on the scale 47 | $Base-counter: 1; 48 | @while ms-calc($Base-counter, $Base, $Ratio) <= ms-calc($Value, nth($Bases, 1), $Ratio) { 49 | $MS-base-list: join($MS-base-list, ms-calc($Base-counter, $Base, $Ratio)); 50 | $Base-counter: $Base-counter + 1; 51 | } 52 | } 53 | 54 | // Find values on a negitive scale 55 | @else { 56 | 57 | // Find lower values on the scale 58 | $Base-counter: 1; 59 | @while ms-calc($Base-counter, $Base, $Ratio) <= nth($Bases, 1) { 60 | $MS-base-list: join($MS-base-list, ms-calc($Base-counter, $Base, $Ratio)); 61 | $Base-counter: $Base-counter + 1; 62 | } 63 | 64 | // Ensure the list is smallest to largest 65 | $MS-base-list: ms-reverse-list($MS-base-list); 66 | 67 | // Find higher possible values on the scale 68 | $Base-counter: -1; 69 | @while ms-calc($Base-counter, $Base, $Ratio) >= ms-calc($Value, nth($Bases, 1), $Ratio) { 70 | $MS-calc: ms-calc($Base-counter, $Base, $Ratio); 71 | // detect if the value excedes the main base value 72 | @if $MS-calc < nth($Bases, 1) { 73 | $MS-base-list: join($MS-base-list, $MS-calc); 74 | } 75 | $Base-counter: $Base-counter - 1; 76 | } 77 | 78 | // Trim outlier base. 79 | @if length($Bases) > 1 { 80 | @for $i from 2 through length($Bases) { 81 | @if nth($MS-base-list, 1) > nth($Bases, 1) { 82 | $MS-new-list: (); 83 | @for $i from 2 through length($MS-base-list) { 84 | $MS-new-list: join($MS-new-list, nth($MS-base-list, $i)); 85 | } 86 | $MS-base-list: $MS-new-list; 87 | } 88 | } 89 | } 90 | } 91 | 92 | // reverse list if its largest to smallest 93 | $MS-base-list: ms-reverse-list($MS-base-list); 94 | 95 | // Add new possibilities to the master list 96 | $MS-list: append($MS-list, $MS-base-list, comma); 97 | 98 | } 99 | } 100 | 101 | // After all the possibilities are found, output a master list 102 | @return $MS-list; 103 | } -------------------------------------------------------------------------------- /test/fixture/bower_components/modular-scale/stylesheets/modular-scale/_pow.scss: -------------------------------------------------------------------------------- 1 | // If a native exponent function doesnt exist 2 | // this one is needed. 3 | @function ms-pow($Base, $Exponent) { 4 | 5 | // Find and remove unit. 6 | // Avoids messyness with unit calculations 7 | $Unit: $Base * 0 + 1; 8 | $Base: $Base/$Unit; 9 | 10 | // This function doesnt support non-interger exponents. 11 | // Warn the user about why this is breaking. 12 | @if round($Exponent) != $Exponent { 13 | @warn "Unfortunately, you need Compass to use non-integer exponents"; 14 | } 15 | 16 | // Set up the loop, priming the return with the base. 17 | $Return: $Base; 18 | 19 | // If the number is positive, multiply it. 20 | @if $Exponent > 0 { 21 | // Basic feedback loop as exponents 22 | // are recursivley multiplied numbers. 23 | @for $i from 1 to $Exponent { 24 | $Return: $Return * $Base; 25 | } 26 | } 27 | 28 | // If the number is 0 or negitive 29 | // divide instead of multiply. 30 | @else { 31 | // Libsass doesn’t allow negitive values in loops 32 | @for $i from (-1 + 1) to (abs($Exponent) + 1) { 33 | $Return: $Return / $Base; 34 | } 35 | } 36 | 37 | // Return is now compounded redy to be returned. 38 | // Add the unit back onto the number. 39 | @return $Return * $Unit; 40 | } -------------------------------------------------------------------------------- /test/fixture/bower_components/modular-scale/stylesheets/modular-scale/_ratios.scss: -------------------------------------------------------------------------------- 1 | // Golden ratio 2 | $phi : 1.618034 ; 3 | $golden : $phi ; 4 | 5 | $double-octave : 4 ; 6 | $major-twelfth : 3 ; 7 | $major-eleventh : 2.666666667 ; 8 | $major-tenth : 2.5 ; 9 | $octave : 2 ; 10 | $major-seventh : 1.875 ; 11 | $minor-seventh : 1.777777778 ; 12 | $major-sixth : 1.666666667 ; 13 | $minor-sixth : 1.6 ; 14 | $fifth : 1.5 ; 15 | $augmented-fourth : 1.41421 ; 16 | $fourth : 1.333333333 ; 17 | $major-third : 1.25 ; 18 | $minor-third : 1.2 ; 19 | $major-second : 1.125 ; 20 | $minor-second : 1.066666667 ; -------------------------------------------------------------------------------- /test/fixture/bower_components/modular-scale/stylesheets/modular-scale/_sort-list.scss: -------------------------------------------------------------------------------- 1 | // List sorting via a modified merge-sort algorythmn 2 | // http://en.wikipedia.org/wiki/Merge_sort 3 | 4 | @function ms-merge($A, $B) { 5 | 6 | $Return: (); 7 | 8 | // Some empty lists get passed through 9 | // so just pass the other list throguh 10 | @if length($A) == 0 { 11 | @return $B; 12 | } 13 | 14 | // If lists fit next to each other, just merge them 15 | // This helps performance skipping the need to check each value 16 | @if nth($A, length($A)) < nth($B, 1) { 17 | @return join($A, $B); 18 | } 19 | @if nth($B, length($B)) < nth($A, 1) { 20 | @return join($B, $A); 21 | } 22 | 23 | // Counters start at 1 24 | $A-counter: 1; 25 | $B-counter: 1; 26 | 27 | // Start looping through all numbers in array 28 | @while $A-counter <= length($A) and $B-counter <= length($B) { 29 | 30 | // Check if the A value is smaller 31 | // Uses or equal to avoid duplicate numbers 32 | @if nth($A, $A-counter) <= nth($B, $B-counter) { 33 | $Return: join($Return, nth($A, $A-counter)); 34 | $A-counter: $A-counter + 1; 35 | } 36 | 37 | // Check if the B value is smaller 38 | @elseif nth($A, $A-counter) > nth($B, $B-counter) { 39 | $Return: join($Return, nth($B, $B-counter)); 40 | $B-counter: $B-counter + 1; 41 | } 42 | } 43 | 44 | // Run through remainder values in the list 45 | @while $A-counter <= length($A) { 46 | $Current: nth($A, $A-counter); 47 | @if $Current != nth($Return, length($Return)) { 48 | $Return: join($Return, $Current); 49 | } 50 | $A-counter: $A-counter + 1; 51 | } 52 | @while $B-counter <= length($B) { 53 | $Current: nth($B, $B-counter); 54 | @if $Current != nth($Return, length($Return)) { 55 | $Return: join($Return, $Current); 56 | } 57 | $B-counter: $B-counter + 1; 58 | } 59 | 60 | // Done! return is now sorted and complete 61 | @return $Return; 62 | } 63 | 64 | 65 | 66 | // Pull it all together 67 | @function ms-sort-list($Lists) { 68 | 69 | $Return: (); 70 | 71 | @each $List in $Lists { 72 | @if $Return == () { 73 | $Return: $List; 74 | } 75 | @else { 76 | $Return: ms-merge($List, $Return); 77 | } 78 | } 79 | 80 | // final cleanup of repeated items 81 | $Last: null; 82 | $New-list: (); 83 | @each $Item in $Return { 84 | @if $Item != $Last { 85 | $New-list: join($New-list, $Item); 86 | } 87 | $Last: $Item; 88 | } 89 | $Return: $New-list; 90 | 91 | 92 | @return $Return; 93 | } -------------------------------------------------------------------------------- /test/fixture/bower_components/modular-scale/stylesheets/modular-scale/_tests.scss: -------------------------------------------------------------------------------- 1 | // Feature testing 2 | 3 | 4 | // Test if the pow() function exists 5 | @function ms-pow-exists() { 6 | @if pow(4, 2) == 16 { 7 | @return true; 8 | } 9 | @return false; 10 | } 11 | 12 | $MS-pow-exists: ms-pow-exists(); 13 | 14 | // Test if MS was installed via the gem 15 | @function ms-gem-exists() { 16 | @if ms-gem-installed() == true { 17 | @return true; 18 | } 19 | @return false; 20 | } 21 | 22 | $MS-gem-exists: ms-gem-exists(); -------------------------------------------------------------------------------- /test/fixture/bower_components/things/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "things", 3 | "version": "0.1.1", 4 | "main": "things.js", 5 | "ignore": [ 6 | "**/.*", 7 | "spec/", 8 | "src/", 9 | "node_modules", 10 | "Gruntfile.js", 11 | "*.json", 12 | "*.map", 13 | "*.md", 14 | "*.min.js" 15 | ], 16 | "homepage": "https://github.com/stephenplusplus/things", 17 | "_release": "0.1.1", 18 | "_resolution": { 19 | "type": "version", 20 | "tag": "0.1.1", 21 | "commit": "5c58725e141dd60f6714f5c118ae52028b5e3ba0" 22 | }, 23 | "_source": "git://github.com/stephenplusplus/things.git", 24 | "_target": "~0.1.1", 25 | "_originalSource": "things", 26 | "_direct": true 27 | } -------------------------------------------------------------------------------- /test/fixture/bower_components/things/things.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * things. it's so thingy. 3 | * v0.0.1 @stephenplusplus 3/22/13 4 | * github.com/stephenplusplus/things 5 | */ 6 | 7 | /** 8 | * things wrapper. 9 | * 10 | * @param {object} root The global window object. 11 | * @return {undefined} 12 | */ 13 | (function(root) { 14 | 'use strict'; 15 | 16 | var 17 | // Save a copy of toString to abuse. 18 | __toString = ({}).toString, 19 | 20 | /** 21 | * Checks if a given "thing" is of a certain "type". 22 | * 23 | * @param {*} thing The thing you're curious about. 24 | * @param {string} type The type you're matching the thing against. 25 | * @return {boolean} 26 | */ 27 | is = function (thing, type) { 28 | return typeof thing === type; 29 | }, 30 | 31 | /** 32 | * Is this thing defined? 33 | * 34 | * @param {*} thing The thing you're curious about. 35 | * @return {boolean} 36 | */ 37 | isDefined = function(thing) { 38 | return !isUndefined(thing); 39 | }, 40 | 41 | /** 42 | * Is this thing undefined? 43 | * 44 | * @param {*} thing The thing you're curious about. 45 | * @return {boolean} 46 | */ 47 | isUndefined = function(thing) { 48 | return is(thing, 'undefined'); 49 | }, 50 | 51 | /** 52 | * Is this thing a function? 53 | * 54 | * @param {*} thing The thing you're curious about. 55 | * @return {boolean} 56 | */ 57 | isFunction = function(thing) { 58 | return __toString.call(thing) === '[object Function]'; 59 | }, 60 | 61 | /** 62 | * Is this thing a string? 63 | * 64 | * @param {*} thing The thing you're curious about. 65 | * @return {boolean} 66 | */ 67 | isString = function(thing) { 68 | return __toString.call(thing) === '[object String]'; 69 | }, 70 | 71 | /** 72 | * Is this thing an array? 73 | * 74 | * @param {*} thing The thing you're curious about. 75 | * @return {boolean} 76 | */ 77 | isArray = function(thing) { 78 | return __toString.call(thing) === '[object Array]'; 79 | }, 80 | 81 | /** 82 | * Is this thing a number? 83 | * 84 | * @param {*} thing The thing you're curious about. 85 | * @return {boolean} 86 | */ 87 | isNumber = function(thing) { 88 | return __toString.call(thing) === '[object Number]'; 89 | }; 90 | 91 | /** 92 | * Internal jQuery/jQuery-esque API to interact with the DOM. 93 | * 94 | * @return {function} Immediately executed to privatize common functions. 95 | */ 96 | var $$ = (function($) { 97 | var jQueryPresent = isFunction($); 98 | 99 | // Let's save this, so we can loop over matches. 100 | var forEach = Array.prototype.forEach; 101 | 102 | /** 103 | * Private find method, which uses jQuery if available. 104 | * 105 | * @param {HTMLElement|string} context The context to search within. 106 | * @return {function|undefined} The bound find function. 107 | */ 108 | var finder = function(context) { 109 | if (isDefined(context)) 110 | return context.querySelectorAll.bind(context); 111 | }; 112 | 113 | /** 114 | * Returns the jQuery-esque API, used internally and exposed as a default 115 | * dependency. 116 | * 117 | * @param {string} arguments[0] 118 | * @return {object} 119 | */ 120 | return function() { 121 | var api = { 122 | matches: null, 123 | 124 | /** 125 | * Looks within the matched DOM element for another element. 126 | * 127 | * @param {string} element A DOM search parameter. 128 | * @return {object} api The $$ api is returned to allow chaining. 129 | */ 130 | find: function(element) { 131 | var context = finder(api.matches[0]) 132 | , matched; 133 | 134 | if (isFunction(context)) 135 | matched = context(element); 136 | 137 | if (isDefined(matched) && isDefined(matched[0])) 138 | api.matches = matched; 139 | 140 | return api; 141 | }, 142 | 143 | /** 144 | * This function will update or return the innerHTML of an element. 145 | * 146 | * @param {*|undefined} newContent A DOM search parameter. 147 | * @return {string|undefined} 148 | */ 149 | html: function(newContent) { 150 | if (isUndefined(newContent)) 151 | return api.matches[0].innerHTML; 152 | 153 | if (!isFunction(newContent) && !isArray(newContent)) 154 | forEach.call(api.matches, function(match) { 155 | return match.innerHTML = newContent; 156 | }); 157 | } 158 | }; 159 | 160 | if (jQueryPresent) 161 | // We have jQuery, so we will use that, straight up! 162 | return $(arguments[0]); 163 | 164 | // jQuery isn't around, so we'll have to use our fallback. 165 | api.matches = finder(root.document)(arguments[0]); 166 | return api; 167 | } 168 | })(root.jQuery); 169 | 170 | var 171 | // These are the different types of dependencies that can be registered. 172 | dependencyTypes = ['route', 'service', 'thing'], 173 | 174 | // `allOfTheThings` holds the things attached to each module that we pass 175 | // around within the library (routes, services, etc). 176 | allOfTheThings = {}, 177 | 178 | // `alOfTheThingsApis` holds the public API for the modules. 179 | allOfTheThingsApis = {}; 180 | 181 | /** 182 | * When a route is invoked, this resolves what element matches the corresponding 183 | * route. It is stored on the route's object for later usage. 184 | * 185 | * @param {object} module The module that contains the route. 186 | * @param {string} route The name of the route we are working with. 187 | * @return {undefined} 188 | */ 189 | var findRouteElements = function(module, route) { 190 | // We will use our internal `$$` to locate the matching elements. 191 | var dataroute = $$('[data-route="'+ route +'"]') 192 | , datael = dataroute.find('[data-el]'); 193 | 194 | setProperty(module, 'route', route, 'dataroute', dataroute); 195 | 196 | setProperty(module, 'route', route, 'datael', 197 | isDefined(datael[0]) 198 | ? datael 199 | : dataroute); 200 | }; 201 | 202 | /** 203 | * When a route is invoked, return the matching element. 204 | * 205 | * @param {object} module The module that contains the route. 206 | * @param {string} route The route we are going to look for the element on. 207 | * @return {$$} 208 | */ 209 | var getElForRoute = function(module, route) { 210 | findRouteElements(module, route); 211 | 212 | return getProperty(module, 'route', route, 'datael'); 213 | }; 214 | 215 | /** 216 | * When we "goTo" a route, we retrieve and execute (if necessary) the 217 | * dependencies of the route, as well as the dependencies of its dependencies, 218 | * and so on and so forth. 219 | * 220 | * @param {object} module The module containing the dependencies. 221 | * @param {string} route The name of the route we are about to `goTo`. 222 | * @return {undefined} 223 | */ 224 | var invokeRoute = function(module, route) { 225 | // We are firing up a route, so let's store its name on our module. 226 | setModuleProperty(module, 'incomingRoute', route); 227 | 228 | // We begin the search for dependencies! 229 | setModuleProperty(module, 'requestingType', 'route'); 230 | invokeDependency(module, route, 'route'); 231 | 232 | // If we've made it here, we have switched from a previous route successfully. 233 | // We will update the `activeRoute` property on the module. 234 | setModuleProperty(module, 'activeRoute', route); 235 | }; 236 | 237 | /** 238 | * The function behind all public APIs that allows dependency registration. 239 | * 240 | * @param {object} module The module the dependency will be registered on. 241 | * @param {string} type The type of dependency being registered. 242 | * @param {string} name The name of the dependency. 243 | * @param {*} value The value of the dependency. 244 | * @return {undefined} 245 | */ 246 | var registerDependency = function(module, type, name, value) { 247 | if (type === 'service' 248 | && !isFunction(value) 249 | && isUndefined(getProperty(module, 'service', name, 'invoked'))) 250 | // If the dependency is a service that has not yet been invoked, we're more 251 | // picky about what the service type can be. 252 | throw new Error('Services must be functions!'); 253 | 254 | var dependency = module[type][name] = value; 255 | 256 | // Create a hidden store for internal data related to this dependency. 257 | module[type]['__' + name] = {}; 258 | 259 | // If the dependency is a function, we strip out the dependencies listed in 260 | // it's signature. 261 | if (isFunction(value)) { 262 | var dependencies = value.toString().match(/^\s*function\s*\((.*?)\)/); 263 | 264 | setProperty(module, type, name, 'dependencies', 265 | dependencies && dependencies[1] !== '' 266 | ? dependencies[1].replace(/\s/g, '').split(',') 267 | : []); 268 | } 269 | 270 | if (type === 'service' && isUndefined(getProperty(module, 'service', name, 'invoked'))) 271 | // If the dependency is a service, we will specifiy that it has not yet 272 | // been invoked. 273 | setProperty(module, type, name, 'invoked', false); 274 | }; 275 | 276 | /** 277 | * When we need a dependency, we start by passing in the module to search in, 278 | * and then as much information as we have. If all we know is the name, this 279 | * searches through the various types of dependencies, until a match is found. 280 | * We can also specify the name AND type of what we want, in which case it is 281 | * handed right to us. 282 | * 283 | * @param {object} module The module from where we're searching for 284 | * the dependency. 285 | * @param {string} name The name of the dependency we need. 286 | * @param {string|undefined} type The type of dependency we want. 287 | * @return {object} returnDependency The dependency and type matched. 288 | */ 289 | var requestDependency = function(module, name, type) { 290 | var returnDependency = { 291 | dependencyType: undefined, 292 | dependency: undefined 293 | }; 294 | 295 | if (isUndefined(name) && isUndefined(type)) 296 | // Nothing provided to us! Abort! 297 | return returnDependency; 298 | 299 | if (isDefined(name) && isDefined(type)) 300 | // We know exactly what we want. 301 | returnDependency.dependencyType = type, 302 | returnDependency.dependency = module[type][name]; 303 | 304 | else 305 | // Let's go digging for it. 306 | returnDependency.dependency = dependencyTypes.filter(function(depType) { 307 | if (isDefined(module[depType][name])) { 308 | returnDependency.dependencyType = depType; 309 | return module[depType][name]; 310 | } 311 | })[0]; 312 | 313 | if (!returnDependency.dependency || !returnDependency.dependencyType) 314 | throw new Error(name + ' doesn\'t appear to be a thing.'); 315 | 316 | return returnDependency; 317 | }; 318 | 319 | /** 320 | * Let's invoke a dependency! 321 | * 322 | * @param {object} module The module containing the dependencies. 323 | * @param {string} name The dependency we are trying to receive. 324 | * @param {string} type The type of dependency we want. 325 | * @return {*} value The value of the dependency can be anything! 326 | */ 327 | var invokeDependency = function(module, name, type) { 328 | if (isUndefined(name) || isUndefined(type)) 329 | return undefined; 330 | 331 | var 332 | // Wire up our invokingFilter, used throughout the life of this function. 333 | filter = getModuleProperty(module, 'invokingFilter')(name, type), 334 | 335 | // Sniff out any dependencies this dependency may have. 336 | dependencies = getProperty(module, type, name, 'dependencies'); 337 | 338 | // Using our `invokingFilter`, we get our initial value of the dependency. 339 | var value = filter.preInstantiation(); 340 | 341 | if (isArray(dependencies)) 342 | // Update the `requestingType` to store the dependency asking for the next 343 | // dependencies. 344 | setModuleProperty(module, 'requestingType', type); 345 | 346 | if (isFunction(value) && !getProperty(module, type, name, 'invoked')) 347 | // If the value is a function, but not a service that's been invoked, this 348 | // will take the first 10 dependencies listed and pass them into a `new`'d 349 | // value(). 350 | value = new value( 351 | invokeDependency(module, dependencies[0], requestDependency(module, dependencies[0]).dependencyType), 352 | invokeDependency(module, dependencies[1], requestDependency(module, dependencies[1]).dependencyType), 353 | invokeDependency(module, dependencies[2], requestDependency(module, dependencies[2]).dependencyType), 354 | invokeDependency(module, dependencies[3], requestDependency(module, dependencies[3]).dependencyType), 355 | invokeDependency(module, dependencies[4], requestDependency(module, dependencies[4]).dependencyType), 356 | invokeDependency(module, dependencies[5], requestDependency(module, dependencies[5]).dependencyType), 357 | invokeDependency(module, dependencies[6], requestDependency(module, dependencies[6]).dependencyType), 358 | invokeDependency(module, dependencies[7], requestDependency(module, dependencies[7]).dependencyType), 359 | invokeDependency(module, dependencies[8], requestDependency(module, dependencies[8]).dependencyType), 360 | invokeDependency(module, dependencies[9], requestDependency(module, dependencies[9]).dependencyType) 361 | ); 362 | 363 | // The value of the dependency might stay the same as it is currently in the 364 | // invokation, or it might need some additional processing. We'll run it 365 | // through the filter one last time to determine its final value, then return 366 | // that value. 367 | return filter.postInstantiation(value); 368 | }; 369 | 370 | /** 371 | * When we're in the process of launching a new route, we'll need to manage a 372 | * lot of dependencies. Some have conditions which must be met before being 373 | * invoked. Others need to keep track of their "active" or "invoked" state and 374 | * subsequently re-registered. 375 | * 376 | * @param {object} module The module where our route's dependencies will be 377 | * matched. 378 | * @param {string} route The name of the route we are going to launch. 379 | * @return {undefined} 380 | */ 381 | var prepareInvokingFilter = function(module) { 382 | // `preInstantiation` functions are passed the name and current value of the 383 | // dependency being requested. All functions must return a value that will 384 | // represent the dependency for the duration of the invokation. 385 | var preInstantiation = { 386 | /** 387 | * Boot functions typically don't requre filtering. However, should we need 388 | * to, we have the option. 389 | * 390 | * @this {object} The name and value of the route being requested. 391 | * @return {*} The value of the dependency being requested. 392 | */ 393 | boot: function() { 394 | return this.value; 395 | }, 396 | 397 | /** 398 | * If a route is being requested, we need to be sure it's the route we're 399 | * trying to launch, and not another route listed as a dependency. 400 | * 401 | * @this {object} The name and value of the route being requested. 402 | * @return {*} The value of the dependency being requested. 403 | */ 404 | route: function() { 405 | if (this.name !== getModuleProperty(module, 'incomingRoute')) 406 | // If a route isn't yet active, someone is asking for a route. Bust 'em! 407 | this.value = 'Routes cannot be dependencies, sorry!'; 408 | 409 | return this.value; 410 | }, 411 | 412 | /** 413 | * A service is being requested as a dependency. 414 | * 415 | * @this {object} The name and value of the service being requested. 416 | * @return {*} The value of the dependency being requested. 417 | */ 418 | service: function() { 419 | return this.value; 420 | }, 421 | 422 | /** 423 | * A thing is being requested as a dependency. 424 | * 425 | * @this {object} The name and value of the thing being requested. 426 | * @return {*} The value of the dependency being requested. 427 | */ 428 | thing: function() { 429 | if (this.name === '$el' 430 | && getModuleProperty(module, 'requestingType') === 'route' 431 | && getModuleProperty(module, 'incomingRoute') !== getModuleProperty(module, 'activeRoute')) 432 | this.value = getElForRoute(module, getModuleProperty(module, 'incomingRoute')); 433 | 434 | return this.value; 435 | } 436 | }; 437 | 438 | // `postInstantiation` functions are passed the name and current value of the 439 | // dependency being requested. All functions must return a value that will 440 | // represent the dependency for the duration of the invokation. 441 | var postInstantiation = { 442 | /** 443 | * A boot is being requested as a dependency. 444 | * 445 | * @param {*} value The value of the route being requested. 446 | * @return {*} The value of the dependency being requested. 447 | */ 448 | boot: function(value) { 449 | return value; 450 | }, 451 | 452 | /** 453 | * A route is being requested as a dependency. 454 | * 455 | * @param {*} value The value of the route being requested. 456 | * @return {*} The value of the dependency being requested. 457 | */ 458 | route: function(value) { 459 | return value; 460 | }, 461 | 462 | /** 463 | * A service is being requested as a dependency. 464 | * 465 | * @param {*} value The value of the service being requested. 466 | * @return {*} The value of the dependency being requested. 467 | */ 468 | service: function(value) { 469 | // Update the dependency in the module to store its returned value. 470 | registerDependency(module, 'service', this.name, value); 471 | 472 | // Switch the `invoked` property to true, so that we don't instantiate 473 | // it again later. 474 | setProperty(module, 'service', this.name, 'invoked', true); 475 | 476 | return value; 477 | }, 478 | 479 | /** 480 | * A thing is being requested as a dependency. 481 | * 482 | * @param {*} value The value of the thing being requested. 483 | * @return {*} The value of the dependency being requested. 484 | */ 485 | thing: function(value) { 486 | return value; 487 | } 488 | }; 489 | 490 | /** 491 | * `invokingFilter` is stored on the module, and used during 492 | * `invokeDependency` to lint or process a dependency before instantiation and 493 | * after. 494 | * 495 | * @param {string} name The name of the dependency being requested. 496 | * @param {string} type The type of dependency being requested. 497 | * @return {object} The pre and postInstantiation methods to process 498 | * the dependency injection before and after 499 | * instantiation. 500 | */ 501 | setModuleProperty(module, 'invokingFilter', function(name, type) { 502 | var data = { 503 | name: name, 504 | value: requestDependency(module, name, type).dependency 505 | }; 506 | 507 | return { 508 | preInstantiation: preInstantiation[type].bind(data), 509 | postInstantiation: postInstantiation[type].bind(data) 510 | }; 511 | }); 512 | }; 513 | 514 | var 515 | 516 | /** 517 | * Sets a property on the internal, hidden data store for the matching thing. 518 | * 519 | * @param {object} module 520 | * @param {string} type 521 | * @param {string} thing 522 | * @param {string} name 523 | * @param {*} value 524 | * @return {undefined} 525 | */ 526 | setProperty = function(module, type, thing, name, value) { 527 | if (type === 'module') 528 | module['__' + name] = value; 529 | else 530 | module[type]['__' + thing][name] = value; 531 | }, 532 | 533 | /** 534 | * Returns a property on the internal, hidden data store for the matching thing. 535 | * 536 | * @param {object} module 537 | * @param {string} type 538 | * @param {string} thing 539 | * @param {string} name 540 | * @return {*} 541 | */ 542 | getProperty = function(module, type, thing, name) { 543 | if (type === 'module') 544 | return module['__' + name]; 545 | else 546 | return module[type]['__' + thing][name]; 547 | }, 548 | 549 | /** 550 | * Sets a property on a module. 551 | * 552 | * @param {object} module 553 | * @param {string} name 554 | * @param {*} value 555 | * @return {undefined} 556 | */ 557 | setModuleProperty = function(module, name, value) { 558 | setProperty(module, 'module', null, name, value); 559 | }, 560 | 561 | /** 562 | * Returns a property from a module. 563 | * 564 | * @param {object} module 565 | * @param {string} name 566 | * @return {*} 567 | */ 568 | getModuleProperty = function(module, name) { 569 | return getProperty(module, 'module', null, name); 570 | }; 571 | 572 | /** 573 | * We will add things to the global object. 574 | * 575 | * @return {function} 576 | */ 577 | root.things = (function() { 578 | /** 579 | * The public API to create a new thing module and register other things. 580 | * 581 | * @param {string} moduleName The name of the thing module being requested. 582 | * @return {object} The api to interact with the thing module. 583 | */ 584 | var things = function(moduleName) { 585 | if (!isString(moduleName) && !isNumber(moduleName)) 586 | throw new Error('Hey! Give your things a name!'); 587 | 588 | // `thingApi` is what will be returned to the user when a thing module is 589 | // created / asked for. 590 | var thingApi = allOfTheThingsApis[moduleName]; 591 | 592 | // If `thingApi` is defined, that means the user has already registered 593 | // a module by this name, so we will return that module to them. This is 594 | // what allows for no variables to be created. Modules can come from 595 | // `things` directly, exposing all necessary APIs. 596 | if (isDefined(thingApi)) 597 | return thingApi; 598 | 599 | // If this is a new module, we'll register it with the private object, 600 | // `allOfTheThings`. It's also referenced as `module` locally, as we will 601 | // be passing this module directly to all dependency register and 602 | // invocation functions. 603 | var module = allOfTheThings[moduleName] = { 604 | route: {}, 605 | service: {}, 606 | thing: {}, 607 | boot: {} 608 | }; 609 | 610 | // Prepare the invoking filter to be stored on the module. 611 | prepareInvokingFilter(module); 612 | 613 | // The default `root` dependency, which is just a refence to `window`. 614 | registerDependency(module, 'thing', 'root', window); 615 | 616 | // Another default `goTo` function, which just returns the `goTo` 617 | // function defined above. 618 | registerDependency(module, 'service', 'goTo', function() { 619 | return goTo; 620 | }); 621 | 622 | // The default `$` dependency, the jQuery-esque API for the DOM. 623 | registerDependency(module, 'service', '$', function() { 624 | return $$; 625 | }); 626 | 627 | // For routes, we provide a special `$el` to reference the route's element. 628 | registerDependency(module, 'thing', '$el', $$); 629 | 630 | /** 631 | * Returns a function bound to the correct dependency type. 632 | * 633 | * @param {string} type What kind of dependency are we going to eventually 634 | * register? 635 | * @return {function} The returned function will call registerDependency. 636 | */ 637 | var createDependency = function(type) { 638 | /** 639 | * The function that is returned which will call registerDependency. 640 | * 641 | * @param {string} name The name of the thing being registered. 642 | * @param {*} value What is the value of this thing? 643 | * @return {undefined} 644 | */ 645 | return function(name, value) { 646 | registerDependency(module, type, name, value); 647 | 648 | return allOfTheThingsApis[moduleName]; 649 | } 650 | }; 651 | 652 | /** 653 | * What is used to "go to" a route. 654 | * 655 | * @param {string} route Name of the route we're invoking. 656 | * @return {object} module The object used for interacting with the module. 657 | */ 658 | var goTo = function(route) { 659 | invokeRoute(module, route); 660 | 661 | return allOfTheThingsApis[moduleName]; 662 | }; 663 | 664 | /** 665 | * Registers functions that intend to be invoked after the DOM is ready. 666 | * 667 | * @param {function} value The function that will execute. 668 | * @return {object|undefined} module The object used for interacting with the 669 | * module. 670 | */ 671 | var boots = function(value) { 672 | if (!isFunction(value)) 673 | return; 674 | 675 | // Create a random name for this boot function. 676 | var bootName = value.toString().substr(10, 30).replace(/[^\w]|\s/g, ''); 677 | 678 | registerDependency(module, 'boot', bootName, value); 679 | 680 | if (isDOMLoaded) 681 | // If the DOM has already loaded, we'll invoke this immediately. 682 | invokeDependency(module, bootName, 'boot'); 683 | 684 | return allOfTheThingsApis[moduleName]; 685 | }; 686 | 687 | /** 688 | * When the DOM has loaded, we can call our `module.boots()` functions 689 | * one-by-one. 690 | * 691 | * @return {undefined} 692 | */ 693 | var isDOMLoaded = document.readyState === 'complete'; 694 | root.onload = function() { 695 | isDOMLoaded = true; 696 | 697 | for (var bootName in module.boot) 698 | if (module.boot.hasOwnProperty(bootName) && bootName.charAt(0) !== '_') 699 | invokeDependency(module, bootName, 'boot'); 700 | }; 701 | 702 | // We return the public API for registering things, as well as store a 703 | // reference to it in `allOfTheThingsApis`. 704 | return allOfTheThingsApis[moduleName] = { 705 | route: createDependency('route'), 706 | service: createDependency('service'), 707 | thing: createDependency('thing'), 708 | goTo: goTo, 709 | boots: boots 710 | }; 711 | }; 712 | 713 | return things; 714 | })(); 715 | 716 | })(window); -------------------------------------------------------------------------------- /test/fixture/bower_packages_without_dependencies.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "fake-package-without-dependencies": "1.0.0" 6 | }, 7 | "overrides": { 8 | "fake-package-without-dependencies": { 9 | "dependencies": { 10 | "codecode": "0.0.3" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/fixture/bower_packages_without_main.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "fake-package-without-main": "1.0.0", 6 | "fake-package-without-main-and-confusing-file-tree": "1.0.0", 7 | "fake-package-with-override": "1.0.0" 8 | }, 9 | "overrides": { 10 | "fake-package-with-override": { 11 | "main": [ 12 | "dist/fake-package-with-override.js", 13 | "dist/fake-package-with-override.css" 14 | ] 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/fixture/bower_with_main.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test", 3 | "version": "0.0.0", 4 | "main": [ 5 | "sample-main.js", 6 | "sample-main.css" 7 | ], 8 | "dependencies": { 9 | "codecode": "0.0.3", 10 | "bootstrap": "3.0.0", 11 | "modular-scale": "2.0.3", 12 | "3l": "1.4.4" 13 | }, 14 | "devDependencies": { 15 | "things": "0.1.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/fixture/bower_with_main_glob.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test", 3 | "version": "0.0.0", 4 | "main": ["sample-*"], 5 | "dependencies": { 6 | "codecode": "0.0.3", 7 | "bootstrap": "3.0.0", 8 | "modular-scale": "2.0.3", 9 | "3l": "1.4.4" 10 | }, 11 | "devDependencies": { 12 | "things": "0.1.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/fixture/bower_with_missing_component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "missing-component": "1.0.0" 6 | } 7 | } -------------------------------------------------------------------------------- /test/fixture/bowerrc/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "custom" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixture/bowerrc/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test", 3 | "version": "0.0.0" 4 | } 5 | -------------------------------------------------------------------------------- /test/fixture/bowerrc/custom/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taptapship/wiredep/0c247f93656147789c6aba5d8fb8decd45ea449c/test/fixture/bowerrc/custom/.gitkeep -------------------------------------------------------------------------------- /test/fixture/cwd_includeself/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test", 3 | "version": "0.0.0", 4 | "main": [ 5 | "sample-main.js", 6 | "sample-main.css" 7 | ], 8 | "dependencies": { 9 | "bootstrap": "3.0.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/fixture/cwd_includeself/bower_components/bootstrap/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap", 3 | "version": "3.0.0", 4 | "main": ["./dist/js/bootstrap.js", "./dist/css/bootstrap.css"], 5 | "ignore": [ 6 | "**/.*" 7 | ], 8 | "dependencies": { 9 | "jquery": ">= 1.9.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/fixture/cwd_includeself/bower_components/bootstrap/dist/css/bootstrap.css: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is only for testing purposes. 3 | **/ 4 | -------------------------------------------------------------------------------- /test/fixture/cwd_includeself/bower_components/bootstrap/dist/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is only for testing purposes. 3 | **/ 4 | -------------------------------------------------------------------------------- /test/fixture/cwd_includeself/bower_components/jquery/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "version": "2.0.3", 4 | "description": "jQuery component", 5 | "keywords": [ 6 | "jquery", 7 | "component" 8 | ], 9 | "main": "jquery.js", 10 | "license": "MIT" 11 | } 12 | -------------------------------------------------------------------------------- /test/fixture/cwd_includeself/bower_components/jquery/jquery.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is only for testing purposes. 3 | **/ 4 | -------------------------------------------------------------------------------- /test/fixture/cwd_includeself/sample-main.css: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is only for testing purposes. 3 | **/ 4 | -------------------------------------------------------------------------------- /test/fixture/cwd_includeself/sample-main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is only for testing purposes. 3 | **/ 4 | -------------------------------------------------------------------------------- /test/fixture/glob_main/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "custom" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixture/glob_main/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "glob": "1.0.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixture/glob_main/custom/glob/app/app.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taptapship/wiredep/0c247f93656147789c6aba5d8fb8decd45ea449c/test/fixture/glob_main/custom/glob/app/app.js -------------------------------------------------------------------------------- /test/fixture/glob_main/custom/glob/app/service/service.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taptapship/wiredep/0c247f93656147789c6aba5d8fb8decd45ea449c/test/fixture/glob_main/custom/glob/app/service/service.js -------------------------------------------------------------------------------- /test/fixture/glob_main/custom/glob/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fake-package-with-glob-main", 3 | "version": "1.0.0", 4 | "main": [ 5 | "app/*.js", 6 | "app/**/*.js" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /test/fixture/haml/index-actual.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | -# endbower 8 | %body 9 | -# bower:js 10 | -# endbower 11 | -------------------------------------------------------------------------------- /test/fixture/haml/index-after-uninstall-actual.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | -# endbower 8 | %body 9 | -# bower:js 10 | -# endbower 11 | -------------------------------------------------------------------------------- /test/fixture/haml/index-after-uninstall-all-actual.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | %link{rel:'stylesheet', href:'../bower_components/bootstrap/dist/css/bootstrap.css'} 8 | -# endbower 9 | %body 10 | -# bower:js 11 | %script{src:'../bower_components/jquery/jquery.js'} 12 | %script{src:'../bower_components/bootstrap/dist/js/bootstrap.js'} 13 | -# endbower 14 | -------------------------------------------------------------------------------- /test/fixture/haml/index-after-uninstall-all-expected.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | -# endbower 8 | %body 9 | -# bower:js 10 | -# endbower 11 | -------------------------------------------------------------------------------- /test/fixture/haml/index-after-uninstall-expected.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | %link{rel:'stylesheet', href:'../bower_components/bootstrap/dist/css/bootstrap.css'} 8 | -# endbower 9 | %body 10 | -# bower:js 11 | %script{src:'../bower_components/jquery/jquery.js'} 12 | %script{src:'../bower_components/bootstrap/dist/js/bootstrap.js'} 13 | -# endbower 14 | -------------------------------------------------------------------------------- /test/fixture/haml/index-custom-format-actual.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | -# endbower 8 | %body 9 | -# bower:js 10 | -# endbower 11 | -------------------------------------------------------------------------------- /test/fixture/haml/index-custom-format-expected.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | %link{href:'../bower_components/codecode/dist/codecode.css', rel:'stylesheet'} 8 | %link{href:'../bower_components/bootstrap/dist/css/bootstrap.css', rel:'stylesheet'} 9 | -# endbower 10 | %body 11 | -# bower:js 12 | %script{type:'text/javascript', src:'../bower_components/jquery/jquery.js'} 13 | %script{type:'text/javascript', src:'../bower_components/codecode/dist/codecode.js'} 14 | %script{type:'text/javascript', src:'../bower_components/bootstrap/dist/js/bootstrap.js'} 15 | -# endbower 16 | -------------------------------------------------------------------------------- /test/fixture/haml/index-excluded-files-actual.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | -# endbower 8 | %body 9 | -# bower:js 10 | -# endbower 11 | -------------------------------------------------------------------------------- /test/fixture/haml/index-excluded-files-expected.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | %link{rel:'stylesheet', href:'../bower_components/bootstrap/dist/css/bootstrap.css'} 8 | -# endbower 9 | %body 10 | -# bower:js 11 | %script{src:'../bower_components/jquery/jquery.js'} 12 | -# endbower 13 | -------------------------------------------------------------------------------- /test/fixture/haml/index-expected.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | %link{rel:'stylesheet', href:'../bower_components/codecode/dist/codecode.css'} 8 | %link{rel:'stylesheet', href:'../bower_components/bootstrap/dist/css/bootstrap.css'} 9 | -# endbower 10 | %body 11 | -# bower:js 12 | %script{src:'../bower_components/jquery/jquery.js'} 13 | %script{src:'../bower_components/codecode/dist/codecode.js'} 14 | %script{src:'../bower_components/bootstrap/dist/js/bootstrap.js'} 15 | -# endbower 16 | -------------------------------------------------------------------------------- /test/fixture/haml/index-second-run-actual.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | %link{rel:'stylesheet', href:'../bower_components/codecode/dist/codecode.css'} 8 | %link{rel:'stylesheet', href:'../bower_components/bootstrap/dist/css/bootstrap.css'} 9 | -# endbower 10 | %body 11 | -# bower:js 12 | %script{src:'../bower_components/jquery/jquery.js'} 13 | %script{src:'../bower_components/codecode/dist/codecode.js'} 14 | %script{src:'../bower_components/bootstrap/dist/js/bootstrap.js'} 15 | -# endbower 16 | -------------------------------------------------------------------------------- /test/fixture/haml/index-second-run-expected.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html{lang:'en'} 3 | %head 4 | %meta{charset:'utf-8'} 5 | %title test. 6 | -# bower:css 7 | %link{rel:'stylesheet', href:'../bower_components/codecode/dist/codecode.css'} 8 | %link{rel:'stylesheet', href:'../bower_components/bootstrap/dist/css/bootstrap.css'} 9 | -# endbower 10 | %body 11 | -# bower:js 12 | %script{src:'../bower_components/jquery/jquery.js'} 13 | %script{src:'../bower_components/codecode/dist/codecode.js'} 14 | %script{src:'../bower_components/bootstrap/dist/js/bootstrap.js'} 15 | -# endbower 16 | -------------------------------------------------------------------------------- /test/fixture/html/deep/nested/index-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/deep/nested/index-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixture/html/index-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-after-uninstall-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-after-uninstall-all-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-after-uninstall-all-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-after-uninstall-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/fixture/html/index-custom-format-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-custom-format-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixture/html/index-cwd-include-self-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-cwd-include-self-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixture/html/index-detect-quotation-marks-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test/fixture/html/index-detect-quotation-marks-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /test/fixture/html/index-emitter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/fixture/html/index-excluded-files-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-excluded-files-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test/fixture/html/index-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixture/html/index-include-glob-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-include-glob-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test/fixture/html/index-include-self-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-include-self-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /test/fixture/html/index-include-self-glob-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-include-self-glob-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /test/fixture/html/index-override-dependencies-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test/fixture/html/index-override-dependencies-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test/fixture/html/index-packages-without-main-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-packages-without-main-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/fixture/html/index-second-run-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixture/html/index-second-run-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixture/html/index-with-custom-bower-directory-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-with-custom-bower-directory-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-with-custom-replace-function-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-with-custom-replace-function-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixture/html/index-with-dev-dependencies-actual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/html/index-with-dev-dependencies-expected.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test/fixture/invalid.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wiredep-test" 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "codecode": "0.0.3", 6 | "bootstrap": "3.0.0", 7 | "modular-scale": "2.0.3", 8 | "3l": "1.4.4", 9 | "karma": "0.2.1" 10 | }, 11 | "devDependencies": { 12 | "things": "0.1.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/fixture/jade/index-actual.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | // endbower 8 | body 9 | // bower:js 10 | // endbower 11 | -------------------------------------------------------------------------------- /test/fixture/jade/index-after-uninstall-actual.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | // endbower 8 | body 9 | // bower:js 10 | // endbower 11 | -------------------------------------------------------------------------------- /test/fixture/jade/index-after-uninstall-all-actual.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 8 | // endbower 9 | body 10 | // bower:js 11 | script(src='../bower_components/jquery/jquery.js') 12 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 13 | // endbower 14 | -------------------------------------------------------------------------------- /test/fixture/jade/index-after-uninstall-all-expected.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | // endbower 8 | body 9 | // bower:js 10 | // endbower 11 | -------------------------------------------------------------------------------- /test/fixture/jade/index-after-uninstall-expected.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 8 | // endbower 9 | body 10 | // bower:js 11 | script(src='../bower_components/jquery/jquery.js') 12 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 13 | // endbower 14 | -------------------------------------------------------------------------------- /test/fixture/jade/index-custom-format-actual.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | // endbower 8 | body 9 | // bower:js 10 | // endbower 11 | -------------------------------------------------------------------------------- /test/fixture/jade/index-custom-format-expected.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(href='../bower_components/codecode/dist/codecode.css', rel='stylesheet') 8 | link(href='../bower_components/bootstrap/dist/css/bootstrap.css', rel='stylesheet') 9 | // endbower 10 | body 11 | // bower:js 12 | script(type='text/javascript', src='../bower_components/jquery/jquery.js') 13 | script(type='text/javascript', src='../bower_components/codecode/dist/codecode.js') 14 | script(type='text/javascript', src='../bower_components/bootstrap/dist/js/bootstrap.js') 15 | // endbower 16 | -------------------------------------------------------------------------------- /test/fixture/jade/index-excluded-files-actual.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | // endbower 8 | body 9 | // bower:js 10 | // endbower 11 | -------------------------------------------------------------------------------- /test/fixture/jade/index-excluded-files-expected.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 8 | // endbower 9 | body 10 | // bower:js 11 | script(src='../bower_components/jquery/jquery.js') 12 | // endbower 13 | -------------------------------------------------------------------------------- /test/fixture/jade/index-expected.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/codecode/dist/codecode.css') 8 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 9 | // endbower 10 | body 11 | // bower:js 12 | script(src='../bower_components/jquery/jquery.js') 13 | script(src='../bower_components/codecode/dist/codecode.js') 14 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 15 | // endbower 16 | -------------------------------------------------------------------------------- /test/fixture/jade/index-second-run-actual.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/codecode/dist/codecode.css') 8 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 9 | // endbower 10 | body 11 | // bower:js 12 | script(src='../bower_components/jquery/jquery.js') 13 | script(src='../bower_components/codecode/dist/codecode.js') 14 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 15 | // endbower 16 | -------------------------------------------------------------------------------- /test/fixture/jade/index-second-run-expected.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/codecode/dist/codecode.css') 8 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 9 | // endbower 10 | body 11 | // bower:js 12 | script(src='../bower_components/jquery/jquery.js') 13 | script(src='../bower_components/codecode/dist/codecode.js') 14 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 15 | // endbower 16 | -------------------------------------------------------------------------------- /test/fixture/jade/index-unbuffered-comments-actual.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | //- bower:css 7 | //- endbower 8 | body 9 | //- bower:js 10 | //- endbower 11 | -------------------------------------------------------------------------------- /test/fixture/jade/index-unbuffered-comments-expected.jade: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | //- bower:css 7 | link(rel='stylesheet', href='../bower_components/codecode/dist/codecode.css') 8 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 9 | //- endbower 10 | body 11 | //- bower:js 12 | script(src='../bower_components/jquery/jquery.js') 13 | script(src='../bower_components/codecode/dist/codecode.js') 14 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 15 | //- endbower 16 | -------------------------------------------------------------------------------- /test/fixture/js/index-actual.js: -------------------------------------------------------------------------------- 1 | // Like you would expect your `karma.conf.js` file to look... 2 | module.exports = function(config){ 3 | config.files = [ 4 | // These are the most important... 5 | // bower:js 6 | // endbower 7 | 8 | // But just in case... 9 | // bower:css 10 | // endbower 11 | "scripts/app/app.js" 12 | ]; // END config.files 13 | 14 | // Mentioning bower inside a comment should have no effect. 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixture/js/index-expected.js: -------------------------------------------------------------------------------- 1 | // Like you would expect your `karma.conf.js` file to look... 2 | module.exports = function(config){ 3 | config.files = [ 4 | // These are the most important... 5 | // bower:js 6 | "../bower_components/jquery/jquery.js", 7 | "../bower_components/codecode/dist/codecode.js", 8 | "../bower_components/bootstrap/dist/js/bootstrap.js", 9 | // endbower 10 | 11 | // But just in case... 12 | // bower:css 13 | "../bower_components/codecode/dist/codecode.css", 14 | "../bower_components/bootstrap/dist/css/bootstrap.css", 15 | // endbower 16 | "scripts/app/app.js" 17 | ]; // END config.files 18 | 19 | // Mentioning bower inside a comment should have no effect. 20 | }; 21 | -------------------------------------------------------------------------------- /test/fixture/less/index-actual.less: -------------------------------------------------------------------------------- 1 | @import "../bower_components/bootstrap/dist/css/bootstrap.css"; 2 | 3 | // bower:css 4 | // endbower 5 | 6 | // bower:less 7 | // endbower 8 | -------------------------------------------------------------------------------- /test/fixture/less/index-expected.less: -------------------------------------------------------------------------------- 1 | @import "../bower_components/bootstrap/dist/css/bootstrap.css"; 2 | 3 | // bower:css 4 | @import "../bower_components/codecode/dist/codecode.css"; 5 | // endbower 6 | 7 | // bower:less 8 | @import "../bower_components/3l/3L/3L.less"; 9 | // endbower 10 | -------------------------------------------------------------------------------- /test/fixture/less/index-second-run-actual.less: -------------------------------------------------------------------------------- 1 | // bower:css 2 | @import "../bower_components/codecode/dist/codecode.css"; 3 | @import "../bower_components/bootstrap/dist/css/bootstrap.css"; 4 | // endbower 5 | 6 | // bower:less 7 | @import "../bower_components/3l/3L/3L.less"; 8 | // endbower 9 | -------------------------------------------------------------------------------- /test/fixture/less/index-second-run-expected.less: -------------------------------------------------------------------------------- 1 | // bower:css 2 | @import "../bower_components/codecode/dist/codecode.css"; 3 | @import "../bower_components/bootstrap/dist/css/bootstrap.css"; 4 | // endbower 5 | 6 | // bower:less 7 | @import "../bower_components/3l/3L/3L.less"; 8 | // endbower 9 | -------------------------------------------------------------------------------- /test/fixture/pug/index-actual.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | // endbower 8 | body 9 | // bower:js 10 | // endbower 11 | -------------------------------------------------------------------------------- /test/fixture/pug/index-after-uninstall-actual.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | // endbower 8 | body 9 | // bower:js 10 | // endbower 11 | -------------------------------------------------------------------------------- /test/fixture/pug/index-after-uninstall-all-actual.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 8 | // endbower 9 | body 10 | // bower:js 11 | script(src='../bower_components/jquery/jquery.js') 12 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 13 | // endbower 14 | -------------------------------------------------------------------------------- /test/fixture/pug/index-after-uninstall-all-expected.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | // endbower 8 | body 9 | // bower:js 10 | // endbower 11 | -------------------------------------------------------------------------------- /test/fixture/pug/index-after-uninstall-expected.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 8 | // endbower 9 | body 10 | // bower:js 11 | script(src='../bower_components/jquery/jquery.js') 12 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 13 | // endbower 14 | -------------------------------------------------------------------------------- /test/fixture/pug/index-custom-format-actual.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | // endbower 8 | body 9 | // bower:js 10 | // endbower 11 | -------------------------------------------------------------------------------- /test/fixture/pug/index-custom-format-expected.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(href='../bower_components/codecode/dist/codecode.css', rel='stylesheet') 8 | link(href='../bower_components/bootstrap/dist/css/bootstrap.css', rel='stylesheet') 9 | // endbower 10 | body 11 | // bower:js 12 | script(type='text/javascript', src='../bower_components/jquery/jquery.js') 13 | script(type='text/javascript', src='../bower_components/codecode/dist/codecode.js') 14 | script(type='text/javascript', src='../bower_components/bootstrap/dist/js/bootstrap.js') 15 | // endbower 16 | -------------------------------------------------------------------------------- /test/fixture/pug/index-excluded-files-actual.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | // endbower 8 | body 9 | // bower:js 10 | // endbower 11 | -------------------------------------------------------------------------------- /test/fixture/pug/index-excluded-files-expected.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 8 | // endbower 9 | body 10 | // bower:js 11 | script(src='../bower_components/jquery/jquery.js') 12 | // endbower 13 | -------------------------------------------------------------------------------- /test/fixture/pug/index-expected.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/codecode/dist/codecode.css') 8 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 9 | // endbower 10 | body 11 | // bower:js 12 | script(src='../bower_components/jquery/jquery.js') 13 | script(src='../bower_components/codecode/dist/codecode.js') 14 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 15 | // endbower 16 | -------------------------------------------------------------------------------- /test/fixture/pug/index-second-run-actual.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/codecode/dist/codecode.css') 8 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 9 | // endbower 10 | body 11 | // bower:js 12 | script(src='../bower_components/jquery/jquery.js') 13 | script(src='../bower_components/codecode/dist/codecode.js') 14 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 15 | // endbower 16 | -------------------------------------------------------------------------------- /test/fixture/pug/index-second-run-expected.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | // bower:css 7 | link(rel='stylesheet', href='../bower_components/codecode/dist/codecode.css') 8 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 9 | // endbower 10 | body 11 | // bower:js 12 | script(src='../bower_components/jquery/jquery.js') 13 | script(src='../bower_components/codecode/dist/codecode.js') 14 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 15 | // endbower 16 | -------------------------------------------------------------------------------- /test/fixture/pug/index-unbuffered-comments-actual.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | //- bower:css 7 | //- endbower 8 | body 9 | //- bower:js 10 | //- endbower 11 | -------------------------------------------------------------------------------- /test/fixture/pug/index-unbuffered-comments-expected.pug: -------------------------------------------------------------------------------- 1 | !!! 5 2 | html(lang='en') 3 | head 4 | meta(charset='utf-8') 5 | title test. 6 | //- bower:css 7 | link(rel='stylesheet', href='../bower_components/codecode/dist/codecode.css') 8 | link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.css') 9 | //- endbower 10 | body 11 | //- bower:js 12 | script(src='../bower_components/jquery/jquery.js') 13 | script(src='../bower_components/codecode/dist/codecode.js') 14 | script(src='../bower_components/bootstrap/dist/js/bootstrap.js') 15 | //- endbower 16 | -------------------------------------------------------------------------------- /test/fixture/sample-main.css: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is only for testing purposes. 3 | **/ 4 | -------------------------------------------------------------------------------- /test/fixture/sample-main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is only for testing purposes. 3 | **/ 4 | -------------------------------------------------------------------------------- /test/fixture/sass/index-actual.sass: -------------------------------------------------------------------------------- 1 | // bower:css 2 | // endbower 3 | 4 | // bower:sass 5 | // endbower 6 | 7 | // bower:scss 8 | // endbower 9 | -------------------------------------------------------------------------------- /test/fixture/sass/index-expected.sass: -------------------------------------------------------------------------------- 1 | // bower:css 2 | @import ../bower_components/codecode/dist/codecode.css 3 | @import ../bower_components/bootstrap/dist/css/bootstrap.css 4 | // endbower 5 | 6 | // bower:sass 7 | // endbower 8 | 9 | // bower:scss 10 | @import ../bower_components/modular-scale/stylesheets/_modular-scale.scss 11 | // endbower 12 | -------------------------------------------------------------------------------- /test/fixture/sass/index-second-run-actual.sass: -------------------------------------------------------------------------------- 1 | // bower:css 2 | @import ../bower_components/codecode/dist/codecode.css 3 | @import ../bower_components/bootstrap/dist/css/bootstrap.css 4 | // endbower 5 | 6 | // bower:sass 7 | // endbower 8 | 9 | // bower:scss 10 | @import ../bower_components/modular-scale/stylesheets/_modular-scale.scss 11 | // endbower 12 | -------------------------------------------------------------------------------- /test/fixture/sass/index-second-run-expected.sass: -------------------------------------------------------------------------------- 1 | // bower:css 2 | @import ../bower_components/codecode/dist/codecode.css 3 | @import ../bower_components/bootstrap/dist/css/bootstrap.css 4 | // endbower 5 | 6 | // bower:sass 7 | // endbower 8 | 9 | // bower:scss 10 | @import ../bower_components/modular-scale/stylesheets/_modular-scale.scss 11 | // endbower 12 | -------------------------------------------------------------------------------- /test/fixture/scss/index-actual.scss: -------------------------------------------------------------------------------- 1 | // bower:css 2 | // endbower 3 | 4 | // bower:sass 5 | // endbower 6 | 7 | // bower:scss 8 | // endbower 9 | -------------------------------------------------------------------------------- /test/fixture/scss/index-expected.scss: -------------------------------------------------------------------------------- 1 | // bower:css 2 | @import "../bower_components/codecode/dist/codecode.css"; 3 | @import "../bower_components/bootstrap/dist/css/bootstrap.css"; 4 | // endbower 5 | 6 | // bower:sass 7 | // endbower 8 | 9 | // bower:scss 10 | @import "../bower_components/modular-scale/stylesheets/_modular-scale.scss"; 11 | // endbower 12 | -------------------------------------------------------------------------------- /test/fixture/scss/index-second-run-actual.scss: -------------------------------------------------------------------------------- 1 | // bower:css 2 | @import "../bower_components/codecode/dist/codecode.css"; 3 | @import "../bower_components/bootstrap/dist/css/bootstrap.css"; 4 | // endbower 5 | 6 | // bower:sass 7 | // endbower 8 | 9 | // bower:scss 10 | @import "../bower_components/modular-scale/stylesheets/_modular-scale.scss"; 11 | // endbower 12 | -------------------------------------------------------------------------------- /test/fixture/scss/index-second-run-expected.scss: -------------------------------------------------------------------------------- 1 | // bower:css 2 | @import "../bower_components/codecode/dist/codecode.css"; 3 | @import "../bower_components/bootstrap/dist/css/bootstrap.css"; 4 | // endbower 5 | 6 | // bower:sass 7 | // endbower 8 | 9 | // bower:scss 10 | @import "../bower_components/modular-scale/stylesheets/_modular-scale.scss"; 11 | // endbower 12 | -------------------------------------------------------------------------------- /test/fixture/slim/index-actual.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | /! endbower 7 | body 8 | / bower:js 9 | / endbower 10 | -------------------------------------------------------------------------------- /test/fixture/slim/index-after-uninstall-actual.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | /! endbower 7 | body 8 | / bower:js 9 | / endbower 10 | -------------------------------------------------------------------------------- /test/fixture/slim/index-after-uninstall-all-actual.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | link rel='stylesheet' href='../bower_components/bootstrap/dist/css/bootstrap.css' 7 | /! endbower 8 | body 9 | / bower:js 10 | script src='../bower_components/jquery/jquery.js' 11 | script src='../bower_components/bootstrap/dist/js/bootstrap.js' 12 | / endbower 13 | -------------------------------------------------------------------------------- /test/fixture/slim/index-after-uninstall-all-expected.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | /! endbower 7 | body 8 | / bower:js 9 | / endbower 10 | -------------------------------------------------------------------------------- /test/fixture/slim/index-after-uninstall-expected.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | link rel='stylesheet' href='../bower_components/bootstrap/dist/css/bootstrap.css' 7 | /! endbower 8 | body 9 | / bower:js 10 | script src='../bower_components/jquery/jquery.js' 11 | script src='../bower_components/bootstrap/dist/js/bootstrap.js' 12 | / endbower 13 | -------------------------------------------------------------------------------- /test/fixture/slim/index-custom-format-actual.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | /! endbower 7 | body 8 | /! bower:js 9 | /! endbower 10 | -------------------------------------------------------------------------------- /test/fixture/slim/index-custom-format-expected.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | link href='../bower_components/codecode/dist/codecode.css' rel='stylesheet' 7 | link href='../bower_components/bootstrap/dist/css/bootstrap.css' rel='stylesheet' 8 | /! endbower 9 | body 10 | /! bower:js 11 | script type='text/javascript' src='../bower_components/jquery/jquery.js' 12 | script type='text/javascript' src='../bower_components/codecode/dist/codecode.js' 13 | script type='text/javascript' src='../bower_components/bootstrap/dist/js/bootstrap.js' 14 | /! endbower 15 | -------------------------------------------------------------------------------- /test/fixture/slim/index-excluded-files-actual.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | /! endbower 7 | body 8 | /! bower:js 9 | /! endbower 10 | -------------------------------------------------------------------------------- /test/fixture/slim/index-excluded-files-expected.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | link rel='stylesheet' href='../bower_components/bootstrap/dist/css/bootstrap.css' 7 | /! endbower 8 | body 9 | /! bower:js 10 | script src='../bower_components/jquery/jquery.js' 11 | /! endbower 12 | -------------------------------------------------------------------------------- /test/fixture/slim/index-expected.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | link rel='stylesheet' href='../bower_components/codecode/dist/codecode.css' 7 | link rel='stylesheet' href='../bower_components/bootstrap/dist/css/bootstrap.css' 8 | /! endbower 9 | body 10 | / bower:js 11 | script src='../bower_components/jquery/jquery.js' 12 | script src='../bower_components/codecode/dist/codecode.js' 13 | script src='../bower_components/bootstrap/dist/js/bootstrap.js' 14 | / endbower 15 | -------------------------------------------------------------------------------- /test/fixture/slim/index-second-run-actual.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | link rel='stylesheet' href='../bower_components/codecode/dist/codecode.css' 7 | link rel='stylesheet' href='../bower_components/bootstrap/dist/css/bootstrap.css' 8 | /! endbower 9 | body 10 | /! bower:js 11 | script src='../bower_components/jquery/jquery.js' 12 | script src='../bower_components/codecode/dist/codecode.js' 13 | script src='../bower_components/bootstrap/dist/js/bootstrap.js' 14 | /! endbower 15 | -------------------------------------------------------------------------------- /test/fixture/slim/index-second-run-expected.slim: -------------------------------------------------------------------------------- 1 | doctype html 2 | head 3 | meta charset='utf-8' 4 | title test 5 | /! bower:css 6 | link rel='stylesheet' href='../bower_components/codecode/dist/codecode.css' 7 | link rel='stylesheet' href='../bower_components/bootstrap/dist/css/bootstrap.css' 8 | /! endbower 9 | body 10 | /! bower:js 11 | script src='../bower_components/jquery/jquery.js' 12 | script src='../bower_components/codecode/dist/codecode.js' 13 | script src='../bower_components/bootstrap/dist/js/bootstrap.js' 14 | /! endbower 15 | -------------------------------------------------------------------------------- /test/fixture/styl/index-actual.styl: -------------------------------------------------------------------------------- 1 | @import "../bower_components/bootstrap/dist/css/bootstrap.css" 2 | 3 | // bower:css 4 | // endbower 5 | 6 | // bower:styl 7 | // endbower 8 | -------------------------------------------------------------------------------- /test/fixture/styl/index-expected.styl: -------------------------------------------------------------------------------- 1 | @import "../bower_components/bootstrap/dist/css/bootstrap.css" 2 | 3 | // bower:css 4 | @import "../bower_components/codecode/dist/codecode.css" 5 | // endbower 6 | 7 | // bower:styl 8 | @import "../bower_components/karma/dist/karma.styl" 9 | // endbower 10 | -------------------------------------------------------------------------------- /test/fixture/styl/index-second-run-actual.styl: -------------------------------------------------------------------------------- 1 | // bower:css 2 | @import "../bower_components/codecode/dist/codecode.css" 3 | @import "../bower_components/bootstrap/dist/css/bootstrap.css" 4 | // endbower 5 | 6 | // bower:styl 7 | @import "../bower_components/karma/dist/karma.styl" 8 | // endbower 9 | -------------------------------------------------------------------------------- /test/fixture/styl/index-second-run-expected.styl: -------------------------------------------------------------------------------- 1 | // bower:css 2 | @import "../bower_components/codecode/dist/codecode.css" 3 | @import "../bower_components/bootstrap/dist/css/bootstrap.css" 4 | // endbower 5 | 6 | // bower:styl 7 | @import "../bower_components/karma/dist/karma.styl" 8 | // endbower 9 | -------------------------------------------------------------------------------- /test/fixture/unrecognized/index-actual.unrecognized: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixture/unrecognized/index-expected.unrecognized: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/fixture/yml/index-actual.yml: -------------------------------------------------------------------------------- 1 | src_css_files: 2 | # bower:css 3 | # endbower 4 | 5 | src_js_files: 6 | # bower:js 7 | # endbower 8 | -------------------------------------------------------------------------------- /test/fixture/yml/index-custom-format-actual.yml: -------------------------------------------------------------------------------- 1 | src_css_files: 2 | # bower:css 3 | # endbower 4 | 5 | src_js_files: 6 | # bower:js 7 | # endbower 8 | -------------------------------------------------------------------------------- /test/fixture/yml/index-custom-format-expected.yml: -------------------------------------------------------------------------------- 1 | src_css_files: 2 | # bower:css 3 | - "../bower_components/codecode/dist/codecode.css" #css 4 | - "../bower_components/bootstrap/dist/css/bootstrap.css" #css 5 | # endbower 6 | 7 | src_js_files: 8 | # bower:js 9 | - "../bower_components/jquery/jquery.js" 10 | - "../bower_components/codecode/dist/codecode.js" 11 | - "../bower_components/bootstrap/dist/js/bootstrap.js" 12 | # endbower 13 | -------------------------------------------------------------------------------- /test/fixture/yml/index-excluded-files-actual.yml: -------------------------------------------------------------------------------- 1 | src_css_files: 2 | # bower:css 3 | # endbower 4 | 5 | src_js_files: 6 | # bower:js 7 | # endbower 8 | -------------------------------------------------------------------------------- /test/fixture/yml/index-excluded-files-expected.yml: -------------------------------------------------------------------------------- 1 | src_css_files: 2 | # bower:css 3 | - ../bower_components/bootstrap/dist/css/bootstrap.css 4 | # endbower 5 | 6 | src_js_files: 7 | # bower:js 8 | - ../bower_components/jquery/jquery.js 9 | # endbower 10 | -------------------------------------------------------------------------------- /test/fixture/yml/index-expected.yml: -------------------------------------------------------------------------------- 1 | src_css_files: 2 | # bower:css 3 | - ../bower_components/codecode/dist/codecode.css 4 | - ../bower_components/bootstrap/dist/css/bootstrap.css 5 | # endbower 6 | 7 | src_js_files: 8 | # bower:js 9 | - ../bower_components/jquery/jquery.js 10 | - ../bower_components/codecode/dist/codecode.js 11 | - ../bower_components/bootstrap/dist/js/bootstrap.js 12 | # endbower 13 | -------------------------------------------------------------------------------- /test/fixture/yml/index-second-run-actual.yml: -------------------------------------------------------------------------------- 1 | src_css_files: 2 | # bower:css 3 | - ../bower_components/codecode/dist/codecode.css 4 | - ../bower_components/bootstrap/dist/css/bootstrap.css 5 | # endbower 6 | 7 | src_js_files: 8 | # bower:js 9 | - ../bower_components/jquery/jquery.js 10 | - ../bower_components/codecode/dist/codecode.js 11 | - ../bower_components/bootstrap/dist/js/bootstrap.js 12 | # endbower 13 | -------------------------------------------------------------------------------- /test/fixture/yml/index-second-run-expected.yml: -------------------------------------------------------------------------------- 1 | src_css_files: 2 | # bower:css 3 | - ../bower_components/codecode/dist/codecode.css 4 | - ../bower_components/bootstrap/dist/css/bootstrap.css 5 | # endbower 6 | 7 | src_js_files: 8 | # bower:js 9 | - ../bower_components/jquery/jquery.js 10 | - ../bower_components/codecode/dist/codecode.js 11 | - ../bower_components/bootstrap/dist/js/bootstrap.js 12 | # endbower 13 | -------------------------------------------------------------------------------- /test/wiredep_test.js: -------------------------------------------------------------------------------- 1 | /*jshint latedef:false */ 2 | /*global after, describe, it, before, beforeEach */ 3 | 4 | 'use strict'; 5 | 6 | var fs = require('fs-extra'); 7 | var path = require('path'); 8 | var assert = require('chai').assert; 9 | var wiredep; 10 | 11 | require.uncache = function (moduleName) { 12 | var mod = require.resolve(moduleName); 13 | if (mod && ((mod = require.cache[mod]) !== undefined)) { 14 | (function run(mod) { 15 | mod.children.forEach(function (child) { 16 | run(child); 17 | }); 18 | delete require.cache[mod.id]; 19 | })(mod); 20 | } 21 | 22 | Object.keys(module.constructor._pathCache).forEach(function(cacheKey) { 23 | if (cacheKey.indexOf(moduleName)>0) { 24 | delete module.constructor._pathCache[cacheKey]; 25 | } 26 | }); 27 | }; 28 | 29 | describe('wiredep', function () { 30 | beforeEach(function () { 31 | wiredep = require('../wiredep'); 32 | }) 33 | afterEach(function () { 34 | require.uncache('../wiredep'); 35 | }) 36 | before(function() { 37 | fs.copySync('test/fixture', '.tmp'); 38 | process.chdir('.tmp'); 39 | }); 40 | after(function () { 41 | process.chdir('..'); 42 | fs.removeSync('.tmp'); 43 | }); 44 | 45 | describe('replace functionality', function () { 46 | function testReplace(fileType) { 47 | return function () { 48 | var filePaths = getFilePaths('index', fileType); 49 | 50 | wiredep({ src: [filePaths.actual] }); 51 | 52 | assert.deepEqual( 53 | filePaths.read('expected').split('\n'), 54 | filePaths.read('actual').split('\n') 55 | ); 56 | }; 57 | } 58 | 59 | it('should work with html files', testReplace('html')); 60 | it('should work with jade files (buffered comments)', testReplace('jade')); 61 | 62 | it('should work with jade files (unbuffered comments)', function () { 63 | var filePaths = getFilePaths('index-unbuffered-comments', 'jade'); 64 | 65 | wiredep({ src: [filePaths.actual] }); 66 | 67 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 68 | }); 69 | 70 | it('should work with pug files (buffered comments)', testReplace('pug')); 71 | 72 | it('should work with pug files (unbuffered comments)', function () { 73 | var filePaths = getFilePaths('index-unbuffered-comments', 'pug'); 74 | 75 | wiredep({ src: [filePaths.actual] }); 76 | 77 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 78 | }); 79 | it('should work with sass files', testReplace('sass')); 80 | it('should work with scss files', testReplace('scss')); 81 | it('should work with yml files', testReplace('yml')); 82 | it('should work with slim files', testReplace('slim')); 83 | it('should work with js files', testReplace('js')); 84 | it('should work with haml files', testReplace('haml')); 85 | it('should work with unrecognized file types', testReplace('unrecognized')); 86 | it('should correctly handle relative paths', testReplace('html/deep/nested')); 87 | 88 | it('should detect and use quotation marks', function () { 89 | var filePaths = getFilePaths('index-detect-quotation-marks', 'html'); 90 | 91 | wiredep({ src: [filePaths.actual] }); 92 | 93 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 94 | }); 95 | 96 | it('should support globbing', function () { 97 | wiredep({ src: ['html/index-actual.*', 'jade/index-actual.*', 'slim/index-actual.*', 'haml/index-actual.*'] }); 98 | 99 | [ 100 | { 101 | actual: 'html/index-actual.html', 102 | expected: 'html/index-expected.html' 103 | }, 104 | { 105 | actual: 'jade/index-actual.jade', 106 | expected: 'jade/index-expected.jade' 107 | }, 108 | { 109 | actual: 'slim/index-actual.slim', 110 | expected: 'slim/index-expected.slim' 111 | }, 112 | { 113 | actual: 'haml/index-actual.haml', 114 | expected: 'haml/index-expected.haml' 115 | } 116 | ].forEach(function (testObject) { 117 | assert.equal( 118 | fs.readFileSync(testObject.actual, { encoding: 'utf8' }), 119 | fs.readFileSync(testObject.expected, { encoding: 'utf8' }) 120 | ); 121 | }); 122 | }); 123 | }); 124 | 125 | describe('second run (identical files)', function () { 126 | function testReplaceSecondRun(fileType) { 127 | return function () { 128 | var filePaths = getFilePaths('index-second-run', fileType); 129 | 130 | wiredep({ src: [filePaths.actual] }); 131 | 132 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 133 | }; 134 | } 135 | 136 | it('should replace html after second run', testReplaceSecondRun('html')); 137 | it('should replace jade after second run', testReplaceSecondRun('jade')); 138 | it('should replace less after second run', testReplaceSecondRun('less')); 139 | it('should replace sass after second run', testReplaceSecondRun('sass')); 140 | it('should replace scss after second run', testReplaceSecondRun('scss')); 141 | it('should replace styl after second run', testReplaceSecondRun('styl')); 142 | it('should replace yml after second run', testReplaceSecondRun('yml')); 143 | it('should replace slim after second run', testReplaceSecondRun('slim')); 144 | it('should replace haml after second run', testReplaceSecondRun('haml')); 145 | }); 146 | 147 | describe('excludes', function () { 148 | function testReplaceWithExcludedSrc(fileType) { 149 | return function () { 150 | var filePaths = getFilePaths('index-excluded-files', fileType); 151 | 152 | wiredep({ 153 | src: [filePaths.actual], 154 | exclude: ['bower_components/bootstrap/dist/js/bootstrap.js', /codecode/] 155 | }); 156 | 157 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 158 | }; 159 | } 160 | 161 | it('should handle html with excludes specified', testReplaceWithExcludedSrc('html')); 162 | it('should handle jade with excludes specified', testReplaceWithExcludedSrc('jade')); 163 | it('should handle yml with excludes specified', testReplaceWithExcludedSrc('yml')); 164 | it('should handle slim with excludes specified', testReplaceWithExcludedSrc('slim')); 165 | it('should handle haml with excludes specified', testReplaceWithExcludedSrc('haml')); 166 | }); 167 | 168 | describe('after uninstalls', function () { 169 | describe('after uninstalling one package', function () { 170 | function testReplaceAfterUninstalledPackage(fileType) { 171 | return function () { 172 | var filePaths = getFilePaths('index-after-uninstall', fileType); 173 | 174 | wiredep({ src: [filePaths.actual] }); 175 | 176 | wiredep({ 177 | bowerJson: JSON.parse(fs.readFileSync('./bower_after_uninstall.json')), 178 | src: [filePaths.actual] 179 | }); 180 | 181 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 182 | }; 183 | } 184 | 185 | it('should work with html', testReplaceAfterUninstalledPackage('html')); 186 | it('should work with jade', testReplaceAfterUninstalledPackage('jade')); 187 | it('should work with slim', testReplaceAfterUninstalledPackage('slim')); 188 | it('should work with haml', testReplaceAfterUninstalledPackage('haml')); 189 | }); 190 | 191 | describe('after uninstalling all packages', function () { 192 | function testReplaceAfterUninstallingAllPackages(fileType) { 193 | return function () { 194 | var filePaths = getFilePaths('index-after-uninstall-all', fileType); 195 | 196 | wiredep({ src: [filePaths.actual] }); 197 | 198 | wiredep({ 199 | bowerJson: JSON.parse(fs.readFileSync('./bower_after_uninstall_all.json')), 200 | src: [filePaths.actual] 201 | }); 202 | 203 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 204 | }; 205 | } 206 | 207 | it('should work with html', testReplaceAfterUninstallingAllPackages('html')); 208 | it('should work with jade', testReplaceAfterUninstallingAllPackages('jade')); 209 | it('should work with slim', testReplaceAfterUninstallingAllPackages('slim')); 210 | it('should work with haml', testReplaceAfterUninstallingAllPackages('haml')); 211 | }); 212 | }); 213 | 214 | describe('custom format', function () { 215 | function testReplaceWithCustomFormat(fileType, fileTypes) { 216 | return function () { 217 | var filePaths = getFilePaths('index-custom-format', fileType); 218 | 219 | wiredep({ 220 | src: [filePaths.actual], 221 | fileTypes: fileTypes 222 | }); 223 | 224 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 225 | }; 226 | } 227 | 228 | it('should work with html', testReplaceWithCustomFormat('html', { 229 | html: { 230 | replace: { 231 | js: '', 232 | css: '' 233 | } 234 | } 235 | })); 236 | 237 | it('should work with jade', testReplaceWithCustomFormat('jade', { 238 | jade: { 239 | replace: { 240 | js: 'script(type=\'text/javascript\', src=\'{{filePath}}\')', 241 | css: 'link(href=\'{{filePath}}\', rel=\'stylesheet\')' 242 | } 243 | } 244 | })); 245 | 246 | it('should work with yml', testReplaceWithCustomFormat('yml', { 247 | yml: { 248 | replace: { 249 | css: '- "{{filePath}}" #css', 250 | js: '- "{{filePath}}"' 251 | } 252 | } 253 | })); 254 | 255 | it('should work with slim', testReplaceWithCustomFormat('slim', { 256 | slim: { 257 | replace: { 258 | js: 'script type=\'text/javascript\' src=\'{{filePath}}\'', 259 | css: 'link href=\'{{filePath}}\' rel=\'stylesheet\'' 260 | } 261 | } 262 | })); 263 | 264 | it('should work with haml', testReplaceWithCustomFormat('haml', { 265 | haml: { 266 | replace: { 267 | js: '%script{type:\'text/javascript\', src:\'{{filePath}}\'}', 268 | css: '%link{href:\'{{filePath}}\', rel:\'stylesheet\'}' 269 | } 270 | } 271 | })); 272 | 273 | }); 274 | 275 | describe('devDependencies', function () { 276 | it('should wire devDependencies if specified', function () { 277 | var filePaths = getFilePaths('index-with-dev-dependencies', 'html'); 278 | 279 | wiredep({ 280 | dependencies: false, 281 | devDependencies: true, 282 | src: [filePaths.actual] 283 | }); 284 | 285 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 286 | }); 287 | }); 288 | 289 | describe('overrides', function () { 290 | it('should allow configuration overrides to specify a `main`', function () { 291 | var filePaths = getFilePaths('index-packages-without-main', 'html'); 292 | var bowerJson = JSON.parse(fs.readFileSync('./bower_packages_without_main.json')); 293 | var overrides = bowerJson.overrides; 294 | delete bowerJson.overrides; 295 | 296 | wiredep({ 297 | bowerJson: bowerJson, 298 | overrides: overrides, 299 | src: [filePaths.actual], 300 | exclude: ['fake-package-without-main-and-confusing-file-tree'] 301 | }); 302 | 303 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 304 | }); 305 | 306 | it('should allow configuration overrides to specify `dependencies`', function () { 307 | var filePaths = getFilePaths('index-override-dependencies', 'html'); 308 | var bowerJson = JSON.parse(fs.readFileSync('./bower_packages_without_dependencies.json')); 309 | var overrides = bowerJson.overrides; 310 | delete bowerJson.overrides; 311 | 312 | wiredep({ 313 | bowerJson: bowerJson, 314 | overrides: overrides, 315 | src: [filePaths.actual] 316 | }); 317 | 318 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 319 | }); 320 | }); 321 | 322 | describe('events', function() { 323 | var filePath = 'html/index-emitter.html'; 324 | var fileData; 325 | 326 | before(function(done) { 327 | fs.readFile(filePath, function(err, file) { 328 | fileData = file; 329 | done(err || null); 330 | }); 331 | }); 332 | 333 | beforeEach(function(done) { 334 | fs.writeFile(filePath, fileData, done); 335 | }); 336 | 337 | it('should send injected file data', function(done) { 338 | var injected = 0; 339 | var paths = ['bootstrap.css', 'codecode.css', 'bootstrap.js', 'codecode.js', 'jquery.js']; 340 | 341 | wiredep({ 342 | src: filePath, 343 | onPathInjected: function(file) { 344 | assert(typeof file.block !== 'undefined'); 345 | assert.equal(file.file, filePath); 346 | assert(paths.indexOf(file.path.split('/').pop()) > -1); 347 | 348 | if (++injected === paths.length) { 349 | done(); 350 | } 351 | } 352 | }); 353 | }); 354 | 355 | it('should send updated file path', function(done) { 356 | wiredep({ 357 | src: filePath, 358 | onFileUpdated: function(path) { 359 | assert.equal(path, filePath); 360 | done(); 361 | } 362 | }); 363 | }); 364 | 365 | it('should send package name when main is not found', function(done) { 366 | var bowerJson = JSON.parse(fs.readFileSync('./bower_packages_without_main.json')); 367 | var packageWithoutMain = 'fake-package-without-main-and-confusing-file-tree'; 368 | 369 | wiredep({ 370 | bowerJson: bowerJson, 371 | src: filePath, 372 | onMainNotFound: function(pkg) { 373 | assert.equal(pkg, packageWithoutMain); 374 | done(); 375 | } 376 | }); 377 | }); 378 | 379 | it('should throw an error when component is not found', function() { 380 | var bowerJson = JSON.parse(fs.readFileSync('./bower_with_missing_component.json')); 381 | var missingComponent = 'missing-component'; 382 | 383 | assert.throws(function () { 384 | wiredep({ 385 | bowerJson: bowerJson, 386 | src: filePath 387 | }); 388 | }, missingComponent + ' is not installed. Try running `bower install` or remove the component from your bower.json file.'); 389 | }); 390 | 391 | it('should allow overriding the error when component is not found', function(done) { 392 | var bowerJson = JSON.parse(fs.readFileSync('./bower_with_missing_component.json')); 393 | var missingComponent = 'missing-component'; 394 | 395 | wiredep({ 396 | bowerJson: bowerJson, 397 | src: filePath, 398 | onError: function(err) { 399 | assert.ok(err instanceof Error); 400 | assert.equal(err.message, missingComponent + ' is not installed. Try running `bower install` or remove the component from your bower.json file.'); 401 | done(); 402 | } 403 | }); 404 | }); 405 | }); 406 | 407 | it('should allow specifying a custom replace function', function () { 408 | var filePaths = getFilePaths('index-with-custom-replace-function', 'html'); 409 | 410 | wiredep({ 411 | src: [filePaths.actual], 412 | fileTypes: { 413 | html: { 414 | replace: { 415 | js: function (filePath) { 416 | return ''; 417 | } 418 | } 419 | } 420 | } 421 | }); 422 | 423 | assert.equal(filePaths.read('expected'), filePaths.read('actual')); 424 | }); 425 | 426 | it('should return a useful object', function () { 427 | var returnedObject = wiredep(); 428 | 429 | assert.equal(typeof returnedObject.js, 'object'); 430 | assert.equal(typeof returnedObject.css, 'object'); 431 | assert.equal(typeof returnedObject.less, 'object'); 432 | assert.equal(typeof returnedObject.scss, 'object'); 433 | assert.equal(typeof returnedObject.styl, 'object'); 434 | assert.equal(typeof returnedObject.packages, 'object'); 435 | }); 436 | 437 | it('should respect the directory specified in a `.bowerrc`', function () { 438 | var filePaths = getFilePaths('index-with-custom-bower-directory', 'html'); 439 | 440 | wiredep({ 441 | bowerJson: JSON.parse(fs.readFileSync('./bowerrc/bower.json')), 442 | cwd: './bowerrc', 443 | src: [filePaths.actual] 444 | }); 445 | 446 | assert.equal(filePaths.read('actual'), filePaths.read('expected')); 447 | }); 448 | 449 | it('should support inclusion of main files from top-level bower.json', function () { 450 | var filePaths = getFilePaths('index-include-self', 'html'); 451 | 452 | wiredep({ 453 | bowerJson: JSON.parse(fs.readFileSync('./bower_with_main.json')), 454 | src: [filePaths.actual], 455 | includeSelf: true 456 | }); 457 | 458 | assert.equal(filePaths.read('actual'), filePaths.read('expected')); 459 | }); 460 | 461 | it('should support inclusion of main files from bower.json in some other dir', function () { 462 | var filePaths = getFilePaths('index-cwd-include-self', 'html'); 463 | 464 | wiredep({ 465 | src: [filePaths.actual], 466 | cwd: 'cwd_includeself', 467 | includeSelf: true 468 | }); 469 | 470 | assert.equal(filePaths.read('actual'), filePaths.read('expected')); 471 | }); 472 | 473 | it('should support inclusion of main files from some other dir with manually loaded bower.json', function () { 474 | var filePaths = getFilePaths('index-cwd-include-self', 'html'); 475 | 476 | wiredep({ 477 | bowerJson: JSON.parse(fs.readFileSync('./cwd_includeself/bower.json')), 478 | src: [filePaths.actual], 479 | cwd: 'cwd_includeself', 480 | includeSelf: true 481 | }); 482 | 483 | assert.equal(filePaths.read('actual'), filePaths.read('expected')); 484 | }); 485 | 486 | it('should support inclusion of glob main files from bower.json', function () { 487 | var filePaths = getFilePaths('index-include-glob', 'html'); 488 | 489 | wiredep({ 490 | bowerJson: JSON.parse(fs.readFileSync('./glob_main/bower.json')), 491 | src: [filePaths.actual], 492 | cwd: 'glob_main' 493 | }); 494 | 495 | assert.equal(filePaths.read('actual'), filePaths.read('expected')); 496 | }); 497 | 498 | it('include-self: true should support inclusion of glob main files from own bower.json', function () { 499 | var filePaths = getFilePaths('index-include-self-glob', 'html'); 500 | 501 | wiredep({ 502 | bowerJson: JSON.parse(fs.readFileSync('./bower_with_main_glob.json')), 503 | src: [filePaths.actual], 504 | includeSelf: true 505 | }); 506 | 507 | assert.equal(filePaths.read('actual'), filePaths.read('expected')); 508 | }); 509 | }); 510 | 511 | function getFilePaths(fileName, fileType) { 512 | var extension = fileType.match(/([^/]*)[/]*/)[1]; 513 | var filePaths = { 514 | expected: path.resolve(fileType, fileName + '-expected.' + extension), 515 | actual: path.resolve(fileType, fileName + '-actual.' + extension), 516 | read: function (type) { 517 | return fs.readFileSync(filePaths[type], { encoding: 'utf8' }); 518 | } 519 | }; 520 | 521 | return filePaths; 522 | } 523 | -------------------------------------------------------------------------------- /wiredep.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var $ = { 4 | _: require('lodash'), 5 | 'bower-config': require('bower-config'), 6 | fs: require('fs'), 7 | glob: require('glob'), 8 | lodash: require('lodash'), 9 | path: require('path'), 10 | through2: require('through2') 11 | }; 12 | 13 | var config; 14 | var helpers = require('./lib/helpers'); 15 | var fileTypesDefault = require('./lib/default-file-types'); 16 | 17 | /** 18 | * Wire up the html files with the Bower packages. 19 | * 20 | * @param {object} config the global configuration object 21 | */ 22 | function wiredep(opts) { 23 | opts = opts || {}; 24 | 25 | var cwd = opts.cwd ? $.path.resolve(opts.cwd) : process.cwd(); 26 | 27 | config = module.exports.config = helpers.createStore(); 28 | 29 | config.set 30 | ('on-error', opts.onError || function(err) { throw new Error(err); }) 31 | ('on-file-updated', opts.onFileUpdated || function() {}) 32 | ('on-main-not-found', opts.onMainNotFound || function() {}) 33 | ('on-path-injected', opts.onPathInjected || function() {}); 34 | 35 | config.set 36 | ('bower.json', opts.bowerJson || JSON.parse($.fs.readFileSync($.path.join(cwd, './bower.json')))) 37 | ('bower-directory', opts.directory || findBowerDirectory(cwd)) 38 | ('cwd', cwd) 39 | ('dependencies', opts.dependencies === false ? false : true) 40 | ('detectable-file-types', []) 41 | ('dev-dependencies', opts.devDependencies) 42 | ('exclude', Array.isArray(opts.exclude) ? opts.exclude : [ opts.exclude ]) 43 | ('file-types', mergeFileTypesWithDefaults(opts.fileTypes)) 44 | ('global-dependencies', helpers.createStore()) 45 | ('ignore-path', opts.ignorePath) 46 | ('include-self', opts.includeSelf) 47 | ('overrides', $._.extend({}, config.get('bower.json').overrides, opts.overrides)) 48 | ('src', []) 49 | ('stream', opts.stream ? opts.stream : {}); 50 | 51 | $._.map(config.get('file-types'), 'detect'). 52 | forEach(function (fileType) { 53 | Object.keys(fileType). 54 | forEach(function (detectableFileType) { 55 | var detectableFileTypes = config.get('detectable-file-types'); 56 | 57 | if (detectableFileTypes.indexOf(detectableFileType) === -1) { 58 | config.set('detectable-file-types', detectableFileTypes.concat(detectableFileType)); 59 | } 60 | }); 61 | }); 62 | 63 | if (!opts.stream && opts.src) { 64 | (Array.isArray(opts.src) ? opts.src : [opts.src]). 65 | forEach(function (pattern) { 66 | config.set('src', config.get('src').concat($.glob.sync(pattern))); 67 | }); 68 | } 69 | 70 | require('./lib/detect-dependencies')(config); 71 | require('./lib/inject-dependencies')(config); 72 | 73 | return config.get('stream').src || 74 | Object.keys(config.get('global-dependencies-sorted')). 75 | reduce(function (acc, depType) { 76 | if (config.get('global-dependencies-sorted')[depType].length) { 77 | acc[depType] = config.get('global-dependencies-sorted')[depType]; 78 | } 79 | 80 | return acc; 81 | }, { packages: config.get('global-dependencies').get() }); 82 | } 83 | 84 | function mergeFileTypesWithDefaults(optsFileTypes) { 85 | var fileTypes = $._.clone(fileTypesDefault, true); 86 | 87 | $._(optsFileTypes).each(function (fileTypeConfig, fileType) { 88 | // fallback to the default type for all html-like extensions (php, twig, hbs, etc) 89 | fileTypes[fileType] = fileTypes[fileType] || fileTypes['default']; 90 | $._.each(fileTypeConfig, function (config, configKey) { 91 | if ($._.isPlainObject(fileTypes[fileType][configKey])) { 92 | fileTypes[fileType][configKey] = 93 | $._.assign(fileTypes[fileType][configKey], config); 94 | } else { 95 | fileTypes[fileType][configKey] = config; 96 | } 97 | }); 98 | }); 99 | 100 | return fileTypes; 101 | } 102 | 103 | function findBowerDirectory(cwd) { 104 | var directory = $.path.join(cwd, ($['bower-config'].read(cwd).directory || 'bower_components')); 105 | 106 | if (!$.fs.existsSync(directory)) { 107 | var error = new Error('Cannot find where you keep your Bower packages.'); 108 | error.code = 'BOWER_COMPONENTS_MISSING'; 109 | config.get('on-error')(error); 110 | } 111 | 112 | return directory; 113 | } 114 | 115 | wiredep.stream = function (opts) { 116 | opts = opts || {}; 117 | 118 | return $.through2.obj(function (file, enc, cb) { 119 | if (file.isNull()) { 120 | this.push(file); 121 | return cb(); 122 | } 123 | 124 | if (file.isStream()) { 125 | this.emit('error', 'Streaming not supported'); 126 | return cb(); 127 | } 128 | 129 | try { 130 | opts.stream = { 131 | src: file.contents.toString(), 132 | path: file.path, 133 | fileType: $.path.extname(file.path).substr(1) 134 | }; 135 | 136 | file.contents = new Buffer(wiredep(opts)); 137 | } catch (err) { 138 | this.emit('error', err); 139 | } 140 | 141 | this.push(file); 142 | cb(); 143 | }); 144 | }; 145 | 146 | 147 | module.exports = wiredep; 148 | --------------------------------------------------------------------------------