├── .editorconfig ├── .eslintrc.json ├── .gitattributes ├── .gitignore ├── .travis.yml ├── .verb.md ├── LICENSE ├── README.md ├── bower.json ├── example.js ├── index.js ├── package.json └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | end_of_line = lf 7 | charset = utf-8 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | insert_final_newline = false 15 | 16 | [**/{actual,fixtures,expected}/**] 17 | trim_trailing_whitespace = false 18 | insert_final_newline = false 19 | 20 | [**/templates/**] 21 | trim_trailing_whitespace = false 22 | insert_final_newline = false 23 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "ecmaFeatures": { 3 | "modules": true, 4 | "experimentalObjectRestSpread": true 5 | }, 6 | 7 | "env": { 8 | "browser": false, 9 | "es6": true, 10 | "node": true, 11 | "mocha": true 12 | }, 13 | 14 | "globals": { 15 | "document": false, 16 | "navigator": false, 17 | "window": false 18 | }, 19 | 20 | "rules": { 21 | "accessor-pairs": 2, 22 | "arrow-spacing": [2, { "before": true, "after": true }], 23 | "block-spacing": [2, "always"], 24 | "brace-style": [2, "1tbs", { "allowSingleLine": true }], 25 | "comma-dangle": [2, "never"], 26 | "comma-spacing": [2, { "before": false, "after": true }], 27 | "comma-style": [2, "last"], 28 | "constructor-super": 2, 29 | "curly": [2, "multi-line"], 30 | "dot-location": [2, "property"], 31 | "eol-last": 2, 32 | "eqeqeq": [2, "allow-null"], 33 | "generator-star-spacing": [2, { "before": true, "after": true }], 34 | "handle-callback-err": [2, "^(err|error)$" ], 35 | "indent": [2, 2, { "SwitchCase": 1 }], 36 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }], 37 | "keyword-spacing": [2, { "before": true, "after": true }], 38 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }], 39 | "new-parens": 2, 40 | "no-array-constructor": 2, 41 | "no-caller": 2, 42 | "no-class-assign": 2, 43 | "no-cond-assign": 2, 44 | "no-const-assign": 2, 45 | "no-control-regex": 2, 46 | "no-debugger": 2, 47 | "no-delete-var": 2, 48 | "no-dupe-args": 2, 49 | "no-dupe-class-members": 2, 50 | "no-dupe-keys": 2, 51 | "no-duplicate-case": 2, 52 | "no-empty-character-class": 2, 53 | "no-eval": 2, 54 | "no-ex-assign": 2, 55 | "no-extend-native": 2, 56 | "no-extra-bind": 2, 57 | "no-extra-boolean-cast": 2, 58 | "no-extra-parens": [2, "functions"], 59 | "no-fallthrough": 2, 60 | "no-floating-decimal": 2, 61 | "no-func-assign": 2, 62 | "no-implied-eval": 2, 63 | "no-inner-declarations": [2, "functions"], 64 | "no-invalid-regexp": 2, 65 | "no-irregular-whitespace": 2, 66 | "no-iterator": 2, 67 | "no-label-var": 2, 68 | "no-labels": 2, 69 | "no-lone-blocks": 2, 70 | "no-mixed-spaces-and-tabs": 2, 71 | "no-multi-spaces": 2, 72 | "no-multi-str": 2, 73 | "no-multiple-empty-lines": [2, { "max": 1 }], 74 | "no-native-reassign": 0, 75 | "no-negated-in-lhs": 2, 76 | "no-new": 2, 77 | "no-new-func": 2, 78 | "no-new-object": 2, 79 | "no-new-require": 2, 80 | "no-new-wrappers": 2, 81 | "no-obj-calls": 2, 82 | "no-octal": 2, 83 | "no-octal-escape": 2, 84 | "no-proto": 0, 85 | "no-redeclare": 2, 86 | "no-regex-spaces": 2, 87 | "no-return-assign": 2, 88 | "no-self-compare": 2, 89 | "no-sequences": 2, 90 | "no-shadow-restricted-names": 2, 91 | "no-spaced-func": 2, 92 | "no-sparse-arrays": 2, 93 | "no-this-before-super": 2, 94 | "no-throw-literal": 2, 95 | "no-trailing-spaces": 0, 96 | "no-undef": 2, 97 | "no-undef-init": 2, 98 | "no-unexpected-multiline": 2, 99 | "no-unneeded-ternary": [2, { "defaultAssignment": false }], 100 | "no-unreachable": 2, 101 | "no-unused-vars": [2, { "vars": "all", "args": "none" }], 102 | "no-useless-call": 0, 103 | "no-with": 2, 104 | "one-var": [0, { "initialized": "never" }], 105 | "operator-linebreak": [0, "after", { "overrides": { "?": "before", ":": "before" } }], 106 | "padded-blocks": [0, "never"], 107 | "quotes": [2, "single", "avoid-escape"], 108 | "radix": 2, 109 | "semi": [2, "always"], 110 | "semi-spacing": [2, { "before": false, "after": true }], 111 | "space-before-blocks": [2, "always"], 112 | "space-before-function-paren": [2, "never"], 113 | "space-in-parens": [2, "never"], 114 | "space-infix-ops": 2, 115 | "space-unary-ops": [2, { "words": true, "nonwords": false }], 116 | "spaced-comment": [0, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], 117 | "use-isnan": 2, 118 | "valid-typeof": 2, 119 | "wrap-iife": [2, "any"], 120 | "yoda": [2, "never"] 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Enforce Unix newlines 2 | * text eol=lf 3 | 4 | # binaries 5 | *.ai binary 6 | *.psd binary 7 | *.jpg binary 8 | *.gif binary 9 | *.png binary 10 | *.jpeg binary -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Numerous always-ignore extensions 2 | *.DS_Store 3 | *.csv 4 | *.dat 5 | *.diff 6 | *.err 7 | *.gz 8 | *.log 9 | *.orig 10 | *.out 11 | *.pid 12 | *.rej 13 | *.seed 14 | *.swo 15 | *.swp 16 | *.vi 17 | *.yo-rc.json 18 | *.zip 19 | *~ 20 | .ruby-version 21 | lib-cov 22 | 23 | # OS or Editor folders 24 | *.esproj 25 | *.sublime-project 26 | *.sublime-workspace 27 | ._* 28 | .cache 29 | .DS_Store 30 | .idea 31 | .project 32 | .settings 33 | .tmproj 34 | nbproject 35 | Thumbs.db 36 | 37 | # Komodo 38 | *.komodoproject 39 | .komodotools 40 | 41 | # grunt-html-validation 42 | validation-status.json 43 | validation-report.json 44 | 45 | # Vendor packages 46 | node_modules 47 | bower_components 48 | vendor 49 | 50 | # General folders and files to ignore 51 | _gh_pages 52 | tmp 53 | temp 54 | TODO.md -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '8' 5 | - '6' 6 | - '4' 7 | - '0.12' 8 | - '0.10' 9 | matrix: 10 | fast_finish: true 11 | -------------------------------------------------------------------------------- /.verb.md: -------------------------------------------------------------------------------- 1 | ## Usage 2 | 3 | ```js 4 | var parsePath = require('{%= name %}'); 5 | parsePath(filepath); 6 | ``` 7 | 8 | This can be used as a polyfill for the native node.js `path.parse()` method, and it also adds a few properties: 9 | 10 | - `path`: the original filepath 11 | - `isAbsolute`: (getter) true if the given path is absolute 12 | - `absolute`: (getter) fully resolved, absolute filepath 13 | - `dirname`: alias for `dir` 14 | - `basename`: alias for `base` 15 | - `extname`: alias for `ext` 16 | - `stem`: alias for `name` 17 | 18 | **Example** 19 | 20 | ```js 21 | var parsePath = require('{%= name %}'); 22 | console.log(parsePath('foo/bar/baz/index.js')); 23 | ``` 24 | 25 | Returns: 26 | 27 | ```js 28 | { root: '', 29 | dir: 'foo/bar/baz', 30 | base: 'index.js', 31 | ext: '.js', 32 | name: 'index', 33 | 34 | // aliases 35 | extname: '.js', 36 | basename: 'index.js', 37 | dirname: 'foo/bar/baz', 38 | stem: 'index', 39 | 40 | // original path 41 | path: 'foo/bar/baz/index.js', 42 | 43 | // getters 44 | absolute: [Getter/Setter], 45 | isAbsolute: [Getter/Setter] } 46 | ``` 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2015, Jon Schlinkert. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # parse-filepath [![NPM version](https://img.shields.io/npm/v/parse-filepath.svg?style=flat)](https://www.npmjs.com/package/parse-filepath) [![NPM downloads](https://img.shields.io/npm/dm/parse-filepath.svg?style=flat)](https://npmjs.org/package/parse-filepath) [![Build Status](https://img.shields.io/travis/jonschlinkert/parse-filepath.svg?style=flat)](https://travis-ci.org/jonschlinkert/parse-filepath) 2 | 3 | > Pollyfill for node.js `path.parse`, parses a filepath into an object. 4 | 5 | You might also be interested in [global-prefix](https://github.com/jonschlinkert/global-prefix). 6 | 7 | ## Install 8 | 9 | Install with [npm](https://www.npmjs.com/): 10 | 11 | ```sh 12 | $ npm install parse-filepath --save 13 | ``` 14 | 15 | ## Usage 16 | 17 | ```js 18 | var parsePath = require('parse-filepath'); 19 | parsePath(filepath); 20 | ``` 21 | 22 | This can be used as a polyfill for the native node.js `path.parse()` method, and it also adds a few properties: 23 | 24 | * `path`: the original filepath 25 | * `isAbsolute`: (getter) true if the given path is absolute 26 | * `absolute`: (getter) fully resolved, absolute filepath 27 | * `dirname`: alias for `dir` 28 | * `basename`: alias for `base` 29 | * `extname`: alias for `ext` 30 | * `stem`: alias for `name` 31 | 32 | **Example** 33 | 34 | ```js 35 | var parsePath = require('parse-filepath'); 36 | console.log(parsePath('foo/bar/baz/index.js')); 37 | ``` 38 | 39 | Returns: 40 | 41 | ```js 42 | { root: '', 43 | dir: 'foo/bar/baz', 44 | base: 'index.js', 45 | ext: '.js', 46 | name: 'index', 47 | 48 | // aliases 49 | extname: '.js', 50 | basename: 'index.js', 51 | dirname: 'foo/bar/baz', 52 | stem: 'index', 53 | 54 | // original path 55 | path: 'foo/bar/baz/index.js', 56 | 57 | // getters 58 | absolute: [Getter/Setter], 59 | isAbsolute: [Getter/Setter] } 60 | ``` 61 | 62 | ## Related projects 63 | 64 | You might also be interested in these projects: 65 | 66 | * [global-prefix](https://www.npmjs.com/package/global-prefix): Get the npm global path prefix. | [homepage](https://github.com/jonschlinkert/global-prefix) 67 | * [is-absolute](https://www.npmjs.com/package/is-absolute): Polyfill for node.js `path.isAbolute`. Returns true if a file path is absolute. | [homepage](https://github.com/jonschlinkert/is-absolute) 68 | * [is-relative](https://www.npmjs.com/package/is-relative): Returns `true` if the path appears to be relative. | [homepage](https://github.com/jonschlinkert/is-relative) 69 | * [relative](https://www.npmjs.com/package/relative): Get the relative filepath from path A to path B. Calculates from file-to-directory, file-to-file, directory-to-file,… [more](https://www.npmjs.com/package/relative) | [homepage](https://github.com/jonschlinkert/relative) 70 | 71 | ## Contributing 72 | 73 | Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/parse-filepath/issues/new). 74 | 75 | ## Building docs 76 | 77 | Generate readme and API documentation with [verb](https://github.com/verbose/verb): 78 | 79 | ```sh 80 | $ npm install verb && npm run docs 81 | ``` 82 | 83 | Or, if [verb](https://github.com/verbose/verb) is installed globally: 84 | 85 | ```sh 86 | $ verb 87 | ``` 88 | 89 | ## Running tests 90 | 91 | Install dev dependencies: 92 | 93 | ```sh 94 | $ npm install -d && npm test 95 | ``` 96 | 97 | ## Author 98 | 99 | **Jon Schlinkert** 100 | 101 | * [github/jonschlinkert](https://github.com/jonschlinkert) 102 | * [twitter/jonschlinkert](http://twitter.com/jonschlinkert) 103 | 104 | ## License 105 | 106 | Copyright © 2016, [Jon Schlinkert](https://github.com/jonschlinkert). 107 | Released under the [MIT license](https://github.com/jonschlinkert/parse-filepath/blob/master/LICENSE). 108 | 109 | *** 110 | 111 | _This file was generated by [verb](https://github.com/verbose/verb), v, on March 29, 2016._ -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parse-filepath", 3 | "description": "Pollyfill for node.js `path.parse`, parses a filepath into an object.", 4 | "repository": "jonschlinkert/parse-filepath", 5 | "license": "MIT", 6 | "homepage": "https://github.com/jonschlinkert/parse-filepath", 7 | "authors": [ 8 | "Jon Schlinkert (https://github.com/jonschlinkert)" 9 | ], 10 | "main": [ 11 | "index.js" 12 | ], 13 | "dependencies": { 14 | "is-absolute": "^0.2.3", 15 | "map-cache": "^0.2.0" 16 | }, 17 | "devDependencies": { 18 | "gulp-format-md": "^0.1.7", 19 | "mocha": "^2.2.5", 20 | "should": "^7.0.2" 21 | }, 22 | "keywords": [ 23 | "absolute", 24 | "basename", 25 | "dir", 26 | "directory", 27 | "dirname", 28 | "ext", 29 | "extension", 30 | "extname", 31 | "file", 32 | "filename", 33 | "filepath", 34 | "is-absolute", 35 | "name", 36 | "object", 37 | "parse", 38 | "parser", 39 | "parts", 40 | "path", 41 | "segment" 42 | ] 43 | } -------------------------------------------------------------------------------- /example.js: -------------------------------------------------------------------------------- 1 | var parsePath = require('./'); 2 | console.log(parsePath('foo/bar/baz/index.js')); 3 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var path = require('path'); 4 | var isAbsolute = require('is-absolute'); 5 | var pathRoot = require('path-root'); 6 | var MapCache = require('map-cache'); 7 | var cache = new MapCache(); 8 | 9 | module.exports = function(filepath) { 10 | if (typeof filepath !== 'string') { 11 | throw new TypeError('parse-filepath expects a string'); 12 | } 13 | 14 | if (cache.has(filepath)) { 15 | return cache.get(filepath); 16 | } 17 | 18 | var obj = {}; 19 | if (typeof path.parse === 'function') { 20 | obj = path.parse(filepath); 21 | obj.extname = obj.ext; 22 | obj.basename = obj.base; 23 | obj.dirname = obj.dir; 24 | obj.stem = obj.name; 25 | 26 | } else { 27 | define(obj, 'root', function() { 28 | return pathRoot(this.path); 29 | }); 30 | 31 | define(obj, 'extname', function() { 32 | return path.extname(filepath); 33 | }); 34 | 35 | define(obj, 'ext', function() { 36 | return this.extname; 37 | }); 38 | 39 | define(obj, 'name', function() { 40 | return path.basename(filepath, this.ext); 41 | }); 42 | 43 | define(obj, 'stem', function() { 44 | return this.name; 45 | }); 46 | 47 | define(obj, 'base', function() { 48 | return this.name + this.ext; 49 | }); 50 | 51 | define(obj, 'basename', function() { 52 | return this.base; 53 | }); 54 | 55 | define(obj, 'dir', function() { 56 | var dir = path.dirname(filepath); 57 | if (dir === '.') { 58 | return (filepath[0] === '.') ? dir : ''; 59 | } else { 60 | return dir; 61 | } 62 | }); 63 | 64 | define(obj, 'dirname', function() { 65 | return this.dir; 66 | }); 67 | } 68 | 69 | obj.path = filepath; 70 | 71 | define(obj, 'absolute', function() { 72 | return path.resolve(this.path); 73 | }); 74 | 75 | define(obj, 'isAbsolute', function() { 76 | return isAbsolute(this.path); 77 | }); 78 | 79 | cache.set(filepath, obj); 80 | return obj; 81 | }; 82 | 83 | function define(obj, prop, fn) { 84 | var cached; 85 | Object.defineProperty(obj, prop, { 86 | configurable: true, 87 | enumerable: true, 88 | set: function(val) { 89 | cached = val; 90 | }, 91 | get: function() { 92 | return cached || (cached = fn.call(obj)); 93 | } 94 | }); 95 | } 96 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parse-filepath", 3 | "description": "Pollyfill for node.js `path.parse`, parses a filepath into an object.", 4 | "version": "1.0.2", 5 | "homepage": "https://github.com/jonschlinkert/parse-filepath", 6 | "author": "Jon Schlinkert (https://github.com/jonschlinkert)", 7 | "repository": "jonschlinkert/parse-filepath", 8 | "bugs": { 9 | "url": "https://github.com/jonschlinkert/parse-filepath/issues" 10 | }, 11 | "license": "MIT", 12 | "files": [ 13 | "index.js" 14 | ], 15 | "main": "index.js", 16 | "engines": { 17 | "node": ">=0.8" 18 | }, 19 | "scripts": { 20 | "test": "mocha" 21 | }, 22 | "dependencies": { 23 | "is-absolute": "^1.0.0", 24 | "map-cache": "^0.2.0", 25 | "path-root": "^0.1.1" 26 | }, 27 | "devDependencies": { 28 | "gulp-format-md": "^0.1.7", 29 | "mocha": "^2.2.5", 30 | "should": "^7.0.2" 31 | }, 32 | "keywords": [ 33 | "absolute", 34 | "basename", 35 | "dir", 36 | "directory", 37 | "dirname", 38 | "ext", 39 | "extension", 40 | "extname", 41 | "file", 42 | "filename", 43 | "filepath", 44 | "is-absolute", 45 | "name", 46 | "object", 47 | "parse", 48 | "parser", 49 | "parts", 50 | "path", 51 | "segment" 52 | ], 53 | "verb": { 54 | "run": true, 55 | "toc": false, 56 | "layout": "default", 57 | "tasks": [ 58 | "readme" 59 | ], 60 | "plugins": [ 61 | "gulp-format-md" 62 | ], 63 | "related": { 64 | "highlight": "global-prefix", 65 | "list": [ 66 | "global-prefix", 67 | "is-absolute", 68 | "is-relative", 69 | "relative" 70 | ] 71 | }, 72 | "reflinks": [ 73 | "verb" 74 | ], 75 | "lint": { 76 | "reflinks": true 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('mocha'); 4 | require('should'); 5 | var path = require('path'); 6 | var assert = require('assert'); 7 | 8 | if (typeof path.parse === 'function') { 9 | describe('with native `path.parse` method:', function() { 10 | 11 | var parsePath; 12 | 13 | beforeEach(function() { 14 | // Avoid cache 15 | delete require.cache[require.resolve('./')]; 16 | parsePath = require('./'); 17 | }); 18 | 19 | describe('dotfiles', function() { 20 | it('should get the absolute path:', function() { 21 | var parsed = parsePath('foo/bar/baz/.dotfile'); 22 | parsed.should.have.property('absolute', path.resolve('foo/bar/baz/.dotfile')); 23 | }); 24 | 25 | it('should specify if a path is absolute:', function() { 26 | assert(!parsePath('foo/bar/baz/.dotfile').isAbsolute); 27 | }); 28 | 29 | it('should specify if a path is absolute:', function() { 30 | assert(parsePath('/foo/bar/baz/.dotfile').isAbsolute); 31 | }); 32 | 33 | it('should recognize dotfiles', function() { 34 | var parsed = parsePath('foo/bar/baz/.dotfile'); 35 | parsed.should.have.property('path', 'foo/bar/baz/.dotfile'); 36 | parsed.should.have.property('name', '.dotfile'); 37 | parsed.should.have.property('stem', '.dotfile'); 38 | parsed.should.have.property('dirname', 'foo/bar/baz'); 39 | parsed.should.have.property('dir', 'foo/bar/baz'); 40 | parsed.should.have.property('extname', ''); 41 | parsed.should.have.property('ext', ''); 42 | parsed.should.have.property('name', '.dotfile'); 43 | parsed.should.have.property('stem', '.dotfile'); 44 | }); 45 | 46 | it('should recognize .gitignore', function() { 47 | var parsed = parsePath('./.gitignore'); 48 | parsed.should.have.property('name', '.gitignore'); 49 | parsed.should.have.property('stem', '.gitignore'); 50 | parsed.should.have.property('dirname', '.'); 51 | parsed.should.have.property('dir', '.'); 52 | parsed.should.have.property('extname', ''); 53 | parsed.should.have.property('ext', ''); 54 | parsed.should.have.property('basename', '.gitignore'); 55 | parsed.should.have.property('base', '.gitignore'); 56 | parsed.should.have.property('root', ''); 57 | }); 58 | 59 | it('should recognize config files', function() { 60 | var parsed = parsePath('./.verbfile.md'); 61 | parsed.should.have.property('name', '.verbfile'); 62 | parsed.should.have.property('stem', '.verbfile'); 63 | parsed.should.have.property('dirname', '.'); 64 | parsed.should.have.property('dir', '.'); 65 | parsed.should.have.property('extname', '.md'); 66 | parsed.should.have.property('ext', '.md'); 67 | parsed.should.have.property('basename', '.verbfile.md'); 68 | parsed.should.have.property('base', '.verbfile.md'); 69 | parsed.should.have.property('root', ''); 70 | }); 71 | 72 | it('should recognize config files', function() { 73 | var parsed = parsePath('./.travis.yml'); 74 | parsed.should.have.property('name', '.travis'); 75 | parsed.should.have.property('stem', '.travis'); 76 | parsed.should.have.property('dirname', '.'); 77 | parsed.should.have.property('dir', '.'); 78 | parsed.should.have.property('extname', '.yml'); 79 | parsed.should.have.property('ext', '.yml'); 80 | parsed.should.have.property('basename', '.travis.yml'); 81 | parsed.should.have.property('base', '.travis.yml'); 82 | parsed.should.have.property('root', ''); 83 | }); 84 | }); 85 | 86 | describe('when a single segment is passed', function() { 87 | it('should return the correct values', function() { 88 | var parsed = parsePath('foo'); 89 | parsed.should.have.property('name', 'foo'); 90 | parsed.should.have.property('stem', 'foo'); 91 | parsed.should.have.property('dirname', ''); 92 | parsed.should.have.property('dir', ''); 93 | parsed.should.have.property('extname', ''); 94 | parsed.should.have.property('ext', ''); 95 | parsed.should.have.property('basename', 'foo'); 96 | parsed.should.have.property('base', 'foo'); 97 | parsed.should.have.property('root', ''); 98 | }); 99 | 100 | it('should return the correct values', function() { 101 | var parsed = parsePath('./foo'); 102 | parsed.should.have.property('name', 'foo'); 103 | parsed.should.have.property('stem', 'foo'); 104 | parsed.should.have.property('dirname', '.'); 105 | parsed.should.have.property('dir', '.'); 106 | parsed.should.have.property('extname', ''); 107 | parsed.should.have.property('ext', ''); 108 | parsed.should.have.property('basename', 'foo'); 109 | parsed.should.have.property('base', 'foo'); 110 | parsed.should.have.property('root', ''); 111 | }); 112 | }); 113 | 114 | describe('when a filepath is passed', function() { 115 | it('should return an object of path parts', function() { 116 | var parsed = parsePath('foo/bar/baz/index.html'); 117 | parsed.should.have.property('name', 'index'); 118 | parsed.should.have.property('stem', 'index'); 119 | parsed.should.have.property('dirname', 'foo/bar/baz'); 120 | parsed.should.have.property('dir', 'foo/bar/baz'); 121 | parsed.should.have.property('extname', '.html'); 122 | parsed.should.have.property('ext', '.html'); 123 | parsed.should.have.property('basename', 'index.html'); 124 | parsed.should.have.property('base', 'index.html'); 125 | parsed.should.have.property('root', ''); 126 | }); 127 | 128 | it('should get the root', function() { 129 | var parsed = parsePath('/foo/bar/baz/index.html'); 130 | parsed.should.have.property('name', 'index'); 131 | parsed.should.have.property('stem', 'index'); 132 | parsed.should.have.property('dirname', '/foo/bar/baz'); 133 | parsed.should.have.property('dir', '/foo/bar/baz'); 134 | parsed.should.have.property('extname', '.html'); 135 | parsed.should.have.property('ext', '.html'); 136 | parsed.should.have.property('basename', 'index.html'); 137 | parsed.should.have.property('base', 'index.html'); 138 | parsed.should.have.property('root', '/'); 139 | }); 140 | }); 141 | 142 | describe('when a filepath ends with a slash', function() { 143 | it('dirname should be the full filepath, and basename should be empty', function() { 144 | var parsed = parsePath('foo/bar/baz/quux/'); 145 | parsed.should.have.property('name', 'quux'); 146 | parsed.should.have.property('stem', 'quux'); 147 | parsed.should.have.property('dirname', 'foo/bar/baz'); 148 | parsed.should.have.property('dir', 'foo/bar/baz'); 149 | parsed.should.have.property('extname', ''); 150 | parsed.should.have.property('ext', ''); 151 | parsed.should.have.property('basename', 'quux'); 152 | parsed.should.have.property('base', 'quux'); 153 | parsed.should.have.property('root', ''); 154 | }); 155 | }); 156 | 157 | describe('when a filepath with multiple extensions is passed', function() { 158 | it('should return an object of path parts', function() { 159 | var parsed = parsePath('foo/bar/baz/index.md.html'); 160 | parsed.should.have.property('name', 'index.md'); 161 | parsed.should.have.property('stem', 'index.md'); 162 | parsed.should.have.property('dirname', 'foo/bar/baz'); 163 | parsed.should.have.property('dir', 'foo/bar/baz'); 164 | parsed.should.have.property('extname', '.html'); 165 | parsed.should.have.property('ext', '.html'); 166 | parsed.should.have.property('basename', 'index.md.html'); 167 | parsed.should.have.property('base', 'index.md.html'); 168 | parsed.should.have.property('root', ''); 169 | }); 170 | }); 171 | 172 | describe('when a filepath with zero extensions is passed', function() { 173 | it('should return an object of path parts', function() { 174 | var parsed = parsePath('foo/bar/baz/index'); 175 | parsed.should.have.property('name', 'index'); 176 | parsed.should.have.property('stem', 'index'); 177 | parsed.should.have.property('dirname', 'foo/bar/baz'); 178 | parsed.should.have.property('dir', 'foo/bar/baz'); 179 | parsed.should.have.property('extname', ''); 180 | parsed.should.have.property('ext', ''); 181 | parsed.should.have.property('basename', 'index'); 182 | parsed.should.have.property('base', 'index'); 183 | parsed.should.have.property('root', ''); 184 | }); 185 | }); 186 | 187 | describe('when a dirname is "."', function() { 188 | it('should preserve the basename', function() { 189 | var parsed = parsePath('index.js'); 190 | parsed.should.have.property('dirname', ''); 191 | parsed.should.have.property('dir', ''); 192 | parsed.should.have.property('basename', 'index.js'); 193 | parsed.should.have.property('base', 'index.js'); 194 | parsed.should.have.property('name', 'index'); 195 | parsed.should.have.property('stem', 'index'); 196 | parsed.should.have.property('extname', '.js'); 197 | parsed.should.have.property('ext', '.js'); 198 | parsed.should.have.property('root', ''); 199 | }); 200 | 201 | it('should parse paths without extensions', function() { 202 | var parsed = parsePath('foo/bar/baz/index'); 203 | parsed.should.have.property('name', 'index'); 204 | parsed.should.have.property('stem', 'index'); 205 | parsed.should.have.property('dirname', 'foo/bar/baz'); 206 | parsed.should.have.property('dir', 'foo/bar/baz'); 207 | parsed.should.have.property('extname', ''); 208 | parsed.should.have.property('ext', ''); 209 | parsed.should.have.property('basename', 'index'); 210 | parsed.should.have.property('base', 'index'); 211 | parsed.should.have.property('root', ''); 212 | }); 213 | 214 | it('should return the extension from options.ext', function() { 215 | parsePath('foo/bar/baz.min.js').extname.should.eql('.js'); 216 | }); 217 | it('should parse the extname', function() { 218 | parsePath('foo/bar/baz.js').extname.should.eql('.js'); 219 | }); 220 | it('should return an empty extname when no extension is passed', function() { 221 | parsePath('foo/bar/baz').extname.should.eql(''); 222 | }); 223 | }); 224 | }); 225 | } 226 | 227 | describe('without native `path.parse` method:', function() { 228 | 229 | var fn; 230 | var parsePath; 231 | 232 | before(function() { 233 | fn = path.parse; 234 | delete path.parse; 235 | }); 236 | 237 | after(function() { 238 | path.parse = fn; 239 | }); 240 | 241 | beforeEach(function() { 242 | // Avoid cache 243 | delete require.cache[require.resolve('./')]; 244 | parsePath = require('./'); 245 | }); 246 | 247 | describe('dotfiles', function() { 248 | it('should get the absolute path:', function() { 249 | var parsed = parsePath('foo/bar/baz/.dotfile'); 250 | parsed.should.have.property('absolute', path.resolve('foo/bar/baz/.dotfile')); 251 | }); 252 | 253 | it('should specify if a path is absolute:', function() { 254 | assert(!parsePath('foo/bar/baz/.dotfile').isAbsolute); 255 | }); 256 | 257 | it('should specify if a path is absolute', function() { 258 | assert(parsePath('/foo/bar/baz/.dotfile').isAbsolute); 259 | }); 260 | 261 | it('should recognize dotfiles', function() { 262 | var parsed = parsePath('foo/bar/baz/.dotfile'); 263 | parsed.should.have.property('path', 'foo/bar/baz/.dotfile'); 264 | parsed.should.have.property('name', '.dotfile'); 265 | parsed.should.have.property('stem', '.dotfile'); 266 | parsed.should.have.property('dirname', 'foo/bar/baz'); 267 | parsed.should.have.property('dir', 'foo/bar/baz'); 268 | parsed.should.have.property('extname', ''); 269 | parsed.should.have.property('ext', ''); 270 | parsed.should.have.property('name', '.dotfile'); 271 | parsed.should.have.property('stem', '.dotfile'); 272 | parsed.should.have.property('root', ''); 273 | }); 274 | 275 | it('should recognize .gitignore', function() { 276 | var parsed = parsePath('./.gitignore'); 277 | parsed.should.have.property('name', '.gitignore'); 278 | parsed.should.have.property('stem', '.gitignore'); 279 | parsed.should.have.property('dirname', '.'); 280 | parsed.should.have.property('extname', ''); 281 | parsed.should.have.property('ext', ''); 282 | parsed.should.have.property('ext', ''); 283 | parsed.should.have.property('basename', '.gitignore'); 284 | parsed.should.have.property('base', '.gitignore'); 285 | parsed.should.have.property('root', ''); 286 | }); 287 | 288 | it('should recognize config files', function() { 289 | var parsed = parsePath('./.verbfile.md'); 290 | parsed.should.have.property('name', '.verbfile'); 291 | parsed.should.have.property('stem', '.verbfile'); 292 | parsed.should.have.property('dirname', '.'); 293 | parsed.should.have.property('dir', '.'); 294 | parsed.should.have.property('extname', '.md'); 295 | parsed.should.have.property('ext', '.md'); 296 | parsed.should.have.property('basename', '.verbfile.md'); 297 | parsed.should.have.property('base', '.verbfile.md'); 298 | parsed.should.have.property('root', ''); 299 | }); 300 | 301 | it('should recognize config files', function() { 302 | var parsed = parsePath('./.travis.yml'); 303 | parsed.should.have.property('name', '.travis'); 304 | parsed.should.have.property('stem', '.travis'); 305 | parsed.should.have.property('dirname', '.'); 306 | parsed.should.have.property('dir', '.'); 307 | parsed.should.have.property('extname', '.yml'); 308 | parsed.should.have.property('ext', '.yml'); 309 | parsed.should.have.property('basename', '.travis.yml'); 310 | parsed.should.have.property('base', '.travis.yml'); 311 | parsed.should.have.property('root', ''); 312 | }); 313 | }); 314 | 315 | describe('when a single segment is passed', function() { 316 | it('should return the correct values', function() { 317 | var parsed = parsePath('foo'); 318 | parsed.should.have.property('name', 'foo'); 319 | parsed.should.have.property('stem', 'foo'); 320 | parsed.should.have.property('dirname', ''); 321 | parsed.should.have.property('dir', ''); 322 | parsed.should.have.property('extname', ''); 323 | parsed.should.have.property('ext', ''); 324 | parsed.should.have.property('basename', 'foo'); 325 | parsed.should.have.property('base', 'foo'); 326 | parsed.should.have.property('root', ''); 327 | }); 328 | 329 | it('should return the correct values', function() { 330 | var parsed = parsePath('./foo'); 331 | parsed.should.have.property('name', 'foo'); 332 | parsed.should.have.property('stem', 'foo'); 333 | parsed.should.have.property('dirname', '.'); 334 | parsed.should.have.property('dir', '.'); 335 | parsed.should.have.property('extname', ''); 336 | parsed.should.have.property('ext', ''); 337 | parsed.should.have.property('basename', 'foo'); 338 | parsed.should.have.property('base', 'foo'); 339 | parsed.should.have.property('root', ''); 340 | }); 341 | }); 342 | 343 | describe('when a filepath is passed', function() { 344 | it('should return an object of path parts', function() { 345 | var parsed = parsePath('foo/bar/baz/index.html'); 346 | parsed.should.have.property('name', 'index'); 347 | parsed.should.have.property('stem', 'index'); 348 | parsed.should.have.property('dirname', 'foo/bar/baz'); 349 | parsed.should.have.property('dir', 'foo/bar/baz'); 350 | parsed.should.have.property('extname', '.html'); 351 | parsed.should.have.property('ext', '.html'); 352 | parsed.should.have.property('basename', 'index.html'); 353 | parsed.should.have.property('base', 'index.html'); 354 | parsed.should.have.property('root', ''); 355 | }); 356 | 357 | it('should get the root', function() { 358 | var parsed = parsePath('/foo/bar/baz/index.html'); 359 | parsed.should.have.property('name', 'index'); 360 | parsed.should.have.property('stem', 'index'); 361 | parsed.should.have.property('dirname', '/foo/bar/baz'); 362 | parsed.should.have.property('dir', '/foo/bar/baz'); 363 | parsed.should.have.property('extname', '.html'); 364 | parsed.should.have.property('ext', '.html'); 365 | parsed.should.have.property('basename', 'index.html'); 366 | parsed.should.have.property('base', 'index.html'); 367 | parsed.should.have.property('root', '/'); 368 | }); 369 | }); 370 | 371 | describe('when a filepath ends with a slash', function() { 372 | it('dirname should be the full filepath, and basename should be empty', function() { 373 | var parsed = parsePath('foo/bar/baz/quux/'); 374 | parsed.should.have.property('name', 'quux'); 375 | parsed.should.have.property('stem', 'quux'); 376 | parsed.should.have.property('dirname', 'foo/bar/baz'); 377 | parsed.should.have.property('dir', 'foo/bar/baz'); 378 | parsed.should.have.property('extname', ''); 379 | parsed.should.have.property('ext', ''); 380 | parsed.should.have.property('basename', 'quux'); 381 | parsed.should.have.property('base', 'quux'); 382 | parsed.should.have.property('root', ''); 383 | }); 384 | }); 385 | 386 | describe('when a filepath with multiple extensions is passed', function() { 387 | it('should return an object of path parts', function() { 388 | var parsed = parsePath('foo/bar/baz/index.md.html'); 389 | parsed.should.have.property('name', 'index.md'); 390 | parsed.should.have.property('stem', 'index.md'); 391 | parsed.should.have.property('dirname', 'foo/bar/baz'); 392 | parsed.should.have.property('dir', 'foo/bar/baz'); 393 | parsed.should.have.property('extname', '.html'); 394 | parsed.should.have.property('ext', '.html'); 395 | parsed.should.have.property('basename', 'index.md.html'); 396 | parsed.should.have.property('base', 'index.md.html'); 397 | parsed.should.have.property('root', ''); 398 | }); 399 | }); 400 | 401 | describe('when a filepath with zero extensions is passed', function() { 402 | it('should return an object of path parts', function() { 403 | var parsed = parsePath('foo/bar/baz/index'); 404 | parsed.should.have.property('name', 'index'); 405 | parsed.should.have.property('stem', 'index'); 406 | parsed.should.have.property('dirname', 'foo/bar/baz'); 407 | parsed.should.have.property('dir', 'foo/bar/baz'); 408 | parsed.should.have.property('extname', ''); 409 | parsed.should.have.property('ext', ''); 410 | parsed.should.have.property('basename', 'index'); 411 | parsed.should.have.property('base', 'index'); 412 | parsed.should.have.property('root', ''); 413 | }); 414 | }); 415 | 416 | describe('when a dirname is "."', function() { 417 | it('should preserve the basename', function() { 418 | var parsed = parsePath('index.js'); 419 | parsed.should.have.property('dirname', ''); 420 | parsed.should.have.property('dir', ''); 421 | parsed.should.have.property('basename', 'index.js'); 422 | parsed.should.have.property('base', 'index.js'); 423 | parsed.should.have.property('name', 'index'); 424 | parsed.should.have.property('stem', 'index'); 425 | parsed.should.have.property('extname', '.js'); 426 | parsed.should.have.property('ext', '.js'); 427 | parsed.should.have.property('root', ''); 428 | }); 429 | 430 | it('should parse paths without extensions', function() { 431 | var parsed = parsePath('foo/bar/baz/index'); 432 | parsed.should.have.property('name', 'index'); 433 | parsed.should.have.property('stem', 'index'); 434 | parsed.should.have.property('dirname', 'foo/bar/baz'); 435 | parsed.should.have.property('dir', 'foo/bar/baz'); 436 | parsed.should.have.property('extname', ''); 437 | parsed.should.have.property('ext', ''); 438 | parsed.should.have.property('basename', 'index'); 439 | parsed.should.have.property('base', 'index'); 440 | parsed.should.have.property('root', ''); 441 | }); 442 | 443 | it('should return the extension from options.ext', function() { 444 | parsePath('foo/bar/baz.min.js').extname.should.eql('.js'); 445 | }); 446 | it('should parse the extname', function() { 447 | parsePath('foo/bar/baz.js').extname.should.eql('.js'); 448 | }); 449 | it('should return an empty extname when no extension is passed', function() { 450 | parsePath('foo/bar/baz').extname.should.eql(''); 451 | }); 452 | }); 453 | }); 454 | --------------------------------------------------------------------------------