tasty-sugar-2.2.1.0: Tests defined by Search Using Golden Answer References
Safe HaskellSafe-Inferred
LanguageHaskell2010

Test.Tasty.Sugar.Ranged

Description

Provides the rangedParam and rangedParamAdjuster helper functions.

Synopsis

Documentation

rangedParam :: Enum a => Ord a => String -> (String -> Maybe a) -> (a -> a -> Bool) -> Maybe a -> CUBE -> [Sweets] -> [Sweets] Source #

Given a Parameter Name and a boolean that indicates valid/not-valid for a Parameter Value, update the expectations in the Sweets to treat the parameter as a ranged value.

[This is the pure internals version; the recommended usage is via the rangedParamAdjuster wrapper specification in the sweetAdjuster field of the CUBE structure.]

Normal sweets results expect a 1:1 match between parameter value and the expected file markup, but this function modifies the sweets results to accomodate a parameter range with range boundaries. For example, if the test might vary the output based on the version of clang used to compile the file, the CUBE might specify:

mkCUBE { rootName = "*.c"
       , expectedSuffix = "good"
       , validParams = [ ("clang-range", Just ["pre_clang11", "pre_clang13" ] ) ]
       ...
       }

Then if the following files were present:

foo.c
foo-pre_clang11.good
foo.good

Then a normal sweets response would include the expectations:

foo-pre_clang11.good ==> Explicit "pre_clang11"
foo.good             ==> Assumed  "pre_clang13"

The withSugarGroups callback would then be invoked with these two expectations. The callback might check the actual version of clang available to run in the environment. If it detected clang version 10 was available, the best file would be the foo-pre_clang11.good, even though the parameters didn't mention clang9 and the foo.good would be the usual match to pick when there was no explicit match.

To handle this case, the rangedParam function is used to filter the sweets, and is also given the version of clang locally available:

let rangedSweets = rangedParam "clang-range" extract (<=) (Just "9") sweets
    extract = readMaybe . drop (length "pre-clang")
withSugarGroups rangedSweets TT.testGroup $ \sweet instnum exp ->
  ... generate test ...

Where the above would result in a single call to the _generate test_ code with the foo-pre_clang11.good expectation. The extract function removes the numeric value from the parameter value, and the <= test checks to see if the version supplied is less than or equal to the extracted parameter value.

The > comparator could be used if the validParams values specified a lower limit instead of an upper limit, and the comparator and extractor can be extended to handle other ways of specifying ranges.

If the extract function returns Nothing, then the corresponding parameter value is not a ranged parameter value (there can be a mix of ranged values and non-ranged values), and the corresponding value(s) will be used whenever there is not a ranged match. As an example, if the validParams above was extended with a "recent-clang" value; for actual clang versions up through 12 one of the pre_clang values provides the ranged match, but for clang versions of 13 or later, there is no pre_clang match so recent-clang will be used. Providing a non-extractable parameter value is recommended as the default to select when no ranged value is applicable; the expected file does not need to have the same parameter value since a weak match (no parameter match) file will match with the Assumed value, which will be selected if no better ranged match is applicable.

rangedParamAdjuster :: Enum a => Ord a => MonadIO m => String -> (String -> Maybe a) -> (a -> a -> Bool) -> Maybe a -> CUBE -> [Sweets] -> m [Sweets] Source #

Given a Parameter Name and a boolean that indicates valid/not-valid for a Parameter Value, update the expectations in the Sweets to treat the parameter as a ranged value. This provides the functionality described by the rangedParam function and is intended for use via the sweetAdjuster field of the CUBE structure.