Skip to content

Commit

Permalink
add tests for bin
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs committed Jun 21, 2023
1 parent d64372e commit 2a4c3ea
Show file tree
Hide file tree
Showing 2 changed files with 229 additions and 0 deletions.
145 changes: 145 additions & 0 deletions tap-snapshots/test/bin.ts.test.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/* IMPORTANT
* This snapshot file is auto-generated, but designed for humans.
* It should be checked into source control and tracked carefully.
* Re-generate by setting TAP_SNAPSHOT=1 and running tests.
* Make sure to inspect the output below. Do not ignore changes!
*/
'use strict'
exports[`test/bin.ts TAP usage > -h shows usage 1`] = `
Object {
"args": Array [
"-h",
],
"code": 0,
"options": Object {},
"signal": null,
"stderr": "",
"stdout": String(
Usage:
glob [options] [<pattern> [<pattern> ...]]
Glob v10.2.7
Expand the positional glob expression arguments into any matching file system
paths found.
-c<command> --cmd=<command>
Run the command provided, passing the glob expression
matches as arguments.
-p<pattern> --default=<pattern>
If no positional arguments are provided, glob will use
this pattern
-A --all By default, the glob cli command will not expand any
arguments that are an exact match to a file on disk.
This prevents double-expanding, in case the shell
expands an argument whose filename is a glob
expression.
For example, if 'app/*.ts' would match 'app/[id].ts',
then on Windows powershell or cmd.exe, 'glob app/*.ts'
will expand to 'app/[id].ts', as expected. However, in
posix shells such as bash or zsh, the shell will first
expand 'app/*.ts' to a list of filenames. Then glob
will look for a file matching 'app/[id].ts' (ie,
'app/i.ts' or 'app/d.ts'), which is unexpected.
Setting '--all' prevents this behavior, causing glob to
treat ALL patterns as glob expressions to be expanded,
even if they are an exact match to a file on disk.
When setting this option, be sure to enquote arguments
so that the shell will not expand them prior to passing
them to the glob command process.
-a --absolute Expand to absolute paths
-d --dot-relative Prepend './' on relative matches
-m --mark Append a / on any directories matched
-x --posix Always resolve to posix style paths, using '/' as the
directory separator, even on Windows. Drive letter
absolute matches on Windows will be expanded to their
full resolved UNC maths, eg instead of 'C:\\\\foo\\\\bar', it
will expand to '//?/C:/foo/bar'.
-f --follow Follow symlinked directories when expanding '**'
-R --realpath Call 'fs.realpath' on all of the results. In the case
of an entry that cannot be resolved, the entry is
omitted. This incurs a slight performance penalty, of
course, because of the added system calls.
-s --stat Call 'fs.lstat' on all entries, whether required or not
to determine if it's a valid match.
-b --match-base Perform a basename-only match if the pattern does not
contain any slash characters. That is, '*.js' would be
treated as equivalent to '**/*.js', matching js files
in all directories.
--dot Allow patterns to match files/directories that start
with '.', even if the pattern does not start with '.'
--nobrace Do not expand {...} patterns
--nocase Perform a case-insensitive match. This defaults to
'true' on macOS and Windows platforms, and false on all
others.
Note: 'nocase' should only be explicitly set when it is
known that the filesystem's case sensitivity differs
from the platform default. If set 'true' on
case-insensitive file systems, then the walk may return
more or less results than expected.
--nodir Do not match directories, only files.
Note: to *only* match directories, append a '/' at the
end of the pattern.
--noext Do not expand extglob patterns, such as '+(a|b)'
--noglobstar Do not expand '**' against multiple path portions. Ie,
treat it as a normal '*' instead.
--windows-path-no-escape
Use '\\\\' as a path separator *only*, and *never* as an
escape character. If set, all '\\\\' characters are
replaced with '/' in the pattern.
-D<n> --max-depth=<n> Maximum depth to traverse from the current working
directory
-C<cwd> --cwd=<cwd> Current working directory to execute/match in
-r<root> --root=<root> A string path resolved against the 'cwd', which is used
as the starting point for absolute patterns that start
with '/' (but not drive letters or UNC paths on
Windows).
Note that this *doesn't* necessarily limit the walk to
the 'root' directory, and doesn't affect the cwd
starting point for non-absolute patterns. A pattern
containing '..' will still be able to traverse out of
the root directory, if it is not an actual root
directory on the filesystem, and any non-absolute
patterns will still be matched in the 'cwd'.
To start absolute and non-absolute patterns in the same
path, you can use '--root=' to set it to the empty
string. However, be aware that on Windows systems, a
pattern like 'x:/*' or '//host/share/*' will *always*
start in the 'x:/' or '//host/share/' directory,
regardless of the --root setting.
--platform=<platform> Defaults to the value of 'process.platform' if
available, or 'linux' if not. Setting --platform=win32
on non-Windows systems may cause strange behavior!
-i<ignore> --ignore=<ignore>
Glob patterns to ignore Can be set multiple times
-v --debug Output a huge amount of noisy debug information about
patterns as they are parsed and used to match files.
-h --help Show this usage information
),
}
`
84 changes: 84 additions & 0 deletions test/bin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { spawn, SpawnOptions } from 'child_process'
import t from 'tap'
import { sep } from 'path'
const bin = require.resolve('../dist/cjs/src/bin.js')

interface Result {
args: string[]
options: SpawnOptions
stdout: string
stderr: string
code: number | null
signal: NodeJS.Signals | null
}
const run = async (args: string[], options = {}) => {
const proc = spawn(
process.execPath,
['--enable-source-maps', bin, ...args],
options
)
const out: Buffer[] = []
const err: Buffer[] = []
proc.stdout.on('data', c => out.push(c))
proc.stderr.on('data', c => err.push(c))
return new Promise<Result>(res => {
proc.on('close', (code, signal) => {
res({
args,
options,
stdout: Buffer.concat(out).toString(),
stderr: Buffer.concat(err).toString(),
code,
signal,
})
})
})
}

t.test('usage', async t => {
t.matchSnapshot(await run(['-h']), '-h shows usage')
const res = await run([])
t.equal(res.code, 1, 'exit with code 1 when no args')
t.match(res.stderr, 'No patterns provided')
t.match(res.stderr, /-h --help +Show this usage information$/m)
const badp = await run(['--platform=glorb'])
t.equal(badp.code, 1, 'exit with code 1 on bad platform arg')
t.match(badp.stderr, 'Invalid value provided for --platform: "glorb"\n')
})

t.test('finds matches for a pattern', async t => {
const cwd = t.testdir({
a: {
'x.y': '',
'x.a': '',
b: {
'z.y': '',
'z.a': '',
},
},
})
const res = await run(['**/*.y'], { cwd })
t.match(res.stdout, `a${sep}x.y\n`)
t.match(res.stdout, `a${sep}b${sep}z.y\n`)

const c = `node -p "process.argv.map(s=>s.toUpperCase())"`
const cmd = await run(['**/*.y', '-c', c], { cwd })
t.match(cmd.stdout, `'a${sep}x.y'`.toUpperCase())
t.match(cmd.stdout, `'a${sep}b${sep}z.y'`.toUpperCase())
})

t.test('prioritizes exact match if exists, unless --all', async t => {
const cwd = t.testdir({
routes: {
'[id].tsx': '',
'i.tsx': '',
'd.tsx': '',
}
})
const res = await run(['routes/[id].tsx'], { cwd })
t.equal(res.stdout, 'routes/[id].tsx\n')

const all = await run(['routes/[id].tsx', '--all'], { cwd })
t.match(all.stdout, 'routes/i.tsx\n')
t.match(all.stdout, 'routes/d.tsx\n')
})

0 comments on commit 2a4c3ea

Please sign in to comment.