Provider conformance
An adapter proves it implements InputProvider correctly by running inputProviderContractCases(), a suite shipped as data rather than as tests. Every adapter repository already has its own test runner, so the suite stays runner-free and each adapter iterates it with whichever one it uses.
Case shape
inputProviderContractCases() returns a readonly array of InputProviderContractCase objects, each with a name string and a run(provider, driver?) function. run throws an Error describing the failure on a broken provider and returns silently on a conforming one, so any test runner can host it as a single assertion.
for (const contractCase of inputProviderContractCases()) {
it(contractCase.name, () => contractCase.run(provider, driver));
}
The cases
- Capability keys.
getCapabilities()must return exactly the eleven keys the contract defines, no more and no fewer. - Well-formed snapshots.
sample()must return an array, and every snapshot needs a non-emptyid, a knownkindandhandedness, andselect/squeezevalues in 0 to 1. - Declared capabilities come with their methods. If
capabilities.hapticsis true,pulse()must exist; ifcapabilities.presenceis true, bothsetPresenceVisible()andsetPresenceModality()must exist. - A working presence pathway is declared. The converse of the case above: if
setPresenceVisible("none", true)reports presence is available,capabilities.presencemust be true andsetPresenceModality()must exist. The"none"target names no side, so this probe changes nothing and is safe to run against a live session. - Snapshot ownership. A snapshot must not change after the next
sample()call, which catches a provider that refills pooled objects in place instead of handing over fresh ones. See the input model for the ownership rule this enforces. - Unsubscribe works.
onCapabilitiesChanged()andonSourcesChanged()must each return a callableUnsubscribe. - A session cycle respects unsubscribe. A listener that has unsubscribed must not be called again across a session start and end.
Drivers
InputProviderContractDriver is an optional pair of hooks, enterSession() and exitSession(), that an adapter's test harness supplies when it can fake a session. The session-cycle case needs both hooks to run at all; without a driver, or with only one hook, that case passes without exercising anything. This is deliberate: a partial driver is always safe, and a case that cannot be faked never blocks conformance, it simply cannot check what it was written to check.
The worked example
Conformance in practice walks through a real test file that builds a provider and a driver, then runs every case against it.