23

在我的package.json中,我有一个**/*Test.js用于匹配文件的脚本块。通过 运行时npm,它们与子目录的匹配不超过一级。当直接在命令行上执行时,它们按预期工作。

谁能解释发生了什么,并提供解决方法或解决方案?

package.json

{
  "name": "immutable-ts",
  "scripts": {
    "test": "echo mocha dist/**/*Test.js",
  }
}

执行

% npm run test

> immutable-ts@0.0.0 test:unit .../immutable-ts
> echo mocha dist/**/*Test.js

mocha dist/queue/QueueTest.js dist/stack/StackTest.js

% echo mocha dist/**/*Test.js

mocha dist/queue/QueueTest.js dist/stack/StackTest.js dist/tree/binary/BinaryTreeTest.js

% ls dist/**/*                                                                                                                                                                                          

dist/collections.js  dist/queue/QueueTest.js  dist/tree/binary/BinaryTree.js      dist/immutable.js.map        dist/stack/Stack.js.map             dist/tree/binary/BinaryTreeTest.js.map
dist/immutable.js    dist/stack/Stack.js      dist/tree/binary/BinaryTreeTest.js  dist/queue/Queue.js.map      dist/stack/StackTest.js.map
dist/queue/Queue.js  dist/stack/StackTest.js  dist/collections.js.map             dist/queue/QueueTest.js.map  dist/tree/binary/BinaryTree.js.map
4

3 回答 3

43

解决方案

更改您的脚本,以便您传递给 Mocha 的内容不会被 shell 扩展:

"scripts": {
    "test": "mocha 'dist/**/*Test.js'",
 }

请注意给定参数的单引号mocha

解释

无需借助外部工具即可解决此问题。您的问题的根本原因是通过npm用作sh将运行您的脚本命令的外壳。

绝大多数情况下,当 *nix 进程启动一个 shell 时,它会启动sh,除非有什么告诉它不这样做。您为登录设置的 shell 首选项并不构成“以其他方式告诉它”的方式。因此,如果您有,例如,zsh作为您的登录外壳,它并不意味着npm将使用zsh.

那些实现sh不包括超出sh应该提供的任何扩展,不会**以您想要的方式理解全局。据我所知,它被解释为*. 但是,Mocha 使用其 glob 的 JavaScript 实现来解释传递给它的路径。因此,您可以通过保护您的 glob 不被sh. 考虑以下内容package.json

{
  "name": "immutable-ts",
  "scripts": {
    "bad": "mocha test/**/*a.js",
    "good": "mocha 'test/**/*a.js'",
    "shell": "echo $0"
  }
}

shell脚本只是为了让我们可以检查哪个 shell 正在运行该脚本。如果你运行它,你应该会看到sh.

现在,给定以下树:

test/
├── a.js
├── b.js
├── x
│   ├── a
│   │   ├── a.js
│   │   └── b.js
│   ├── a.js
│   └── b
│       └── a.js
└── y
    ├── a.js
    └── q

包含所有a.jsb.js文件it(__filename);。您会得到以下结果:

$ npm run bad

> immutable-ts@ bad /tmp/t2
> mocha test/**/*a.js

  - /tmp/t2/test/x/a.js
  - /tmp/t2/test/y/a.js

  0 passing (6ms)
  2 pending

$ npm run good

> immutable-ts@ good /tmp/t2
> mocha 'test/**/*a.js'

  - /tmp/t2/test/a.js
  - /tmp/t2/test/x/a.js
  - /tmp/t2/test/x/a/a.js
  - /tmp/t2/test/x/b/a.js
  - /tmp/t2/test/y/a.js

  0 passing (5ms)
  5 pending
于 2015-12-30T12:19:18.470 回答
3

您可以将find命令与-name脚本中的选项内联,以替换 zsh 提供的扩展通配符语法。

在您的情况下,命令将是:

mocha `find dist -type f -name '*Test.js'`

-type f如果您确信永远不会将“Test.js”放在目录名称中,则实际上可以省略该部分。(很可能是一个安全的假设,但为了完整起见,我将其包括在内)

于 2015-12-30T04:18:28.417 回答
-1

glob 扩展实际上是由您的 shell 完成的,这就是它从命令行工作的原因。

你可以做mocha --recursive并指向你的测试目录。

于 2015-08-14T21:56:50.140 回答