From 7cb4fe396900ee4d2c831b405b9a405973d806a1 Mon Sep 17 00:00:00 2001 From: Steve Boyd Date: Thu, 15 Feb 2024 14:44:25 +1300 Subject: [PATCH] ENH Include filename of script in predictable_random_int() --- funcs_scripts.php | 17 ++++++++++++++--- tests/FuncsScriptsTest.php | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 tests/FuncsScriptsTest.php diff --git a/funcs_scripts.php b/funcs_scripts.php index eb25285..8aca416 100644 --- a/funcs_scripts.php +++ b/funcs_scripts.php @@ -309,15 +309,26 @@ function human_cron(string $cron): string } /** - * Creates a predicatable random int between 0 and $max based on the module name to be used with the % mod operator. + * Creates a predicatable random int between 0 and $max based on the module name and file name script + * is called with to be used with the % mod operator. * $offset variable will offset both the min (0) and $max. e.g. $offset of 1 with a max of 27 will return an int * between 1 and 28 - * Note that this will return the exact same value every time it is called for a given module. + * Note that this will return the exact same value every time it is called for a given filename in a given module */ function predictable_random_int($max, $offset = 0): int { global $MODULE_DIR; - $chars = str_split($MODULE_DIR); + $callingFile = debug_backtrace()[0]['file']; + // remove absolute path e.g. /home/myuser/... + $moduleStandardiserDir = basename(__DIR__); + $dirQuoted = preg_quote($moduleStandardiserDir); + // double $dirQuoted is for github actions CI where there which will have a directory strcture + // with /module-standardiser/module-standardiser/... + if (!preg_match("#/$dirQuoted/$dirQuoted/(.+)$#", $callingFile, $matches)) { + preg_match("#/$dirQuoted/(.+)$#", $callingFile, $matches); + } + $relativePath = $matches[1]; + $chars = str_split("$MODULE_DIR-$relativePath"); $codes = array_map(fn($c) => ord($c), $chars); mt_srand(array_sum($codes)); return mt_rand(0, $max) + $offset; diff --git a/tests/FuncsScriptsTest.php b/tests/FuncsScriptsTest.php new file mode 100644 index 0000000..641dd19 --- /dev/null +++ b/tests/FuncsScriptsTest.php @@ -0,0 +1,22 @@ +assertSame(0, predictable_random_int(15)); + $this->assertSame(25, predictable_random_int(30)); + $this->assertSame(45, predictable_random_int(30, 20)); + $MODULE_DIR = 'donuts'; + $this->assertSame(13, predictable_random_int(15)); + // use eval to simulate calling from a different file + // it will suffix "(19) : eval()'d code" to the calling file in debug_backtrace() + $ret = null; + eval('$ret = predictable_random_int(15);'); + $this->assertSame(2, $ret); + } +}