blade('', ['p' => [10, 20, null, 40, 50]]);
// Zwei Züge: einer vor der Lücke, einer danach. Ein einziges `M` hieße,
// die Linie läuft durch.
expect(substr_count($view->__toString(), 'toBe(2);
});
it('draws one unbroken line when nothing is missing', function () {
// Die Gegenprobe: an sauberen Reihen — und das sind alle bisherigen
// Aufrufer — darf sich nichts ändern.
$view = $this->blade('', ['p' => [10, 20, 30, 40, 50]]);
expect(substr_count($view->__toString(), 'toBe(1);
});
it('keeps later points in place when an earlier one is missing', function () {
// Der eigentliche Schaden am Filtern: der letzte Punkt einer Stunde muss
// ganz rechts liegen, egal wie viele Messwerte dazwischen fehlen.
$withGap = $this->blade('', ['p' => [10, null, 30, 40, 50]])->__toString();
$without = $this->blade('', ['p' => [10, 20, 30, 40, 50]])->__toString();
expect($withGap)->toContain('96 ') // rechter Rand erreicht
->and($without)->toContain('96 ');
});
it('closes the filled area with a path a renderer can actually follow', function () {
// Beim Zerlegen in Züge ist der Flächenpfad kurz `… L` direkt vor einem `M`
// geworden — gültig sieht das aus, gezeichnet wird es nicht, und die
// Füllung verschwand still. Ein Blick auf die Seite hat es gezeigt, keine
// Meldung.
$view = $this->blade('', ['p' => [10, 20, null, 40, 50]])->__toString();
preg_match_all('/class="area"[^>]*\sd="([^"]+)"/', $view, $m);
expect($m[1])->toHaveCount(2);
foreach ($m[1] as $d) {
expect($d)->toStartWith('M')
->and($d)->not->toContain('LM') // ein Befehl direkt hinter einem anderen
->and($d)->toEndWith('Z');
}
});
it('draws nothing at all when every sample is missing', function () {
$view = $this->blade('', ['p' => [null, null]]);
expect($view->__toString())->not->toContain(' $n) {
if ($i % 2 === 1) {
$ys[] = (float) $n;
}
}
}
return $ys;
}
it('keeps a nearly idle host near the baseline instead of filling the box', function () {
$html = $this->blade('', ['p' => [0.1, 0.3, 0.2, 0.25]])->__toString();
// 30 ist die Grundlinie, 4 die Oberkante. Bei 0,2 % darf nichts hochspringen.
expect(max(sparkY($html)))->toBeGreaterThan(29.0)
->and(min(sparkY($html)))->toBeGreaterThan(29.0);
});
it('still uses the whole box when the load really does span it', function () {
$html = $this->blade('', ['p' => [0, 100]])->__toString();
expect(min(sparkY($html)))->toBe(4.0) // 100 % ganz oben
->and(max(sparkY($html)))->toBe(30.0); // 0 % auf der Grundlinie
});
it('draws a flat line at the bottom when nothing moved at all', function () {
// Die Netz-Kacheln eines ruhigen Hosts: lauter Nullen. Ohne verankerte
// Untergrenze wurde daraus eine Linie irgendwo in der Mitte.
$html = $this->blade('', ['p' => [0, 0, 0, 0]])->__toString();
expect(array_unique(sparkY($html)))->toBe([30.0]);
});
it('scales to the series itself when no bounds are given', function () {
// Die Gegenprobe: alle bisherigen Aufrufer geben keine Grenzen mit und
// dürfen sich nicht verändern.
$html = $this->blade('', ['p' => [10, 20]])->__toString();
expect(min(sparkY($html)))->toBe(4.0)
->and(max(sparkY($html)))->toBe(30.0);
});