Home Explore Blog Models CI



nixpkgs

6th chunk of `doc/build-helpers/testers.chapter.md`
767def06b9490540e353a745e43848df1877d03a9cf2ab120000000100000fb7
    foo baz baz
  '';
  actual =
    runCommand "actual"
      {
        # not really necessary for a package that's in stdenv
        nativeBuildInputs = [ gnused ];
        base = writeText "base" ''
          foo bar baz
        '';
      }
      ''
        sed -e 's/bar/baz/g' $base >$out
      '';
  # if applicable
  postFailureMessage = ''
    The bar-baz replacer produced an unexpected result.
    If the new behavior is acceptable and validated against the bar-baz specification, run ./adopt-new-bar-baz-result.sh to adjust this test and require the new behavior.
  '';
}
```

:::

## `testEqualArrayOrMap` {#tester-testEqualArrayOrMap}

Check that bash arrays (including associative arrays, referred to as "maps") are populated correctly.

This can be used to ensure setup hooks are registered in a certain order, or to write unit tests for shell functions which transform arrays.

:::{.example #ex-testEqualArrayOrMap-test-function-add-cowbell}

# Test a function which appends a value to an array

```nix
testers.testEqualArrayOrMap {
  name = "test-function-add-cowbell";
  valuesArray = [
    "cowbell"
    "cowbell"
  ];
  expectedArray = [
    "cowbell"
    "cowbell"
    "cowbell"
  ];
  script = ''
    addCowbell() {
      local -rn arrayNameRef="$1"
      arrayNameRef+=( "cowbell" )
    }

    nixLog "appending all values in valuesArray to actualArray"
    for value in "''${valuesArray[@]}"; do
      actualArray+=( "$value" )
    done

    nixLog "applying addCowbell"
    addCowbell actualArray
  '';
}
```

:::

### Inputs {#tester-testEqualArrayOrMap-inputs}

NOTE: Internally, this tester uses `__structuredAttrs` to handle marshalling between Nix expressions and shell variables.
This imposes the restriction that arrays and "maps" have values which are string-like.

NOTE: At least one of `expectedArray` and `expectedMap` must be provided.

`name` (string)

: The name of the test.

`script` (string)

: The singular task of `script` is to populate `actualArray` or `actualMap` (it may populate both).
  To do this, `script` may access the following shell variables:

  - `valuesArray` (available when `valuesArray` is provided to the tester)
  - `valuesMap` (available when `valuesMap` is provided to the tester)
  - `actualArray` (available when `expectedArray` is provided to the tester)
  - `actualMap` (available when `expectedMap` is provided to the tester)

  While both `expectedArray` and `expectedMap` are in scope during the execution of `script`, they *must not* be accessed or modified from within `script`.

`valuesArray` (array of string-like values, optional)

: An array of string-like values.
  This array may be used within `script`.

`valuesMap` (attribute set of string-like values, optional)

: An attribute set of string-like values.
  This attribute set may be used within `script`.

`expectedArray` (array of string-like values, optional)

: An array of string-like values.
  This array *must not* be accessed or modified from within `script`.
  When provided, `script` is expected to populate `actualArray`.

`expectedMap` (attribute set of string-like values, optional)

: An attribute set of string-like values.
  This attribute set *must not* be accessed or modified from within `script`.
  When provided, `script` is expected to populate `actualMap`.

### Return value {#tester-testEqualArrayOrMap-return}

The tester produces an empty output and only succeeds when `expectedArray` and `expectedMap` match `actualArray` and `actualMap`, respectively, when non-null.
The build log will contain differences encountered.

## `testEqualDerivation` {#tester-testEqualDerivation}

Checks that two packages produce the exact same build instructions.

This can be used to make sure that a certain difference of configuration, such as the presence of an overlay does not cause a cache miss.

When the derivations are equal, the return value is an empty file.
Otherwise, the build log explains the difference via `nix-diff`.

:::{.example #ex-testEqualDerivation-hello}

Title: Nix Testers: `testEqualContents` (Example), `testEqualArrayOrMap`, and `testEqualDerivation`
Summary
This chunk first concludes an example for `testers.testEqualContents`, demonstrating how to compare the output of a `runCommand` with expected text and utilizing `postFailureMessage`. It then introduces `testers.testEqualArrayOrMap`, a utility for checking the correct population of bash arrays and associative arrays (maps). The `testEqualArrayOrMap` section includes an example of testing a function that appends values to an array, details its inputs (`name`, `script`, `valuesArray`, `valuesMap`, `expectedArray`, `expectedMap`), specifies restrictions (string-like values, `expected` variables not modifiable in `script`, at least one `expected` array/map required), and explains its return behavior. Finally, `testers.testEqualDerivation` is introduced as a tool to check if two packages produce identical build instructions, aiming to prevent unnecessary cache misses due to minor configuration changes.