Skip to content

Commit 6f05f9d

Browse files
committed
add more unit tests for catching invalid lockfiles early
1 parent fe14519 commit 6f05f9d

File tree

4 files changed

+78
-43
lines changed

4 files changed

+78
-43
lines changed

lib/internal/nodejsLockUtils.nix

+5-31
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99

1010
sanitizeLockfile = lock:
1111
# Every project MUST have a name
12-
assert lock ? name;
12+
if ! lock ? name then throw "Invalid lockfile: Every project MUST have a name" else
1313
# Every project MUST have a version
14-
assert lock ? version;
14+
if ! lock ? version then throw "Invalid lockfile: Every project MUST have a version" else
1515
# This lockfile module only supports lockfileVersion 2 and 3
16-
assert !lock ? lockfileVersion || lock.lockfileVersion >= 2;
16+
if ! lock ? lockfileVersion || lock.lockfileVersion <= 1 then throw "This lockfile module only supports lockfileVersion 2 and 3" else
1717
# The Lockfile must contain a 'packages' attribute.
18-
assert lock ? packages;
18+
if ! lock ? packages then throw "Invalid lockfile: The Lockfile must contain 'packages' attribute." else
1919
lock;
2020

2121
findEntry =
@@ -35,32 +35,6 @@
3535
then throw "${search} not found in package-lock.json."
3636
else findEntry packageLock (stripPath currentPath) search;
3737

38-
# Returns the names of all "bundledDependencies".
39-
# People depend on different types and different names. Unfortunatly those fields are not part of the offical npm documentation.
40-
# Which may also be the reason for the mess.
41-
#
42-
# TODO: define unit tests.
43-
# Adopted from https://github.com/aakropotkin/floco/blob/708c4ffa0c05033c29fe6886a238cb20c3ba3fb4/modules/plock/implementation.nix#L139
44-
#
45-
# getBundledDependencies :: Pent -> {}
46-
getBundledDependencies = pent: let
47-
# b :: bool | []
48-
b = pent.bundledDependencies or pent.bundleDependencies or [];
49-
in
50-
# The following asserts is the XOR logic.
51-
# "bundle" and "bundled" dependencies are both valid but invalid if both or none keys exist
52-
assert ( pent ? bundledDependencies ) ->
53-
( ! ( pent ? bundleDependencies ) );
54-
assert ( pent ? bundleDependencies ) ->
55-
( ! ( pent ? bundledDependencies ) );
56-
if b == [] then {} else
57-
if builtins.isList b then { bundledDependencies = b; } else
58-
if ! b then {} else {
59-
# b :: true
60-
bundledDependencies = builtins.attrNames (
61-
( pent.dependencies or {} ) // ( pent.requires or {} )
62-
);
63-
};
6438
in {
65-
inherit findEntry stripPath getBundledDependencies sanitizeLockfile;
39+
inherit findEntry stripPath sanitizeLockfile;
6640
}

modules/dream2nix/nodejs-package-lock-v3/default.nix

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
Pent :: {
2525
See: https://docs.npmjs.com/cli/v9/configuring-npm/package-lock-json#packages
2626
}
27+
> We should mention that docs are imcomplete on npmjs.com
2728
pent is one entry of 'packages'
2829
*/
2930
parseSource = pent:

tests/nix-unit/test_nodejs_lock_v3/default.nix

+7-9
Original file line numberDiff line numberDiff line change
@@ -297,18 +297,16 @@ in {
297297
imports = [
298298
dream2nix.modules.dream2nix.nodejs-package-lock-v3
299299
];
300-
nodejs-package-lock-v3.packageLock = lib.mkForce {
301-
# Example content of lockfile
302-
# "lockfileVersion" = 1;
303-
};
300+
nodejs-package-lock-v3.packageLock =
301+
lib.mkForce {
302+
};
304303
};
305304
config = evaled.config;
306305
in {
307-
expr = builtins.tryEval (config.nodejs-package-lock-v3.pdefs);
308-
expected = {
309-
success = false;
310-
value = false;
306+
expr = config.nodejs-package-lock-v3.pdefs;
307+
expectedError = {
308+
type = "ThrownError";
309+
msg = "Invalid lockfile";
311310
};
312311
};
313-
314312
}

tests/nix-unit/test_nodejs_lockutils/default.nix

+65-3
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@
7474
expr = path;
7575
expected = "node_modules/underscore";
7676
};
77-
78-
# test the lock
77+
78+
# test the lock
7979
test_nodejsLockUtils_lockfile_v3 = let
8080
plock = {
8181
name = "foo";
@@ -110,7 +110,69 @@
110110
};
111111
in {
112112
expr = nodejsLockUtils.sanitizeLockfile plock;
113-
expectedError = plock;
113+
expectedError = {
114+
type = "ThrownError";
115+
msg = "This lockfile module only supports lockfileVersion 2 and 3";
116+
};
114117
};
115118

119+
test_nodejsLockUtils_lockfile_missing_name = let
120+
plock = {
121+
# name = "foo";
122+
version = "1.0.0";
123+
lockfileVersion = 3;
124+
packages = {};
125+
};
126+
in {
127+
expr = nodejsLockUtils.sanitizeLockfile plock;
128+
expectedError = {
129+
type = "ThrownError";
130+
msg = "MUST have a name";
131+
};
132+
};
133+
134+
test_nodejsLockUtils_lockfile_missing_version = let
135+
plock = {
136+
name = "foo";
137+
# version = "1.0.0";
138+
lockfileVersion = 3;
139+
packages = {};
140+
};
141+
in {
142+
expr = nodejsLockUtils.sanitizeLockfile plock;
143+
expectedError = {
144+
type = "ThrownError";
145+
msg = "MUST have a version";
146+
};
147+
};
148+
149+
test_nodejsLockUtils_lockfile_missing_lockfileVersion = let
150+
plock = {
151+
name = "foo";
152+
version = "1.0.0";
153+
# lockfileVersion = 3;
154+
packages = {};
155+
};
156+
in {
157+
expr = nodejsLockUtils.sanitizeLockfile plock;
158+
expectedError = {
159+
type = "ThrownError";
160+
msg = "lockfileVersion";
161+
};
162+
};
163+
164+
test_nodejsLockUtils_lockfile_missing_packages = let
165+
plock = {
166+
name = "foo";
167+
version = "1.0.0";
168+
lockfileVersion = 3;
169+
# packages = {};
170+
};
171+
in {
172+
expr = nodejsLockUtils.sanitizeLockfile plock;
173+
expectedError = {
174+
type = "ThrownError";
175+
msg = "must contain 'packages'";
176+
};
177+
};
116178
}

0 commit comments

Comments
 (0)