aboutsummaryrefslogtreecommitdiffstats
path: root/tests/jq.sh
diff options
context:
space:
mode:
Diffstat (limited to 'tests/jq.sh')
-rwxr-xr-xtests/jq.sh122
1 files changed, 122 insertions, 0 deletions
diff --git a/tests/jq.sh b/tests/jq.sh
new file mode 100755
index 0000000..a62d6cb
--- /dev/null
+++ b/tests/jq.sh
@@ -0,0 +1,122 @@
+#! /bin/sh
+# Runs populate's jq programs for flakes over lock files in the shapes
+# different versions of Nix write, without VMs.
+#
+# usage: jq.sh DIR
+#
+# DIR contains the programs as selected.jq, selfIsRemote.jq, and
+# selfLocked.jq.
+set -efu
+
+programs=$1
+failed=0
+
+# usage: expect WHAT ACTUAL EXPECTED
+expect() {
+ if test "$2" != "$3"; then
+ printf 'FAIL: %s\n expected: %s\n got: %s\n' "$1" "$3" "$2" >&2
+ failed=1
+ fi
+}
+
+# usage: expect_error WHAT ACTUAL MESSAGE
+expect_error() {
+ case $2 in
+ *"$3"*) ;;
+ *)
+ printf 'FAIL: %s\n expected an error: %s\n got: %s\n' "$1" "$3" "$2" >&2
+ failed=1
+ ;;
+ esac
+}
+
+# usage: selection METADATA INPUT
+selection() {
+ printf '%s\n' "$1" |
+ timeout 10 jq -c --argjson input "$2" --from-file "$programs"/selected.jq 2>&1 ||
+ :
+}
+
+# A flake with an input dep, which has an input inner following the flake's
+# input inner, and an input sub, a flake in a subdirectory, written as
+# attribute dir or as query parameter dir of the URL.
+metadata() {
+ cat <<JSON
+{
+ "locked": { "type": "path", "path": "/src/top", "narHash": "sha256-top" },
+ "path": "/nix/store/top-source",
+ "locks": {
+ "root": "root",
+ "version": 7,
+ "nodes": {
+ "root": { "inputs": { "dep": "dep", "inner": "inner", "sub": "sub" } },
+ "dep": {
+ "inputs": { "inner": [ "inner" ] },
+ "locked": { "type": "tarball", "url": "http://x/dep.tar.gz", "narHash": "sha256-dep" }
+ },
+ "inner": {
+ "locked": { "type": "tarball", "url": "http://x/inner.tar.gz", "narHash": "sha256-inner" }
+ },
+ "sub": {
+ "locked": $1,
+ "original": $2
+ }
+ }
+ }
+}
+JSON
+}
+attribute=$(metadata \
+ '{ "type": "tarball", "url": "http://x/mono.tar.gz", "dir": "sub", "narHash": "sha256-mono" }' \
+ '{ "type": "tarball", "url": "http://x/mono.tar.gz", "dir": "sub" }')
+url=$(metadata \
+ '{ "type": "tarball", "url": "http://x/mono.tar.gz?dir=sub", "narHash": "sha256-mono" }' \
+ '{ "type": "tarball", "url": "http://x/mono.tar.gz?dir=sub" }')
+
+mono='{"self":false,"locked":{"type":"tarball","url":"http://x/mono.tar.gz","narHash":"sha256-mono"},"subdir":"sub"}'
+expect "subdirectory as attribute" "$(selection "$attribute" '["sub"]')" "$mono"
+expect "subdirectory in the URL" "$(selection "$url" '["sub"]')" "$mono"
+expect "the flake itself" "$(selection "$attribute" '[]')" \
+ '{"self":true,"locked":null,"subdir":""}'
+expect "name through follows" "$(selection "$attribute" '["dep","inner"]')" \
+ '{"self":false,"locked":{"type":"tarball","url":"http://x/inner.tar.gz","narHash":"sha256-inner"},"subdir":""}'
+expect_error "missing input" "$(selection "$attribute" '["nope"]')" "no input nope"
+
+# An empty follows path removes an input.
+removed=$(printf '%s\n' "$attribute" | jq -c '.locks.nodes.dep.inputs.inner = []')
+expect_error "removed input" "$(selection "$removed" '["dep","inner"]')" "no input inner"
+
+# Inputs following each other.
+cyclic=$(printf '%s\n' "$attribute" | jq -c '
+ .locks.nodes.dep.inputs.inner = ["inner", "x"]
+ | .locks.nodes.inner.inputs = { x: ["dep", "inner"] }
+')
+expect_error "cyclic follows" "$(selection "$cyclic" '["dep","inner"]')" "follows nest too deep"
+
+# An input given by a path relative to the flake, which is in subdirectory
+# sub itself.
+relative=$(printf '%s\n' "$attribute" | jq -c '
+ .locked.dir = "sub"
+ | .locks.nodes.root.inputs.lib = "lib"
+ | .locks.nodes.lib = { locked: { type: "path", path: "./lib" }, parent: [] }
+')
+expect "relative path" "$(selection "$relative" '["lib"]')" \
+ '{"self":true,"locked":null,"subdir":"sub/lib"}'
+
+# usage: remote LOCKED
+remote() {
+ printf '{ "locked": %s }\n' "$1" |
+ jq --from-file "$programs"/selfIsRemote.jq
+}
+expect "path" "$(remote '{ "type": "path", "path": "/src" }')" false
+expect "local Git" "$(remote '{ "type": "git", "url": "file:///src" }')" false
+expect "remote Git" "$(remote '{ "type": "git", "url": "https://x/y" }')" true
+expect "GitHub" "$(remote '{ "type": "github", "owner": "o", "repo": "r" }')" true
+
+expect "locked reference of the flake itself" "$(
+ printf '%s\n' '{ "locked": { "__final": true, "type": "tarball", "url": "http://x/mono.tar.gz?dir=sub", "narHash": "sha256-mono" } }' |
+ jq -c --argjson selected '{"self":true,"locked":null,"subdir":"sub"}' \
+ --from-file "$programs"/selfLocked.jq
+)" "$mono"
+
+exit "$failed"