Releases: Reefact/just-dummies
Release list
cli-v1.1.0-beta.6
1.1.0-beta.6 — September 3, 2026
A composed parameter's generator call is now written the same way whatever, if anything, answers to its name — no more inspecting your compilation to decide.
🐛 Bug Fixes
- Composing a parameter through its type's own
AnyXgenerator no longer depends on what, if anything, exists under that name in your compilation.dumalways writesnew AnyOrderReference(), in the composed type's own namespace — never opening ausingfor a candidate it did not look up. A same-named type that cannot serve as a generator, two or more that could, and a real, unique, correctly-implemented one are all handled identically:dumwrites the call, and your own build resolves it.
xunit-v1.0.0-preview.2
1.0.0-preview.2 — September 2, 2026
A license change every consumer should read.
⚠️ Breaking changes
- JustDummies.Xunit is now licensed under PolyForm Internal Use 1.0.0, not Apache 2.0 — source-available, not open source. You may read, build, modify and run the adapter for your own or your company's internal business operations; you may not distribute the software. Versions already published on NuGet are untouched and keep the license they shipped with. Contributions are now governed by a Contributor Agreement.
lib-v1.0.0-preview.6
1.0.0-preview.6 — September 2, 2026
A license change every consumer should read, a nullable-widening generator, and a fairer draw for Half.
⚠️ Breaking changes
- JustDummies is now licensed under PolyForm Internal Use 1.0.0, not Apache 2.0 — source-available, not open source. You may read, build, modify and run the library (and its bundled analyzers) for your own or your company's internal business operations; you may not distribute the software. Versions already published on NuGet are untouched and keep the license they shipped with. Contributions are now governed by a Contributor Agreement.
✨ New
- New
generator.AsNullable()— widens a generator's type to nullable without ever drawing an absent value, the opposite of.OrNull(). It keeps the wrapped generator's known value count, soAny.SetOf(Any.Enum<T>().AsNullable())sizes correctly against the enum's members (ADR-0094).
🙌 Improvements
Any.Half()now draws uniformly over the values a half can actually represent, instead of over the reals and rounding — which produced almost nothing below 1. A seeded test drawing aHalfwill replay a different value than before (ADR-0091).
🐛 Bug Fixes
Any.Half()now states how many distinct values it holds, soAny.SetOf(Any.Half())beyond that count is refused instead of exhausting a redraw budget.JD016now proves several more small element domains exactly (Char,Byte/SByte,Int16/UInt16,Half, and an enum's distinct values), and counts a caller-suppliedAny.Char().OneOf(...)pool exactly.JD015now weighs a value set against every declared constraint together, so a chain refused only by the intersection of several constraints is reported.- An element generator that admits nothing now names its own emptying constraint, even inside a distinct collection like
Any.SetOf(...).
cli-v1.1.0-beta.5
1.1.0-beta.5 — September 2, 2026
A same-named type that could not actually serve as a generator was still being proposed as one — this closes that gap.
🐛 Bug Fixes
- A same-named type that is not usable as a generator —
static, missingIAny<T>,abstract, or missing a public parameterless constructor — is no longer proposed as a parameter'sAnyX. Composing through it collided with the real declaration and failed your build on whatever it actually was (CS0712for a static class, among others), under a recap that still claimedAnyXinferred it, often with nousingfor its namespace either. The parameter is now left open instead, exactly as if nothing answered to that name. - Where two or more types named
AnyXeach qualify as a parameter's generator,dumno longer picks one silently — it lists every one of them under the parameter'sTODO, the same discipline already held for a tied static factory.
cli-v1.1.0-beta.4
1.1.0-beta.4 — September 2, 2026
A license change every consumer should read, a composed parameter now drawn through its own generator, and a long list of guard-reading fixes — several of them closing the known limitations 1.1.0-beta.3 shipped with.
⚠️ Breaking changes
- JustDummies is now licensed under PolyForm Internal Use 1.0.0, not Apache 2.0 — source-available, not open source. You may read, build, modify and run the tool for your own or your company's internal business operations; you may not distribute the software. Versions already published on NuGet are untouched and keep the license they shipped with. Contributions are now governed by a Contributor Agreement.
- A composed parameter is now scaffolded as
new AnyOrderReference()— the generator its own type owns — instead of a recipe derived from its factory's guards and inlined at every call site. Where the target compilation does not carry that generator yet,CS0246at that line names what to scaffold (ADR-0089). - The call for a composed parameter now goes straight into the constructor's initializer, and any remaining factory method is renamed to what it returns —
AnyValidQuantity()rather thanQuantityFactory(). - A nullable value-type parameter is now scaffolded as
.AsNullable(), not.As(value => (T?)value)— needs aJustDummiesrelease carryingAsNullable()(ADR-0094); a project on an older package still gets the previous hop. - The
factoryprovenance word, andcandidateson a parameter, are gone from--format json— a parameter is never left open over an ambiguous factory anymore, so both always read empty.
🐛 Bug Fixes
- A type refused for being abstract or generic now says so (
TypeIsAbstract/TypeIsGeneric) instead of being reported as having no constructor, and the same refusal now also names the static-factory route where several eligible factories tie. - A guard written in a project on another target framework (a
netstandard2.0library under anet8.0test project, say) is read again instead of silently ignored. - A collection of interface-typed collections (
List<HashSet<T>>for aList<ISet<T>>parameter) no longer emits a file that fails to compile. - A
readonly structbehind a private constructor and a publicCreatenow scaffolds through its factory instead of a zero-initialized default. - Every spelling of the whitespace rejection now reads as
.NotBlank()instead of.NonEmpty()— needs the matchingJustDummiesrelease carryingNotBlank(). - A guard reached through a null-conditional receiver, a
throwinside aswitchassignment, or a guard-library call in return position or a local declaration's initializer is now markedunread guardsinstead of passed over in silence. - A guard a
: this(…)/: base(…)initializer, or a factory built over a guarded private constructor, merely delegates to is now folded onto the parameter that hands it there — closing several shapes 1.1.0-beta.3 read silently wrong or not at all. - A
paramshand-off in normal form is read again; only the expanded form is refused. - A null-forgiving hand-off (
value!) folds the guard instead of dropping it, read directly or through a delegated constructor. - A self-delegating
: this(…)initializer no longer overflows the stack. - A
.Count/.Lengthguard on a parameter that is neither a string nor a collection is now markedunread guardsinstead of read against the wrong family. - A guard a jump can skip from inside a
using,lockorcheckedblock is now markedunread guards, not only at the top of the body. - A distinct floor over
char,byte,sbyte,Int16/UInt16,Half, or an enum's domain is now markedunread guardspast what the element can actually produce, instead of written with confidence. - An enum with no declared member now leaves the parameter open instead of scaffolding a call the library itself refuses.
catalog-v1.0.0-preview.5
1.0.0-preview.5 — September 2, 2026
A license change every consumer should read.
⚠️ Breaking changes
- JustDummies.DiagnosticCatalog is now licensed under PolyForm Internal Use 1.0.0, not Apache 2.0 — source-available, not open source. You may read, build, modify and run the package for your own or your company's internal business operations; you may not distribute the software. Versions already published on NuGet are untouched and keep the license they shipped with. Contributions are now governed by a Contributor Agreement.
lib-v1.0.0-preview.5
1.0.0-preview.5 — August 25, 2026
A guard against blank strings, and four chain-ordering fixes so a specification reads the same regardless of the order it was written in.
✨ New
- New
NotBlank()onAny.String()— requires at least one non-whitespace character, the guardNonEmpty()alone never covered since an entirely-whitespace string is not empty (ADR-0088).
🐛 Bug Fixes
JD015now measures a string's length budget the way the generator actually lays it out, so a re-declared prefix or aNotBlank()filler position is no longer double-counted or missed.- An
Any.Enum<T>()pool emptied byExcept(...)now honoursAllowingCombinations()regardless of which call was written first. - A flag combination named in
OneOfis now accepted wherever it is written, with no need forAllowingCombinations()at all. - A distinct collection (
Any.SetOf(...)and similar) is now judged on the whole finished chain, soContaining,ContainingAnyand a finerDistinct(comparer)are honoured regardless of whereWithCountsits in the chain. JD030now counts every anchored literal (StartingWith,EndingWith,Containing) when it reports the interval a chain draws.
lib-v1.0.0-preview.4
1.0.0-preview.4 — August 24, 2026
A rename that reads better, and a size ceiling analyzer and library now agree on.
⚠️ Breaking changes
AnyCharandAnyStringrenameLowerCase()/UpperCase()toInLowerCase()/InUpperCase()— the bare names read like a state change, not a quality of the drawn value. No behaviour changes; only the two names do.
🐛 Bug Fixes
- JD014 now reports a size ceiling above the producible cap:
WithMaxLengthandWithMaxCountwere declared uncapped while the library caps them, so a call the analyzer blessed could be refused at run time with nothing between the two to say so.
cli-v1.1.0-beta.3
1.1.0-beta.3 — August 24, 2026
Guard reading gets wider and stricter at once — two named guard libraries and a factory-built type are read now, while three shapes where the tool was confidently wrong about a guard's reach are refused instead of guessed.
⚠️ Breaking changes
- A guard the tool cannot place above every write to its parameter, or cannot prove runs on every construction, is now marked
unread guards— so a scaffold that used to compile can block your build until you confirm the generator. It used to emit a constraint the real constructor does not hold, which is the worse of the two failures: the file compiled, the recap reported nothing worth looking at, and the draw threw inside the constructor much later.
✨ New
- The guard helpers of Ardalis.GuardClauses and CommunityToolkit.Diagnostics are read, in both their spellings —
Name = Guard.Against.NullOrWhiteSpace(name);no longer ends the scan before anything is read, so a constructor guarded in that style stops scaffolding neutral generators under a recap showing no doubt anywhere (ADR-0086). A recognised library's method outside the measured rows earnsunread guardsrather than silence. - A type with no accessible constructor now scaffolds through its own factory — the canonical validating value object, a private constructor behind a public
Create, hasGenerate()call the factory and its guards read like a constructor's, with the recap's signature line naming the call the emitted file makes (factory Email.Create(string)). An abstract type with a factory scaffolds too.
🐛 Bug Fixes
- A guard is no longer read as a bound on a value the constructor had already replaced, or never reached — a write to the parameter itself (
percent = 100 - percent), a: this(…)or: base(…)initializer that runs entire before the body, a loop,switch,usingorfinallywhose order the tool does not read, and areturnorgotoabove the guard. Each is now placed correctly or refused. - A sign guard on an unsigned parameter no longer loses its constraint —
if (size <= 0)on abyteor auintread as.Positive(), a member the unsigned generators do not carry, so it was dropped silently andAny.Byte()still drew0; it now reads as.NonZero(), which is the same constraint rather than a looser one. - The arithmetic
ArgumentOutOfRangeExceptionthrow helpers are read as guards instead of blocking the build —ThrowIfNegative,ThrowIfNegativeOrZero,ThrowIfZero,ThrowIfLessThan,ThrowIfGreaterThan,ThrowIfLessThanOrEqualandThrowIfGreaterThanOrEqualnow map to the same numeric rows a comparison already builds. - A guard followed by an
else, or anelse ifchain that throws throughout, is read rather than passed over — reading stops at the first branch that does not throw unconditionally, and that branch, with everything after it, is markedunread guards. - An enum exclusion guard is read as
AnyEnum<T>.DifferentFrom—if (status == Status.None) { throw … }, the commonest enum guard there is, used to read as.NonZero(), a memberAnyEnum<T>does not carry, and was dropped silently. - The recap no longer prints
guardfor a factory whose guards tightened nothing — the word is computed from the constraints that reach the emitted chain, on the factory path as on every other.
catalog-v1.0.0-preview.4
1.0.0-preview.4 — August 24, 2026
The catalogue catches up with the rule set JustDummies 1.0.0-preview.3 shipped: three rules join the constants, JD031, JD032 and JD033.
✨ New
JustDummiesRule.JD031— Two inclusive bounds the library also names as one range, categoryJustDummies.Constraints.JustDummiesRule.JD032— A bound declared twice, where only the tighter one survives, categoryJustDummies.Constraints.JustDummiesRule.JD033— An anchored literal the declared characters cannot draw, categoryJustDummies.Constraints.