Qwiratry::Test

Reusable conformance ('contract') test kit for Qwiratry Format and Location plugins.

Qwiratry::Test

Reusable conformance ("contract") test kit for Qwiratry Format and Location plugins.

Instead of every plugin re-writing the same discovery / factory / round-trip / error-handling tests, a plugin depends on Qwiratry::Test at test time and calls one routine that runs the shared battery against its implementation. The plugin then only needs to add tests for behaviour that is genuinely specific to it.

Requirements

  • Rakudo with RakuAST (RAKUDO_RAKUAST=1), as required by Qwiratry itself.

  • Qwiratry (a runtime dependency of this kit).

Installation

zef install Qwiratry::Test

Usage

Add the kit to your plugin's META6.json as a test-phase dependency:

"depends": {
  "runtime": { "requires": [ "Qwiratry" ] },
  "test":    { "requires": [ "Qwiratry::Test" ] }
}

(The classic flat "test-depends": [ "Qwiratry::Test" ] array works too.)

Testing a format plugin

use Test;
use Qwiratry::Test::Format;

conforms-to-format-contract(
    format        => 'JSON',
    parse-samples => [ '{"b":2,"a":1}', '[1,2,3]' ],
    render-values => [ { :a(1), :b(2) }, [1, 2, 3] ],
    :lossless,
);

done-testing;

conforms-to-format-contract verifies:

  • the format is discoverable through Qwiratry::Format.formats;

  • the factory autoloads ::Parse / ::Render classes that inherit Qwiratry::Format::Base::Parse / ::Render;

  • parse yields defined data and render yields Str;

  • the lossless round-trip law parse ∘ render ∘ parse == parse (when :lossless);

  • the ↱ (parse) and ↓ (render) pipeline operators agree with direct calls;

  • invalid input is rejected (when :invalid-samples are supplied).

Everything except :format is optional and capability-driven — pass only the samples and flags that apply to your format. :parse/:render (default both) and :pipeline (default on) let you narrow the surface.

Testing a location plugin

use Test;
use Qwiratry::Test::Location;

conforms-to-location-contract(
    backend            => 'HTTP',
    scheme             => 'https',
    sample-location    => 'https://example.test/data',
    :!writable,          # a GET-only backend skips write/round-trip checks
    :needs-network,      # gate live checks behind QWIRATRY_TEST_NETWORK
);

done-testing;

conforms-to-location-contract verifies:

  • the backend is discoverable through Qwiratry::Location.backends;

  • the factory autoloads ::Source / ::Destination classes that inherit Qwiratry::Location::Base::Source / ::Destination;

  • the URI scheme resolves to the backend (when :scheme is supplied);

  • write-then-read round-trips, directly and through the ā®· / ⮳ operators (when both :writable and :readable and a :roundtrip-location are given);

  • a missing location raises X::Qwiratry::IO::LocationError (when :missing-location is supplied).

Use :needs-network for backends that reach the outside world; those subtests are skipped unless QWIRATRY_TEST_NETWORK is set, so plugin CI stays hermetic by default.

How the kit tests itself

To avoid a circular dependency, the base Qwiratry distribution does not depend on this kit. Instead, Qwiratry::Test depends on Qwiratry and its own test suite runs the kit against Qwiratry's bundled reference implementations — the File location backend and the JSONdemo format — so the contract battery is validated end to end. See t/.

Versioning

The kit's assertions are effectively part of Qwiratry's plugin API. Tightening a check is a semver-relevant change, so plugins should pin a minimum version, e.g. "Qwiratry::Test:ver<0.0.1+>".

License

Licensed under the same terms as Raku itself.

Author

Tim Nelson (wayland at wayland dot id dot au)

Qwiratry::Test v0.0.1

Reusable conformance ('contract') test kit for Qwiratry Format and Location plugins.

Authors

  • Tim Nelson

License

Dependencies

Test Dependencies

Provides

  • Qwiratry::Test::Format
  • Qwiratry::Test::Location

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.