Skip to content

Commit

Permalink
feat(lib): format
Browse files Browse the repository at this point in the history
Signed-off-by: Lexus Drumgold <[email protected]>
  • Loading branch information
unicornware committed Dec 9, 2022
1 parent e58f9e2 commit 56e3061
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/lib/__tests__/format.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* @file Unit Tests - format
* @module pathe/lib/tests/unit/format
* @see https://github.com/nodejs/node/blob/main/test/parallel/test-path-parse-format.js
*/

import sep from '#src/lib/sep'
import { posix, win32 } from 'node:path'
import testSubject from '../format'

describe('unit:lib/format', () => {
/**
* Converts Windows-style path separators (`\`) to POSIX (`/`).
*
* @param {string} path - Path to normalize
* @return {string} `path` normalized
*/
const ensurePosix = (path: string): string => path.replace(/\\/g, sep)

it('should return path string from object', () => {
// Arrange
const cases: Parameters<typeof testSubject>[] = [
[{}],
[{ root: '/' }],
[{ dir: 'some/dir' }],
[{ base: 'index.html' }],
[{ ext: '.png', name: 'x' }],
[{ ext: '.html', name: 'index' }],
[{ ext: '.html', name: 'index', root: '/' }],
[{ dir: 'some/dir', ext: '.html', name: 'index' }]
]

// Act + Expect
cases.forEach(([pathObject]) => {
expect(testSubject(pathObject)).to.equal(posix.format(pathObject))
})
})

describe('windows', () => {
it('should return path string from object', () => {
// Arrange
const cases: Parameters<typeof testSubject>[] = [
[{}],
[{ root: 'C:\\' }],
[{ dir: 'some\\dir' }],
[{ base: 'index.html' }],
[{ ext: '.html', name: 'index' }],
[{ ext: '.html', name: 'index', root: 'C:\\' }],
[{ dir: 'some\\dir', ext: '.html', name: 'index' }]
]

// Act + Expect
cases.forEach(([object]) => {
expect(testSubject(object)).to.equal(ensurePosix(win32.format(object)))
})
})
})
})
56 changes: 56 additions & 0 deletions src/lib/format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* @file format
* @module pathe/lib/format
*/

import type { PathObject } from '#src/interfaces'
import ensurePosix from '#src/internal/ensure-posix'
import validateObject from '#src/internal/validate-object'
import formatExt from '#src/utils/format-ext'
import sep from './sep'

/**
* Returns a path string from an object.
*
* @param {PathObject} pathObject - Object to evaluate
* @param {string} [pathObject.base] - File name including extension (if any)
* @param {string} [pathObject.dir] - Directory name or full directory path
* @param {string} [pathObject.ext] - File extension (if any)
* @param {string} [pathObject.name] - File name without extension (if any)
* @param {string} [pathObject.root] - Root of path
* @return {string} Path string
* @throws {TypeError} If `pathObject` is not an object
*/
const format = (pathObject: PathObject): string => {
validateObject(pathObject, 'pathObject')

// ensure path components meet posix standards
pathObject.base && (pathObject.base = ensurePosix(pathObject.base))
pathObject.dir && (pathObject.dir = ensurePosix(pathObject.dir))
pathObject.ext && (pathObject.ext = ensurePosix(pathObject.ext))
pathObject.name && (pathObject.name = ensurePosix(pathObject.name))
pathObject.root && (pathObject.root = ensurePosix(pathObject.root))

/**
* File name including extension (if any).
*
* @const {string} base
*/
const base: string =
pathObject.base ?? `${pathObject.name ?? ''}${formatExt(pathObject.ext)}`

/**
* Directory name or full path.
*
* @const {string | undefined} dir
*/
const dir: string | undefined = pathObject.dir ?? pathObject.root

return !dir
? base
: dir === pathObject.root
? `${dir}${base}`
: `${dir}${sep}${base}`
}

export default format
1 change: 1 addition & 0 deletions src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export { default as basename } from './basename'
export { default as delimiter } from './delimiter'
export { default as dirname } from './dirname'
export { default as extname } from './extname'
export { default as format } from './format'
export { default as isAbsolute } from './is-absolute'
export { default as sep } from './sep'

0 comments on commit 56e3061

Please sign in to comment.