JustDummies

Just dummies — but seriously powerful ones.

Documentation sections

JD016: CollectionConstraintsAdmitNoValue

PropertyValue
CategoryConstraints (JustDummies.Constraints)
Severity🟠 Warning
Enabled by defaultYes

The declared count constraints cannot all hold, or the chain asks for more distinct elements than its element generator can produce — the cardinality gate ADR-0004 opens in a new tab records.

Both throw at declaration time, so this rule turns an arrange-time red into a build-time red rather than closing a silent green. That is still worth it: the chain usually sits in an arrange helper several call frames away from the test that dies on it, where the message names two constraints the reader must then go hunting for.

Noncompliant

Any.ListOf(Any.Int32()).WithCount(0).NonEmpty()                  // fixed at 0, then required non-empty
Any.ListOf(Any.Int32()).WithMinCount(5).WithMaxCount(2)          // no count satisfies both
Any.ListOf(Any.Int32()).WithMaxCount(2).Containing(1).Containing(2).Containing(3)   // 3 items, 2 slots
Any.SetOf(Any.Boolean()).WithCount(5)                            // 5 distinct booleans do not exist
Any.ListOf(Any.Enum<Day>()).Distinct().WithCount(10)             // more than the enum has members
Any.SetOf(Any.Int16()).WithCount(70000)                          // only 65536 distinct Int16 values exist
Any.SetOf(Any.Char().OneOf('a', 'b')).WithCount(5)               // narrowed to 2 characters, not the ASCII 128

Compliant

Any.ListOf(Any.Int32()).WithCountBetween(2, 10)
Any.SetOf(Any.Boolean()).WithCount(2)
Any.ListOf(Any.Boolean()).WithCount(10)                          // no Distinct: repeats are fine
Any.SetOf(Any.Char().OneOf('a', 'b', 'c')).WithCount(3)          // fits the narrowed pool exactly

Which domains it can prove

The ones the compiler settles: Any.Boolean() (2); the small primitive rows — Any.Char() (128, the ASCII pool of ADR-0075 opens in a new tab), Any.Byte()/Any.SByte() (256), Any.Int16()/Any.UInt16() (65536), Any.Half() (63487 — the distinct finite halves, the two zeros counting as one because they compare equal); Any.Enum<T>() (its distinct declared values, not its declared names — an aliased member such as Grade { Low = 1, …, Min = 1 } still counts 3, not 5); and a OneOf/ElementOf pool of constants (its distinct count). Anything else is unprovable and reported as nothing — an unprovable domain must never be treated as a small one.

A pool narrowed with Any.Char().OneOf(...) is counted for what it actually declares rather than folded back to the 128-value default: the caller’s own pool can reach past ASCII on purpose, documented on the member itself, so Any.Char().OneOf('a', 'b') reads as 2, not 128.

AllowingCombinations() is a case in point. It widens an enum’s universe to the OR-closure of its declared members — eight values for four flags — so counting declared members there would condemn a legal chain. The rule stands down instead of computing the closure: a deliberate false negative, found by dogfooding against AnyEnumCombinationTests, which asserts WithCount(8) succeeds.

What it does not flag

  • A count or element generator that is not a compile-time constant.
  • A chain split across statements — it must be one expression.
  • A conflict-asserting negative test, where the illegal chain is the whole body of a lambda argument.

Read the source, or correct it there opens in a new tab· Mirrored from lib-v1.0.0-preview.6