Repository navigation
v3.2.0
What's Changed
Changed
-
Resizeris a service (#150) — registered asdrupal_kit.resizer, with the seven\Drupal::reaches replaced by injected dependencies.Resizer::resizer()stays as a thin static facade, so this is a MINOR and no consumer changes.#44 removed the service registration with the reason that "the class has no instance state". That stopped being true when the class grew a format-detection cache:
ResizerFocalPointKernelTest::setUp()reset$outputFormatand$formatCheckedby reflection, with a comment saying that without it "the getOutputFormat body inside this test class never runs". A test reaching into private static state to keep the next test honest was the evidence, sitting in the repository the whole time. Those nine lines are gone — a kernel test gets a fresh container, so the cache starts clean by construction.Measured before touching anything: nothing calls the static entry point. One caller inside the kit (
TwigExtension), zero PHP callers acrossdrupal-base,htdvereandproficio— all three reach it through the|resizerTwig filter. So the facade costs one delegation and keeps a promiseRELEASING.mdmakes.focal_point.manageris injected with@?and the hash helper now guards on having received the service rather than onmoduleExists(). The same correction #137 made inRequirements, for the same reason: one asks whether the container knows the module, the other whether this object holds the thing it is about to call.TwigExtensiontakes the service as a trailing optional constructor argument, whichRELEASING.md§ Public API surface classifies as MINOR.getResizer()also stops being declaredstatic— it was registered as[$this, 'getResizer'], so PHP was already calling it on an instance and the declaration simply disagreed with the call site.Two behaviour changes on the facade, worth stating plainly. It fetches the service before the input guards run, so
Resizer::resizer([], [])now needs a container where it used to answer without one. And it needs this module installed: the old body reached only core services, so the class worked in any container where it autoloaded — a kernel test listing justsystem,fileandimage, for instance. An uninstalleddrupal_kitnow raisesServiceNotFoundException. Neither matters in production, where both hold by definition; the second was found by review, not by me.The unit tests build the service instead of calling the facade, which is what a unit test should have been doing anyway.
TwigExtensionTestnow asserts delegation. The old case passed an SVG and checked the single-item list came back unchanged, which exercisedResizer's passthrough and said nothing aboutTwigExtension: a method that ignored its arguments and returned the input would have passed too.
Added
-
DisplayBase::create()and the focal-point hash have tests (#148) — both were gaps the tracker did not record, and both were self-concealing.DisplayBasesat at 13% line coverage while__callhad fourteen cases. The uncovered half was the constructor andcreate(), andDisplayBaseKernelTesthid it: it builds its subject withnew class(...), listing the same thirteen arguments in the same ordercreate()does, so the test carried its own copy of the ordering it was meant to protect. Reorderingcreate()left it green.The ordering matters because
$entity_helperis untyped — the type lives only in the docblock. Swapping two typed services is aTypeError; swapping that one is silent, and the class asks the wrong service for the rest of its life.DisplayBaseis a base class consumers extend, so the failure would surface in their project, not here. Mutation-checked:current_route_match↔language_manageris caught by PHP itself,drupal_kit.entity_helper→drupal_kit.media_array_builderonly by the new test.ResizerFocalPointKernelTestcarried a docblock saying the non-empty-hash branch was "left as a follow-up". It is followed up. The hash is the cache-busting mechanism: Drupal keys a derivative by image style name, so without the suffix an editor who moves the focal point is served the old crop until someone flushes image styles — a silent regression that reads as a caching problem. The tests assert behaviour rather than recomputingmd5()against the implementation: no crop means no suffix, two positions give two ids, the same position gives the same id, all read off the generated URL rather than by reflecting into the private helper.
Pull Requests
- #149 — test: cover DisplayBase::create() and the focal-point hash
- #152 — refactor(resizer): make Resizer a service, keep the static as a facade
Full Changelog: v3.1.0...v3.2.0