ClazzDevelopmentTest
I’ve defined a new test subassembly, ClazzDevelopmentTest, with three new test cases:
- ClazzDevelopmentLoadsTest: Validates that the clazzes that comprise the ClazzDevelopment subassembly are present and well-formed.
- BuildZeetixKernelTest: Validates that the clazzes that comprise a newly-formed instance of SystemConfiguration are properly built. The tests in AssemblySupportTest validate new SystemConfiguration instances — the tests in BuildZeetixKernelTest validate the machinery that builds them.
- BuildNewSubclazzTest: Validates that the environment can create properly-formed new subclazzes at runtime and install them into the running ecology. This machinery is used throughout the rest of the universe, and so its proper operation is crucial.
Refactored KernelTest hierarchy
Most of the tests in the KernelTest subassembly hierarchy need to validate Kernel clazzes for correctness. Since every Clazz is built to the same pattern, this validation code is common to all of them. Rather than copy the validation code among each TestCase descendant, I refactored the module hierarchy so that those tests inherit from an abstract “ClazzValidator” (itself a descendant of TestCase) that provides the validation behavior.
I’m aware that this might better be accomplished by applying the strategy pattern, relying on delegation instead of inheritance, but this works for now. It is “the simplest thing that can possibly work.”
This has two immediate benefits:
- The validation code is collected in one place (Once and Only Once).
- The SystemConfiguration clazz, created specially, is validated using the same test as all other kernel clazzes. This ensures that subsequent changes to clazz structure are correctly propagated to all clazzes
A “landmine” bug found and fixed
Part of the SystemConfiguration validation test is to verify that the size of the global namespace (“them”) is non-zero. As it turns out, the size reported by SystemDictionary (the clazz of “them”) is always zero. Ouch. The dictionary exists and is the correct size; it is the method that answers the size (“doSize”) for just this Collection descendant (SystemDictionary) that is broken — Set and SortedCollection work just fine.
This, again, is the sort of bug that is pernicious and hellishly difficult to track down. The instance works most of the time. Debuggers report its size correctly. When the bug causes a problem, the symptom is often far removed from the source — in both time and lexical space. The code that needs the size may likely be correct. The code that contains the bug ran a long time ago (at startup, in this case) and in a faraway place (in the Kernel.Core.CLDT subassembly).
I call a bug like this a “landmine” bug (not to be confused with another equally pernicious category, the “timebomb” bug). A landmine bug is a bug that makes a system work nearly all the time, until you step on the landmine. Then — “boom” — the landmine goes off, and the developer is left wondering “what happened?”
This means that the KernelTest.CLDTTest subassembly needs to include a test case that validates that each concrete descendant overrides doSize to answer the correct value (for that descendant, of course).
The more general learning is that we will need a way to specify, as part of an interface, that descendants of a clazz correctly implement the hooks required by that clazz. This, in turn, means that the universe needs a family of interface abstractions and an associated way to test them (see below).
I love unit tests.
KernelTest.CLDTTest subassembly
Validates the existence and correct behavior of the Kernel.CLDT (Common Language Data Types) clazzes. In this case, these are the clazzes that support collections with the Zeetix universe.
to do: Create a test case that validates that doSize is correctly implemented in each concrete Collection descendant.
InterfaceSupportTest and InterfaceSupport
Validates that the InterfaceSupport clazzes exist and operate correctly. When a resource, assembly, or feature claims compatibility with a specific interface, these tests validate that claim. When a resource, assembly, or feature claims to provide a specific existing existing or new interface, these tests validate that claim.