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

tempestphp / tempest-framework / 14161923512

30 Mar 2025 01:41PM UTC coverage: 80.964% (+0.2%) from 80.716%
14161923512

push

github

web-flow
ci: prevent coveralls failures from failing tests (#1104)

11058 of 13658 relevant lines covered (80.96%)

100.68 hits per line

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

78.26
/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
use Tempest\Support\Str\ImmutableString;
12

13
use function Tempest\Support\str;
14

15
final class TextInputRenderer
16
{
17
    use RendersInput;
18

19
    private int $scrollOffset = 0;
20

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

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

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

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

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

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

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

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

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

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

93
        return $this->finishRender();
5✔
94
    }
95

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

100
        return new Point(
×
101
            x: $position->x + self::MARGIN_X + 1 + self::PADDING_X, // +1 is the border width
×
102
            y: ($position->y - $this->scrollOffset) + self::MARGIN_TOP + $this->offsetY, // subtract scroll offset
×
103
        );
×
104
    }
105
}
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