mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-14 13:39:15 +03:00
testers.testEqualArrayOrMap: use buildCommandPath and change checkSetupScript argument to script
This commit is contained in:
parent
261693fe5d
commit
731b74db8b
7 changed files with 132 additions and 111 deletions
|
@ -351,7 +351,7 @@ testers.testEqualContents {
|
||||||
|
|
||||||
Check that bash arrays (including associative arrays, referred to as "maps") are populated correctly.
|
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 write unit tests for shell functions which transform arrays.
|
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}
|
:::{.example #ex-testEqualArrayOrMap-test-function-add-cowbell}
|
||||||
|
|
||||||
|
@ -369,7 +369,7 @@ testers.testEqualArrayOrMap {
|
||||||
"cowbell"
|
"cowbell"
|
||||||
"cowbell"
|
"cowbell"
|
||||||
];
|
];
|
||||||
checkSetupScript = ''
|
script = ''
|
||||||
addCowbell() {
|
addCowbell() {
|
||||||
local -rn arrayNameRef="$1"
|
local -rn arrayNameRef="$1"
|
||||||
arrayNameRef+=( "cowbell" )
|
arrayNameRef+=( "cowbell" )
|
||||||
|
@ -390,8 +390,8 @@ testers.testEqualArrayOrMap {
|
||||||
|
|
||||||
### Inputs {#tester-testEqualArrayOrMap-inputs}
|
### Inputs {#tester-testEqualArrayOrMap-inputs}
|
||||||
|
|
||||||
NOTE: Internally, this tester uses `__structuredAttrs` to handle marhsalling between Nix expressions and shell variables.
|
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-coercible.
|
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.
|
NOTE: At least one of `expectedArray` and `expectedMap` must be provided.
|
||||||
|
|
||||||
|
@ -399,39 +399,39 @@ NOTE: At least one of `expectedArray` and `expectedMap` must be provided.
|
||||||
|
|
||||||
: The name of the test.
|
: The name of the test.
|
||||||
|
|
||||||
`checkSetupScript` (string)
|
`script` (string)
|
||||||
|
|
||||||
: The singular task of `checkSetupScript` is to populate `actualArray` or `actualMap` (it may populate both).
|
: The singular task of `script` is to populate `actualArray` or `actualMap` (it may populate both).
|
||||||
To do this, checkSetupScript may access the following shell variables:
|
To do this, `script` may access the following shell variables:
|
||||||
|
|
||||||
- `valuesArray`
|
- `valuesArray` (available when `valuesArray` is provided to the tester)
|
||||||
- `valuesMap`
|
- `valuesMap` (available when `valuesMap` is provided to the tester)
|
||||||
- `actualArray`
|
- `actualArray` (available when `expectedArray` is provided to the tester)
|
||||||
- `actualMap`
|
- `actualMap` (available when `expectedMap` is provided to the tester)
|
||||||
|
|
||||||
While both `expectedArray` and `expectedMap` are in scope during the execution of `checkSetupScript`, they *must not* be accessed or modified from within `checkSetupScript`.
|
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)
|
`valuesArray` (array of string-like values, optional)
|
||||||
|
|
||||||
: An array of string-coercible values.
|
: An array of string-like values.
|
||||||
This array may be used within `checkSetupScript`.
|
This array may be used within `script`.
|
||||||
|
|
||||||
`valuesMap` (attribute set of string-like values, optional)
|
`valuesMap` (attribute set of string-like values, optional)
|
||||||
|
|
||||||
: An attribute set of string-coercible values.
|
: An attribute set of string-like values.
|
||||||
This attribute set may be used within `checkSetupScript`.
|
This attribute set may be used within `script`.
|
||||||
|
|
||||||
`expectedArray` (array of string-like values, optional)
|
`expectedArray` (array of string-like values, optional)
|
||||||
|
|
||||||
: An array of string-coercible values.
|
: An array of string-like values.
|
||||||
This array *must not* be accessed or modified from within `checkSetupScript`.
|
This array *must not* be accessed or modified from within `script`.
|
||||||
When provided, `checkSetupScript` is expected to populate `actualArray`.
|
When provided, `script` is expected to populate `actualArray`.
|
||||||
|
|
||||||
`expectedMap` (attribute set of string-like values, optional)
|
`expectedMap` (attribute set of string-like values, optional)
|
||||||
|
|
||||||
: An attribute set of string-coercible values.
|
: An attribute set of string-like values.
|
||||||
This attribute set *must not* be accessed or modified from within `checkSetupScript`.
|
This attribute set *must not* be accessed or modified from within `script`.
|
||||||
When provided, `checkSetupScript` is expected to populate `actualMap`.
|
When provided, `script` is expected to populate `actualMap`.
|
||||||
|
|
||||||
### Return value {#tester-testEqualArrayOrMap-return}
|
### Return value {#tester-testEqualArrayOrMap-return}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
# See https://nixos.org/manual/nixpkgs/unstable/#tester-testEqualArrayOrMap
|
# See https://nixos.org/manual/nixpkgs/unstable/#tester-testEqualArrayOrMap
|
||||||
# or doc/build-helpers/testers.chapter.md
|
# or doc/build-helpers/testers.chapter.md
|
||||||
# NOTE: Must be `import`-ed rather than `callPackage`-d to preserve the `override` attribute.
|
# NOTE: Must be `import`-ed rather than `callPackage`-d to preserve the `override` attribute.
|
||||||
testEqualArrayOrMap = import ./testEqualArrayOrMap/tester.nix { inherit lib runCommand; };
|
testEqualArrayOrMap = import ./testEqualArrayOrMap/tester.nix { inherit lib stdenvNoCC; };
|
||||||
|
|
||||||
# See https://nixos.org/manual/nixpkgs/unstable/#tester-testVersion
|
# See https://nixos.org/manual/nixpkgs/unstable/#tester-testVersion
|
||||||
# or doc/build-helpers/testers.chapter.md
|
# or doc/build-helpers/testers.chapter.md
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
# Tests if an array is declared.
|
||||||
|
isDeclaredArray() {
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
local -nr arrayRef="$1" && [[ ${!arrayRef@a} =~ a ]]
|
||||||
|
}
|
||||||
|
|
||||||
# Asserts that two arrays are equal, printing out differences if they are not.
|
# Asserts that two arrays are equal, printing out differences if they are not.
|
||||||
# Does not short circuit on the first difference.
|
# Does not short circuit on the first difference.
|
||||||
assertEqualArray() {
|
assertEqualArray() {
|
||||||
|
@ -12,13 +18,13 @@ assertEqualArray() {
|
||||||
local -nr expectedArrayRef="$1"
|
local -nr expectedArrayRef="$1"
|
||||||
local -nr actualArrayRef="$2"
|
local -nr actualArrayRef="$2"
|
||||||
|
|
||||||
if [[ ! ${expectedArrayRef@a} =~ a ]]; then
|
if ! isDeclaredArray expectedArrayRef; then
|
||||||
nixErrorLog "first arugment expectedArrayRef must be an array reference"
|
nixErrorLog "first arugment expectedArrayRef must be an array reference to a declared array"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! ${actualArrayRef@a} =~ a ]]; then
|
if ! isDeclaredArray actualArrayRef; then
|
||||||
nixErrorLog "second arugment actualArrayRef must be an array reference"
|
nixErrorLog "second arugment actualArrayRef must be an array reference to a declared array"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
# shellcheck shell=bash
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
# Tests if a map is declared.
|
||||||
|
isDeclaredMap() {
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
local -nr mapRef="$1" && [[ ${!mapRef@a} =~ A ]]
|
||||||
|
}
|
||||||
|
|
||||||
# Asserts that two maps are equal, printing out differences if they are not.
|
# Asserts that two maps are equal, printing out differences if they are not.
|
||||||
# Does not short circuit on the first difference.
|
# Does not short circuit on the first difference.
|
||||||
assertEqualMap() {
|
assertEqualMap() {
|
||||||
|
@ -12,13 +18,13 @@ assertEqualMap() {
|
||||||
local -nr expectedMapRef="$1"
|
local -nr expectedMapRef="$1"
|
||||||
local -nr actualMapRef="$2"
|
local -nr actualMapRef="$2"
|
||||||
|
|
||||||
if [[ ! ${expectedMapRef@a} =~ A ]]; then
|
if ! isDeclaredMap expectedMapRef; then
|
||||||
nixErrorLog "first arugment expectedMapRef must be an associative array reference"
|
nixErrorLog "first arugment expectedMapRef must be an associative array reference to a declared associative array"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! ${actualMapRef@a} =~ A ]]; then
|
if ! isDeclaredMap actualMapRef; then
|
||||||
nixErrorLog "second arugment actualMapRef must be an associative array reference"
|
nixErrorLog "second arugment actualMapRef must be an associative array reference to a declared associative array"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
# shellcheck shell=bash
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
preScript() {
|
||||||
|
# If neither expectedArray nor expectedMap are declared, the test is meaningless.
|
||||||
|
if ! isDeclaredArray expectedArray && ! isDeclaredMap expectedMap; then
|
||||||
|
nixErrorLog "neither expectedArray nor expectedMap were set, so test is meaningless!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if isDeclaredArray valuesArray; then
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
nixLog "using valuesArray: $(declare -p valuesArray)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if isDeclaredMap valuesMap; then
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
nixLog "using valuesMap: $(declare -p valuesMap)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if isDeclaredArray expectedArray; then
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
nixLog "using expectedArray: $(declare -p expectedArray)"
|
||||||
|
declare -ag actualArray=()
|
||||||
|
fi
|
||||||
|
|
||||||
|
if isDeclaredMap expectedMap; then
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
nixLog "using expectedMap: $(declare -p expectedMap)"
|
||||||
|
declare -Ag actualMap=()
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
scriptPhase() {
|
||||||
|
runHook preScript
|
||||||
|
|
||||||
|
runHook script
|
||||||
|
|
||||||
|
runHook postScript
|
||||||
|
}
|
||||||
|
|
||||||
|
postScript() {
|
||||||
|
if isDeclaredArray expectedArray; then
|
||||||
|
nixLog "using actualArray: $(declare -p actualArray)"
|
||||||
|
nixLog "comparing actualArray against expectedArray"
|
||||||
|
assertEqualArray expectedArray actualArray
|
||||||
|
nixLog "actualArray matches expectedArray"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if isDeclaredMap expectedMap; then
|
||||||
|
nixLog "using actualMap: $(declare -p actualMap)"
|
||||||
|
nixLog "comparing actualMap against expectedMap"
|
||||||
|
assertEqualMap expectedMap actualMap
|
||||||
|
nixLog "actualMap matches expectedMap"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
runHook scriptPhase
|
||||||
|
touch "${out:?}"
|
|
@ -3,12 +3,10 @@
|
||||||
# our negative tests will not work. See ./tests.nix for more information.
|
# our negative tests will not work. See ./tests.nix for more information.
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
runCommand,
|
stdenvNoCC,
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
inherit (lib) maintainers;
|
|
||||||
inherit (lib.customisation) makeOverridable;
|
inherit (lib.customisation) makeOverridable;
|
||||||
inherit (lib.strings) optionalString;
|
|
||||||
|
|
||||||
testEqualArrayOrMap =
|
testEqualArrayOrMap =
|
||||||
{
|
{
|
||||||
|
@ -17,76 +15,25 @@ let
|
||||||
valuesMap ? null,
|
valuesMap ? null,
|
||||||
expectedArray ? null,
|
expectedArray ? null,
|
||||||
expectedMap ? null,
|
expectedMap ? null,
|
||||||
checkSetupScript ? ''
|
script,
|
||||||
nixErrorLog "no checkSetupScript provided!"
|
|
||||||
exit 1
|
|
||||||
'',
|
|
||||||
}:
|
}:
|
||||||
runCommand name
|
stdenvNoCC.mkDerivation (finalAttrs: {
|
||||||
{
|
__structuredAttrs = true;
|
||||||
__structuredAttrs = true;
|
strictDeps = true;
|
||||||
strictDeps = true;
|
|
||||||
|
|
||||||
nativeBuildInputs = [
|
inherit name;
|
||||||
./assert-equal-array.sh
|
|
||||||
./assert-equal-map.sh
|
|
||||||
];
|
|
||||||
|
|
||||||
inherit valuesArray valuesMap;
|
nativeBuildInputs = [
|
||||||
inherit expectedArray expectedMap;
|
./assert-equal-array.sh
|
||||||
|
./assert-equal-map.sh
|
||||||
|
];
|
||||||
|
|
||||||
preCheckSetupScript =
|
inherit valuesArray valuesMap;
|
||||||
optionalString (expectedArray == null && expectedMap == null) ''
|
inherit expectedArray expectedMap;
|
||||||
nixErrorLog "neither expectedArray nor expectedMap were set, so test is meaningless!"
|
|
||||||
exit 1
|
|
||||||
''
|
|
||||||
+ optionalString (valuesArray != null) ''
|
|
||||||
nixLog "using valuesArray: $(declare -p valuesArray)"
|
|
||||||
''
|
|
||||||
+ optionalString (valuesMap != null) ''
|
|
||||||
nixLog "using valuesMap: $(declare -p valuesMap)"
|
|
||||||
''
|
|
||||||
+ optionalString (expectedArray != null) ''
|
|
||||||
nixLog "using expectedArray: $(declare -p expectedArray)"
|
|
||||||
declare -ag actualArray
|
|
||||||
''
|
|
||||||
+ optionalString (expectedMap != null) ''
|
|
||||||
nixLog "using expectedMap: $(declare -p expectedMap)"
|
|
||||||
declare -Ag actualMap
|
|
||||||
'';
|
|
||||||
|
|
||||||
# NOTE:
|
inherit script;
|
||||||
# The singular task of checkSetupScript is to populate actualArray or actualMap. To do this, checkSetupScript
|
|
||||||
# may access valuesArray, valuesMap, actualArray, and actualMap, but should *never* access or modify expectedArray,
|
|
||||||
# or expectedMap.
|
|
||||||
inherit checkSetupScript;
|
|
||||||
|
|
||||||
postCheckSetupScript =
|
buildCommandPath = ./build-command.sh;
|
||||||
optionalString (expectedArray != null) ''
|
});
|
||||||
nixLog "using actualArray: $(declare -p actualArray)"
|
|
||||||
nixLog "comparing actualArray against expectedArray"
|
|
||||||
assertEqualArray expectedArray actualArray
|
|
||||||
nixLog "actualArray matches expectedArray"
|
|
||||||
''
|
|
||||||
+ optionalString (expectedMap != null) ''
|
|
||||||
nixLog "using actualMap: $(declare -p actualMap)"
|
|
||||||
nixLog "comparing actualMap against expectedMap"
|
|
||||||
assertEqualMap expectedMap actualMap
|
|
||||||
nixLog "actualMap matches expectedMap"
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
''
|
|
||||||
nixLog "running preCheckSetupScript"
|
|
||||||
runHook preCheckSetupScript
|
|
||||||
|
|
||||||
nixLog "running checkSetupScript"
|
|
||||||
runHook checkSetupScript
|
|
||||||
|
|
||||||
nixLog "running postCheckSetupScript"
|
|
||||||
runHook postCheckSetupScript
|
|
||||||
|
|
||||||
nixLog "test passed"
|
|
||||||
touch "$out"
|
|
||||||
'';
|
|
||||||
in
|
in
|
||||||
makeOverridable testEqualArrayOrMap
|
makeOverridable testEqualArrayOrMap
|
||||||
|
|
|
@ -33,7 +33,7 @@ in
|
||||||
"cowbell"
|
"cowbell"
|
||||||
"cowbell"
|
"cowbell"
|
||||||
];
|
];
|
||||||
checkSetupScript = ''
|
script = ''
|
||||||
addCowbell() {
|
addCowbell() {
|
||||||
local -rn arrayNameRef="$1"
|
local -rn arrayNameRef="$1"
|
||||||
arrayNameRef+=( "cowbell" )
|
arrayNameRef+=( "cowbell" )
|
||||||
|
@ -61,7 +61,7 @@ in
|
||||||
"cat"
|
"cat"
|
||||||
"dog"
|
"dog"
|
||||||
];
|
];
|
||||||
checkSetupScript = ''
|
script = ''
|
||||||
${concatValuesArrayToActualArray}
|
${concatValuesArrayToActualArray}
|
||||||
actualArray+=( "dog" )
|
actualArray+=( "dog" )
|
||||||
'';
|
'';
|
||||||
|
@ -79,7 +79,7 @@ in
|
||||||
"bee"
|
"bee"
|
||||||
"cat"
|
"cat"
|
||||||
];
|
];
|
||||||
checkSetupScript = ''
|
script = ''
|
||||||
actualArray+=( "dog" )
|
actualArray+=( "dog" )
|
||||||
${concatValuesArrayToActualArray}
|
${concatValuesArrayToActualArray}
|
||||||
'';
|
'';
|
||||||
|
@ -92,7 +92,7 @@ in
|
||||||
"cat"
|
"cat"
|
||||||
];
|
];
|
||||||
expectedArray = [ ];
|
expectedArray = [ ];
|
||||||
checkSetupScript = ''
|
script = ''
|
||||||
# doing nothing
|
# doing nothing
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
@ -103,7 +103,7 @@ in
|
||||||
name = "${name}-failure";
|
name = "${name}-failure";
|
||||||
valuesArray = [ "apple" ];
|
valuesArray = [ "apple" ];
|
||||||
expectedArray = [ ];
|
expectedArray = [ ];
|
||||||
checkSetupScript = concatValuesArrayToActualArray;
|
script = concatValuesArrayToActualArray;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
runCommand name
|
runCommand name
|
||||||
|
@ -140,7 +140,7 @@ in
|
||||||
cat = "2";
|
cat = "2";
|
||||||
dog = "3";
|
dog = "3";
|
||||||
};
|
};
|
||||||
checkSetupScript = ''
|
script = ''
|
||||||
${concatValuesMapToActualMap}
|
${concatValuesMapToActualMap}
|
||||||
actualMap["dog"]="3"
|
actualMap["dog"]="3"
|
||||||
'';
|
'';
|
||||||
|
@ -158,7 +158,7 @@ in
|
||||||
cat = "2";
|
cat = "2";
|
||||||
dog = "3";
|
dog = "3";
|
||||||
};
|
};
|
||||||
checkSetupScript = ''
|
script = ''
|
||||||
${concatValuesMapToActualMap}
|
${concatValuesMapToActualMap}
|
||||||
unset 'actualMap[bee]'
|
unset 'actualMap[bee]'
|
||||||
'';
|
'';
|
||||||
|
@ -179,7 +179,7 @@ in
|
||||||
cat = "2";
|
cat = "2";
|
||||||
dog = "3";
|
dog = "3";
|
||||||
};
|
};
|
||||||
checkSetupScript = concatValuesMapToActualMap;
|
script = concatValuesMapToActualMap;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
runCommand name
|
runCommand name
|
||||||
|
@ -210,9 +210,7 @@ in
|
||||||
name = "${name}-failure";
|
name = "${name}-failure";
|
||||||
valuesArray = [ ];
|
valuesArray = [ ];
|
||||||
expectedMap.apple = 1;
|
expectedMap.apple = 1;
|
||||||
checkSetupScript = ''
|
script = "";
|
||||||
nixLog "doing nothing in checkSetupScript"
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
runCommand name
|
runCommand name
|
||||||
|
@ -252,7 +250,7 @@ in
|
||||||
bee = "1";
|
bee = "1";
|
||||||
dog = "3";
|
dog = "3";
|
||||||
};
|
};
|
||||||
checkSetupScript = concatValuesMapToActualMap;
|
script = concatValuesMapToActualMap;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
runCommand
|
runCommand
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue