summaryrefslogtreecommitdiffstats
path: root/lib/path/tests/prop.nix
blob: b4fa355e952507f323321fd722f418665e875a8d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# Given a list of path-like strings, check some properties of the path library
# using those paths and return a list of attribute sets of the following form:
#
#     { <string> = <lib.path.subpath.normalise string>; }
#
# If `normalise` fails to evaluate, the attribute value is set to `""`.
# If not, the resulting value is normalised again and an appropriate attribute set added to the output list.
{
  # The path to the nixpkgs lib to use
  libpath,
  # A flat directory containing files with randomly-generated
  # path-like values
  dir,
}:
let
  lib = import libpath;

  # read each file into a string
  strings = map (name: builtins.readFile (dir + "/${name}")) (
    builtins.attrNames (builtins.readDir dir)
  );

  inherit (lib.path.subpath) normalise isValid;
  inherit (lib.asserts) assertMsg;

  normaliseAndCheck =
    str:
    let
      originalValid = isValid str;

      tryOnce = builtins.tryEval (normalise str);
      tryTwice = builtins.tryEval (normalise tryOnce.value);

      absConcatOrig = /. + ("/" + str);
      absConcatNormalised = /. + ("/" + tryOnce.value);
    in
    # Check the lib.path.subpath.normalise property to only error on invalid subpaths
    assert assertMsg (
      originalValid -> tryOnce.success
    ) "Even though string \"${str}\" is valid as a subpath, the normalisation for it failed";
    assert assertMsg (
      !originalValid -> !tryOnce.success
    ) "Even though string \"${str}\" is invalid as a subpath, the normalisation for it succeeded";

    # Check normalisation idempotency
    assert assertMsg (
      originalValid -> tryTwice.success
    ) "For valid subpath \"${str}\", the normalisation \"${tryOnce.value}\" was not a valid subpath";
    assert assertMsg (originalValid -> tryOnce.value == tryTwice.value)
      "For valid subpath \"${str}\", normalising it once gives \"${tryOnce.value}\" but normalising it twice gives a different result: \"${tryTwice.value}\"";

    # Check that normalisation doesn't change a string when appended to an absolute Nix path value
    assert assertMsg (originalValid -> absConcatOrig == absConcatNormalised)
      "For valid subpath \"${str}\", appending to an absolute Nix path value gives \"${absConcatOrig}\", but appending the normalised result \"${tryOnce.value}\" gives a different value \"${absConcatNormalised}\"";

    # Return an empty string when failed
    if tryOnce.success then tryOnce.value else "";

in
lib.genAttrs strings normaliseAndCheck