Lines 90.90% 10 / 11
Functions and Methods 87.50% 7 / 8
Classes and Traits 0.00% 0 / 1
Name Lines Functions and Methods CRAP Classes and Traits
RecordingExposure 90.90% 10 / 11 87.50% 7 / 8 9.06 0.00% 0 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 getKey 100.00% 1 / 1 100.00% 1 / 1 1
 cancelCommandSubscriptions 0.00% 0 / 1 0.00% 0 / 1 2
 remove 100.00% 2 / 2 100.00% 1 / 1 1
 recordConfig 100.00% 2 / 2 100.00% 1 / 1 1
 watchPushedCommands 100.00% 1 / 1 100.00% 1 / 1 1
 deliverCommand 100.00% 1 / 1 100.00% 1 / 1 1
 assertNotRemoved 100.00% 2 / 2 100.00% 1 / 1 2
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Testing\Exposure;
6
7use Stewart\Contracts\EventStream;
8use Stewart\Contracts\Exception\CommandException;
9use Stewart\Contracts\Exception\ExposureException;
10use Stewart\Contracts\Exposure\Command\ExposedCommand;
11use Stewart\Contracts\Exposure\ExposedEntityKey;
12use Stewart\Contracts\Exposure\ExposureConfig;
13use Stewart\Support\Stream\OperatorStream;
14use Stewart\Testing\Stream\PushSource;
15use Stewart\Testing\Time\ManualTimers;
16
17/** @template TConfig of ExposureConfig */
18abstract class RecordingExposure
19{
20    public private(set) bool $removed = false;
21
22    /** @var PushSource<ExposedCommand> */
23    private readonly PushSource $commands;
24
25    /** @param TConfig $config */
26    public function __construct(
27        private readonly ExposedEntityKey $key,
28        public private(set) ExposureConfig $config,
29        private readonly ManualTimers $timers,
30    ) {
31        $this->commands = new PushSource($timers->handlerFibers);
32    }
33
34    public function getKey(): ExposedEntityKey
35    {
36        return $this->key;
37    }
38
39    public function cancelCommandSubscriptions(): void
40    {
41        $this->commands->cancelAttachments();
42    }
43
44    public function remove(): void
45    {
46        $this->assertNotRemoved();
47        $this->removed = true;
48    }
49
50    /**
51     * @param TConfig $config
52     * @throws ExposureException
53     */
54    protected function recordConfig(ExposureConfig $config): void
55    {
56        $this->assertNotRemoved();
57        $this->config = $config;
58    }
59
60    /** @return EventStream<ExposedCommand> */
61    protected function watchPushedCommands(): EventStream
62    {
63        return new OperatorStream($this->commands, $this->timers);
64    }
65
66    /** @throws CommandException */
67    protected function deliverCommand(ExposedCommand $command): void
68    {
69        $this->commands->push($command);
70    }
71
72    /** @throws ExposureException */
73    protected function assertNotRemoved(): void
74    {
75        if ($this->removed) {
76            throw ExposureException::removed($this->key);
77        }
78    }
79}