• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tempestphp / tempest-framework / 14049246919

24 Mar 2025 09:42PM UTC coverage: 79.353% (-0.04%) from 79.391%
14049246919

push

github

web-flow
feat(support): support array parameters in string manipulations (#1073)

48 of 48 new or added lines in 2 files covered. (100.0%)

735 existing lines in 126 files now uncovered.

10492 of 13222 relevant lines covered (79.35%)

90.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.78
/src/Tempest/Console/src/Components/Renderers/TextInputRenderer.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Tempest\Console\Components\Renderers;
6

7
use Tempest\Console\Components\ComponentState;
8
use Tempest\Console\Components\TextBuffer;
9
use Tempest\Console\Point;
10
use Tempest\Console\Terminal\Terminal;
11

12
use function Tempest\Support\str;
13

14
final class TextInputRenderer
15
{
16
    use RendersInput;
17

18
    private int $scrollOffset = 0;
19

20
    public function __construct(
59✔
21
        private ?bool $multiline = false,
22
        private int $maximumLines = 4,
23
    ) {}
59✔
24

25
    public function render(
5✔
26
        Terminal $terminal,
27
        ComponentState $state,
28
        TextBuffer $buffer,
29
        ?string $label,
30
        ?string $placeholder = null,
31
        ?string $hint = null,
32
    ): string {
33
        $this->prepareRender($terminal, $state);
5✔
34
        $this->label($label);
5✔
35

36
        if ($hint) {
5✔
UNCOV
37
            $this->offsetY++;
×
38
            $this->line($this->style('fg-gray', $hint))->newLine();
×
39
        }
40

41
        // splits the text to an array so we can work with individual lines
42
        $lines = str($buffer->text ?: ($placeholder ?: ''))
5✔
43
            ->explode("\n")
5✔
44
            ->flatMap(fn (string $line) => str($line)->chunk($this->maxLineCharacters)->toArray())
5✔
45
            ->map(static fn (string $line) => str($line)->replaceEnd("\n", ' '));
5✔
46

47
        // calculates scroll offset based on cursor position
48
        $this->scrollOffset = $this->calculateScrollOffset($lines, $this->maximumLines, $buffer->getRelativeCursorPosition($this->maxLineCharacters)->y);
5✔
49

50
        // slices lines to display only the visible portion
51
        $displayLines = $lines->slice($this->scrollOffset, $this->state->isFinished() ? 1 : $this->maximumLines);
5✔
52

53
        // if there is nothing to display after the component is done, show "no input"
54
        if ($this->state->isFinished() && $lines->count() === 0) {
5✔
UNCOV
55
            $this->line($this->style('italic dim', 'No input.'))->newLine();
×
56
        }
57

58
        // renders visible lines
59
        foreach ($displayLines as $line) {
5✔
60
            $this->line(
5✔
61
                // Add a symbol depending on the state
62
                match ($this->state) {
5✔
63
                    ComponentState::DONE => '<style="fg-green">✓</style> ',
5✔
64
                    default => '',
5✔
65
                },
5✔
66
                // Prints the actual line
67
                $this->style(
5✔
68
                    style: match (true) {
5✔
69
                        $this->state === ComponentState::DONE => 'dim',
5✔
70
                        $this->state === ComponentState::CANCELLED => 'italic dim strikethrough',
5✔
71
                        default => null,
5✔
72
                    },
5✔
73
                    content: $line,
5✔
74
                ),
5✔
75
                // Add an ellipsis if there is more than one line but we're done with the input
76
                $this->state->isFinished() && $this->multiline && $lines->count() > 1
5✔
UNCOV
77
                    ? '<style="dim">…</style>'
×
78
                    : '',
5✔
79
            )->newLine();
5✔
80
        }
81

82
        // fills remaining lines if less than max display lines
83
        if (! $this->state->isFinished()) {
5✔
84
            $lines = $this->multiline ? $this->maximumLines : 1;
5✔
85

86
            for ($i = $displayLines->count(); $i < $lines; $i++) {
5✔
87
                $this->line("\n");
2✔
88
            }
89
        }
90

91
        return $this->finishRender();
5✔
92
    }
93

UNCOV
94
    public function getCursorPosition(Terminal $terminal, TextBuffer $buffer): Point
×
95
    {
UNCOV
96
        $position = $buffer->getRelativeCursorPosition(((($terminal->width - self::MARGIN_X) - 1) - self::PADDING_X) - self::MARGIN_X);
×
97

UNCOV
98
        return new Point(
×
99
            x: $position->x + self::MARGIN_X + 1 + self::PADDING_X, // +1 is the border width
×
100
            y: ($position->y - $this->scrollOffset) + self::MARGIN_TOP + $this->offsetY, // subtract scroll offset
×
101
        );
×
102
    }
103
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc