indexnowkit/testing
Testing helpers for IndexNowKit: fake IndexNow submissions, assert which URLs were sent, and inspect requests without hitting live search engine endpoints, so your test suite stays fast, deterministic, and offline.
This release is entirely additive on the testing/conformance side — no runtime API changes, no deprecations. If you already use the package in an app, nothing to migrate; just be aware of the new indexnowkit/core ^0.13 floor.
Start here, in this order:
composer require indexnowkit/core (plus your framework adapter). The core is a library, not a Laravel service provider — the Laravel adapter is what you actually boot.ReadmeAssertions::FAMILY_COMMANDS — the canonical command registry across adapters. It now knows indexnow:submit-record (Yii3). This is the fastest place to discover the console surface before reading the Laravel adapter's source, and it tells you which command names are considered stable API across the family.tests/ directory — it delegates to Conformance\Arrays::merge for its fixtures, so reading it shows you the intended option shapes for the runtime and the expected check output.Conformance\OptionalPackageAssertions — the reference for how optional integrations (sitemap, verify, history) are supposed to degrade when absent.First use case: a URL submission on model save, queued rather than inline, with a record written for later reconciliation. The conformance suite defines what "correct" looks like for that flow; mirror it in your own app tests instead of inventing assertions.
Merge options in tests, don't hand-roll. Conformance\Arrays::merge($base, $overrides) is now the single implementation of the fixture-merge semantics the Laravel, Yii2 and Yii3 suites each carried separately. Rules: a nested associative block merges key by key; a list, an empty array, or a scalar replaces. Use it for Pest/PHPUnit datasets where you want a sane default config with one key overridden per case.
Test the absent-dependency path for real. OptionalPackageAssertions::assertDetected($checkOutput) works with predicates left to detection (installed: null) — the check output then names exactly the optional packages that are physically missing and none of the present ones. The trap the release calls out explicitly: passing installed: false with the packages still installed proves the text, not the boot. For genuine coverage, run a CI job that composer removes sitemap, verify and history before the detection test, exporting INDEXNOWKIT_OPTIONAL_PACKAGES=absent so absence becomes an assertion rather than an assumption.
Adopting a new adapter? ConformanceIdsTest now discovers adapters off the filesystem — any packages/* that requires indexnowkit/core and has a tests/ directory gets picked up automatically (minus the libraries), with a floor assertion that at least four were found. A new adapter must bring H01–H06 conformance tests the day it lands; there is no opt-out list to sneak onto.
Extension points. The detection predicates are the intended seam — supply your own when your app's optional integration isn't one of the three bundled ones, and keep the assertion output shaped like check's so the conformance helper stays usable.
^0.13 core constraint is lockstep. If you pin core below 0.13 you cannot take this release. Bump core and the adapter together; the adapter releases are built against the conformance suite, and a mismatched pair will fail ConformanceIdsTest locally even though the runtime works.Arrays::merge is not array_replace_recursive. An empty array replaces rather than merging, and lists replace wholesale. If you're porting fixtures that relied on deep-recursive behaviour, the merged result will look subtly wrong (a config key silently emptied) rather than throwing.false and tell you nothing about the boot path.packages/bitrix (next up) fails CI until H01–H06 exist — good — but it also means a stray packages/ directory with a tests/ folder and a core dependency will be pulled into the run and fail loudly. If you vendor or mirror the monorepo layout, expect that.check command is the source of truth. If assertDetected fails, diff the actual check output against what you expect — the failure is usually a package that's present but not wired into detection, not a wrong predicate.How can I help you explore Laravel packages today?