The test then becomes something like
Check.Sample(
Gen.Bool, Gen.Bool, Gen.Bool
(loggedIn, hasGreenHair, likesBananas) => {
var anyTrue = loggedIn | hasGreenHair | likesBananas;//the property to test
var messagePrinted = formatMessage(loggedIn, hasGreenHair, likesBananas);
Assert.Equal(anyTrue, messagePrinted);
}
);
This is obviously overkill for a test space of cardinality 8. But for complex cases this can provide better coverage of unexpected interactions than just stabbing a few positive and negative results.Another approach for this test would be to use a metamorphic property (also possible with CsCheck). You basically come up with a rule that says something like, "if a user is logged in, then it should not matter if they have green hair or if they are like bananas". Then just let the framework search for falsifiable cases.
A real-world example of this was when I designed a scheduling system that would compile a set of abstract rules down to concrete events. I used metamorphic testing to look for cases where "If I add a new rule to a calendar, the total observable complexity of the calendar should be greater than or equal to before" (the equal case is if the new rule was equivalent to an existing rule. This allowed me to ensure that the internal complexity wasn't dropping observable details.