Files
mesh-tools/node-tools/internal/npmlock/npmlock_test.go
T
jochen 52e275ad2f
mesh/merge-gate head 52e275ad2f3a merged into trunk 954e1a53eef9 — pass, with a note: builds mesh-tools (+39 dependent(s)) → ace, g14, novox, shanks; no bu…
mesh/repo-check head 52e275ad2f3a merged into trunk 954e1a53eef9 — pass: its merge-check.sh passed
mesh/delivery delivered
Bring node-tools' lock back in step with package.json, and fail the check when it falls behind (hq issue 624)
The lab installs node-tools with npm ci, which refuses a lock that no longer
describes package.json; the SDK's range and the toolchain's development
dependencies had moved in package.json alone, so every lab run stopped at
setup. The image's build runs npm install and never read the lock, so nothing
noticed.
2026-10-13 15:12:10 +02:00

76 lines
2.5 KiB
Go

package npmlock
import (
"os"
"path/filepath"
"strings"
"testing"
)
// TestNodeToolsLockIsInStepWithItsPackage: the lab installs node-tools with `npm ci`, which refuses a lock
// out of step with package.json, so a change to package.json without its lock fails here and not at a
// lab run's setup (novox/hq issue 624).
func TestNodeToolsLockIsInStepWithItsPackage(t *testing.T) {
out, err := Check(filepath.Join("..", ".."))
if err != nil {
t.Fatal(err)
}
if len(out) > 0 {
t.Fatalf("node-tools/package-lock.json is out of step with package.json; run `npm install --package-lock-only` in node-tools:\n%s", strings.Join(out, "\n"))
}
}
func TestALockBehindItsPackageIsNamed(t *testing.T) {
dir := t.TempDir()
write(t, dir, "package.json", `{"dependencies":{"@novox/mesh-sdk":"^0.1.6","nats":"^2.29.0"},"devDependencies":{"pg":"^8"}}`)
write(t, dir, "package-lock.json", `{"lockfileVersion":3,"packages":{
"":{"dependencies":{"@novox/mesh-sdk":"^0.1.0","nats":"^2.29.0","left":"^1"}},
"node_modules/@novox/mesh-sdk":{"version":"0.1.1"},
"node_modules/nats":{"version":"2.29.3"}}}`)
out, err := Check(dir)
if err != nil {
t.Fatal(err)
}
got := strings.Join(out, "\n")
for _, want := range []string{
`dependencies @novox/mesh-sdk is "^0.1.6" in package.json and "^0.1.0" in the lock`,
`dependencies left "^1" is in the lock and no longer in package.json`,
`devDependencies pg "^8" is in package.json and not in the lock`,
`devDependencies pg has no resolved package in the lock`,
} {
if !strings.Contains(got, want) {
t.Errorf("missing %q in:\n%s", want, got)
}
}
if len(out) != 4 {
t.Errorf("want 4 findings, got %d:\n%s", len(out), got)
}
}
func TestALockInStepIsQuiet(t *testing.T) {
dir := t.TempDir()
write(t, dir, "package.json", `{"dependencies":{"nats":"^2.29.0"}}`)
write(t, dir, "package-lock.json", `{"lockfileVersion":3,"packages":{"":{"dependencies":{"nats":"^2.29.0"}},"node_modules/nats":{"version":"2.29.3"}}}`)
out, err := Check(dir)
if err != nil || len(out) != 0 {
t.Fatalf("want quiet, got %v %v", out, err)
}
}
func TestAnOldLockfileVersionIsNamed(t *testing.T) {
dir := t.TempDir()
write(t, dir, "package.json", `{}`)
write(t, dir, "package-lock.json", `{"lockfileVersion":1,"dependencies":{}}`)
out, err := Check(dir)
if err != nil || len(out) != 1 {
t.Fatalf("want one finding, got %v %v", out, err)
}
}
func write(t *testing.T, dir, name, content string) {
t.Helper()
if err := os.WriteFile(filepath.Join(dir, name), []byte(content), 0o644); err != nil {
t.Fatal(err)
}
}