-
-
Notifications
You must be signed in to change notification settings - Fork 269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plugin @tapjs/nock doesn't work in a NPM workspace #940
Comments
I also tried running
Note that my project is setup as an ESM project with |
Continuing my investigation, and it seems that there's probably an issue with @tapjs/nock as trying to load the |
(Just to be clear, we talking about
Ah, tap 18 does not work (at least, not with custom per-project plugins, not currently) as a global install. You have to install it locally as a dev dependency. When you add a plugin, the following happens:
When you have tap installed as a global, it's installing the Doing it this way ensures that I've thought a bit about some ways to be able to have a tap runner and tap install work if they're not the same install, or multiple versions of the built If the only reason for having a global I have this function in my .bashrc that I run as part of the array_contains_element () {
local e
local match="$1"
shift
for e; do [[ "$e" == "$match" ]] && return 0; done
return 1
}
array_uniq () {
local e
local u
u=()
for e; do
if ! array_contains_element "$e" "${u[@]}"; then
u+=("$e")
fi
done
echo "${u[*]}"
}
export NO_NPX_PATH=$PATH
set_npx_path () {
local p=$(pwd)
local ifs=$IFS
export IFS=:
local ogpath=($PATH)
local nm
nm=()
local d=$(dirname -- "$p")
while [ "$p" != "$d" ] && [ "$p" != "$HOME" ]; do
if [ -d "$p/node_modules" ] || [ -f "$p/package.json" ]; then
nm+=("$p/node_modules/.bin")
fi
p=$d
d=$(dirname -- "$p")
done
local newpath=(${nm[*]}:${NO_NPX_PATH[*]})
local newpathu=($(array_uniq "${newpath[@]}"))
export IFS=:
export PATH="${newpathu[*]}"
export IFS=$ifs
}
# you can run it on each prompt like this:
export PROMPT_COMMAND="set_npx_path; $PROMPT_COMMAND" If you use zsh or fish, I'm not sure if this would work, but probably something similar is possible. |
Yes it's nock 😉 I have installed locally, I only added a global install for my last tests to run the commands without npx and see if I had better success. |
Right, but that's what I'm saying, you can't add plugins if tap isn't found in the current project, or it'll try to add the plugin to itself in the global location, and fail to find it when it goes to run the build. One potential way to avoid the footgun, I suppose, is for the test runner to try to load itself from the cwd if it's not found there? That might work, but it might be a little bit clever? Anyway, this is what's happening:
But running the
|
This makes the tap runner load itself from the current project install if it's being run from somewhere else, so that plugins etc all work as expected and stay in sync. If that's not possible, and the user is attempting to run plugin commands using a tap executable from some other location, print a warning, and the command to try if it fails. Fix: #940
This makes the tap runner load itself from the current project install if it's being run from somewhere else, so that plugins etc all work as expected and stay in sync. If that's not possible, and the user is attempting to run plugin commands using a tap executable from some other location, print a warning, and the command to try if it fails. Fix: #940
Sorry if that wasn't clear (was pretty tired yesterday): Here's some traces, I removed the global tap install for clarity:
Doing that creates a Then I removed these and tried manually:
and added:
To my The plugin is recognized with
But when I run my tests, import { TapNock } from '@tapjs/nock';
...
t.test('testing', async (t) => {
const tn = new TapNock(t);
tn.nock.snapshot(); Throws an error "nock plugin is not loaded" I hope that's more clear. |
I made a minimal repo to reproduce the issue: https://github.com/sinedied/taptest
I'm now sure that the problem comes from the fact that it's in a NPM workspace:
|
Ah, I see. It's getting confused about where to run the install/build, I think. But shouldn't be too hard to work out. The issue that closed this was a legit bug/footgun, and I think related to this, but yes there's another thing as well. |
Ok, so here's what I'm finding, just capturing here for posterity:
diff --git a/package.json b/package.json
index a932f4d..0671fbb 100644
--- a/package.json
+++ b/package.json
@@ -5,5 +5,10 @@
"type": "module",
"workspaces": [
"packages/*"
- ]
+ ],
+ "tap": {
+ "plugin": [
+ "@tapjs/nock"
+ ]
+ }
} Since
Since
That way, it'll install in the workspace root when you |
Required for: tapjs/tapjs#940 Fix: #3
Need it to realpath symlinked packages, to address the plan in #940
Need it to realpath symlinked packages, to address the plan in #940
1. Detect if the tap in use is not built with the plugins listed in the config. If this is the case, run `build([], config)` prior to spawning test processes. 2. When executing npm install as part of `tap plugin add`, detect the appropriate place to do so, in this priority order: - the parent of the node_modules folder containing `tap` - the parent of the node_modules folder containing `@tapjs/test` - the output of `npm prefix` (ie, workspace root) - the root of the project (previous behavior) Adds `t.pluginSignature` getter which returns the built string signature which can be compared against the desired set captured by `config.pluginSignature`. Fix: #940
1. Detect if the tap in use is not built with the plugins listed in the config. If this is the case, run `build([], config)` prior to spawning test processes. 2. When executing npm install as part of `tap plugin add`, detect the appropriate place to do so, in this priority order: - the parent of the node_modules folder containing `tap` - the parent of the node_modules folder containing `@tapjs/test` - the output of `npm prefix` (ie, workspace root) - the root of the project (previous behavior) Adds `t.pluginSignature` getter which returns the built string signature which can be compared against the desired set captured by `config.pluginSignature`. Fix: #940
Thanks for your time detailing all your investigation and the fix, I didn't expect such a quick fix ❤️ I can confirm that it now works with the latest version! |
I'm working on a monorepo with a pretty standard NPM workspace setup (with my modules under packages/*).
When trying to use plugins, it doesn't seem to work. For example, running this from
/packages/my-server/
:will create a
/packages/my-server/package-lock.json
and fail with an error, whereas it should use the root lockfile (and modules instead).Manually adding the package with
npm i -D @tapjs/nock
properly adds it to the root/node_modules
folder, but if I add it to my .taprc file it's not used.Running
tap plugin list
from/packages/my-server/
shows@tapjs/nock
in the list, but trying to uset.nock.snapshot()
in a test result in an error telling thatt.nock
is undefined.Any idea how to solve this?
Thanks
The text was updated successfully, but these errors were encountered: