plesty.sdk.commands.mock_test

Generate a module’s mock pipeline test from what its device declares.

plesty init field-test asks six to eight questions because every one of them is a safety judgement about a real instrument that no schema inspection can make. This command asks nothing. Nothing here can move a stage or fire an exposure, and everything it needs is either declared by the device or settled by trying it:

  • the device’s doc_model() — the parameters and operations, read through the same reader the field test uses, so the two cannot disagree

  • the package name — the module, and the test file name

  • a construction probe — how to reach the device without one

The probe is the design. A device module is hardware-free in one of several ways: address="mock" selects an in-memory simulator in one reference module, use_mock_solver=True does it in the other. Which one applies is knowable by constructing the device and looking, so the strategies are tried in order and each is verified the way the gates will verify it — connect, read is_operatable, call identity() and check_errors(). A strategy is written into the file only once it has passed the checks the file will make, which is why a generated test that is written passes.

Where no strategy works the command refuses and says what it tried. It does not fall back to asking: a developer given a question the probe could not answer would be guessing at the same thing, and a file built on a guess is the failure this approach exists to avoid — it looks complete and tests less than it claims.

Attributes

_STRATEGIES

_DOC_DEVICE_NOTE

Classes

MockStrategy

How the generated test reaches the device without hardware.

MockTestScaffold

Build a module's mock pipeline test from its own declarations.

Functions

_never_ask(→ Any)

Refuse to prompt.

_accepted_kwargs(→ set[str])

Return the keyword arguments a device constructor accepts.

_verify(→ str | None)

Run the lifecycle, identity and error checks against a construction.

_needs_unique(→ str | None)

Return the keyword argument needing a fresh value per instance.

_import_block(→ str)

Return the import lines the generated file needs.

_device_block(→ str)

Return the device subclass the pipeline is given, when one is needed.

_pipeline_args(→ str)

Return the arguments of the DevicePipeline(...) call.

_asset(→ Any)

Return a packaged asset.

scaffold_mock_test(→ pathlib.Path)

Probe the module and write its mock pipeline test.

Module Contents

plesty.sdk.commands.mock_test._STRATEGIES: tuple[tuple[str, dict[str, Any], str], Ellipsis]
plesty.sdk.commands.mock_test._DOC_DEVICE_NOTE = 'The module exports ``DocDevice``, the pre-addressed hardware-free factory gate d3 requires, and...
class plesty.sdk.commands.mock_test.MockStrategy

How the generated test reaches the device without hardware.

Variables:
  • name – Short label, quoted when the command reports what it found.

  • factory – The exported name the file constructs — Device or DocDevice.

  • kwargs – Keyword arguments that make the construction hardware-free.

  • note – What this strategy is, for the generated file’s docstring.

  • unique_kwarg – A keyword argument needing a fresh value per instance, when constructing twice over otherwise fails. The gates construct repeatedly, and a module keying a registry on its address or host collides on the second one.

  • unwrap – DocDevice is partial(Device, ...) rather than a class. DevicePipeline constructs from a class and names it by __name__, which a partial has not, so the file passes Device and forwards the partial’s arguments — the same construction, read from DocDevice at run time so it cannot drift from it.

name: str
factory: str
kwargs: dict[str, Any]
note: str = ''
unique_kwarg: str | None = None
unwrap: bool = False
class plesty.sdk.commands.mock_test.MockTestScaffold(project_root: pathlib.Path)

Build a module’s mock pipeline test from its own declarations.

Parameters:

project_root (pathlib.Path) – Root directory of the device module.

Store the project root and the reader shared with the field test.

project_root
_reader
candidates() → plesty.sdk.commands.field_test.Candidates

Return what the device declares, read as the field test reads it.

Returns:

The module’s parameters, operations and package name.

Raises:

ScaffoldError – If the module cannot be imported or built doc-free.

Return type:

plesty.sdk.commands.field_test.Candidates

FILENAME = 'test_mock_pipeline.py'
MARKER = 'Generated by ``plesty init mock-test``'
filename(candidates: plesty.sdk.commands.field_test.Candidates) → str

Return the test file name.

Parameters:

candidates (plesty.sdk.commands.field_test.Candidates) – What the device declared; unused, kept so callers read the same way as the field-test scaffold.

Returns:

The bare file name.

Return type:

str

probe(candidates: plesty.sdk.commands.field_test.Candidates) → MockStrategy

Find a construction that connects, identifies and reports no errors.

Parameters:

candidates (plesty.sdk.commands.field_test.Candidates) – What the device declared.

Returns:

The first strategy that passed every check.

Raises:

ScaffoldError – If none did, listing what was tried and why each failed.

Return type:

MockStrategy

_export(candidates: plesty.sdk.commands.field_test.Candidates, name: str, required: bool = True) → Any

Return a name exported by the module.

Parameters:
Returns:

The exported object, or None when absent and not required.

Raises:

ScaffoldError – If the name is required and the module has none.

Return type:

Any

render(candidates: plesty.sdk.commands.field_test.Candidates, strategy: MockStrategy) → str

Emit the test file.

Parameters:
Returns:

The file content.

Return type:

str

write(content: str, candidates: plesty.sdk.commands.field_test.Candidates, force: bool = False) → pathlib.Path

Write the test file.

Parameters:
Returns:

The path written.

Raises:

ScaffoldError – If the file exists and force is not set.

Return type:

pathlib.Path

plesty.sdk.commands.mock_test._never_ask(*args: Any, **kwargs: Any) → Any

Refuse to prompt.

The field-test scaffold takes an ask because its questions are the point of it. This command has none, and reaching a prompt would mean a code path assumed one.

Raises:

AssertionError – Always.

Parameters:
  • args (Any)

  • kwargs (Any)

Return type:

Any

plesty.sdk.commands.mock_test._accepted_kwargs(device_cls: Any) → set[str]

Return the keyword arguments a device constructor accepts.

Parameters:

device_cls (Any) – The device class.

Returns:

The accepted names. A constructor taking **kwargs accepts anything, which is reported as every candidate name so a strategy is tried rather than skipped.

Return type:

set[str]

plesty.sdk.commands.mock_test._verify(factory: Any, kwargs: dict[str, Any]) → str | None

Run the lifecycle, identity and error checks against a construction.

These are three of the eight gates. Verifying here is what makes a generated file that is written a generated file that passes.

Parameters:
  • factory (Any) – The device class or factory to call.

  • kwargs (dict[str, Any]) – Keyword arguments to call it with.

Returns:

None when every check passed, otherwise why it did not.

Return type:

str | None

plesty.sdk.commands.mock_test._needs_unique(device_cls: Any, kwargs: dict[str, Any], accepted: set[str]) → str | None

Return the keyword argument needing a fresh value per instance.

The gates construct the device several times over. A module keying its resource registry on the address or host collides on the second construction, which is why both reference modules hand-wrote a uniquifier. Rather than assume, this constructs twice and looks.

Parameters:
  • device_cls (Any) – The device class.

  • kwargs (dict[str, Any]) – The strategy’s keyword arguments.

  • accepted (set[str]) – The constructor’s accepted keyword names.

Returns:

The name to vary, or None when repeated construction is fine.

Return type:

str | None

plesty.sdk.commands.mock_test._import_block(candidates: plesty.sdk.commands.field_test.Candidates, strategy: MockStrategy) → str

Return the import lines the generated file needs.

Parameters:
Returns:

The import block.

Return type:

str

plesty.sdk.commands.mock_test._device_block(candidates: plesty.sdk.commands.field_test.Candidates, strategy: MockStrategy) → str

Return the device subclass the pipeline is given, when one is needed.

Parameters:
Returns:

The block, empty when the exported factory can be used as it stands.

Return type:

str

plesty.sdk.commands.mock_test._pipeline_args(candidates: plesty.sdk.commands.field_test.Candidates, strategy: MockStrategy) → str

Return the arguments of the DevicePipeline(...) call.

Parameters:
Returns:

The argument text, on one line.

Return type:

str

plesty.sdk.commands.mock_test._asset(name: str) → Any

Return a packaged asset.

Parameters:

name (str) – File name under plesty/sdk/assets/init.

Returns:

The traversable asset.

Return type:

Any

plesty.sdk.commands.mock_test.scaffold_mock_test(project_root: pathlib.Path, force: bool = False) → pathlib.Path

Probe the module and write its mock pipeline test.

Parameters:
  • project_root (pathlib.Path) – Root directory of the device module.

  • force (bool) – Replace an existing file.

Returns:

The path written.

Raises:

ScaffoldError – If the module cannot be read, or no hardware-free construction of it works.

Return type:

pathlib.Path