433c53aabd
Die GM4000 liefert im Auslieferzustand keine Sekunden, sondern Zehntelminuten.
Bisher wurde daraus eine Sekundenanzeige gerechnet -- die sprang in
6-Sekunden-Schritten, weil die Rohdaten sie gar nicht hergeben. Die Zehntelform
ist ehrlicher und kuerzer, und der gewonnene Platz traegt die Beschriftung:
RA 18h36.9m
DE +38°47'
Bei Hochpraezision entfaellt die Beschriftung, dort braucht die Deklination mit
+38°47'01" alle Zellen.
Der Mock konnte das gar nicht nachstellen -- er sendete immer das
Hochpraezisionsformat. Neu: "mount_mock.py --low" bildet den Auslieferzustand ab
(RA als HH:MM.T, DEC ohne Bogensekunden). Vorgabe bleibt hoch, damit die
bestehenden Tests mit ihren festen Erwartungen unveraendert durchlaufen.
Zur Darstellung, alles am Geraet ausprobiert:
- **Schmale Zeichen** (config.CELL_NARROW): Dezimalpunkt und der Abstand
zwischen Beschriftung und Wert bekommen 3 statt 6 px -- in der Sperrschrift
standen sie sonst sehr luftig. Fuer die Leerzeichen am Zeilenende gilt das
nicht, die sollen den Rest der Zeile ueberschreiben.
- Damit entscheidet die **Pixelbreite** ueber das Abschneiden, nicht mehr die
Zeichenzahl: "RA 18h36.9m" sind 11 Zeichen und trotzdem nur 60 px.
- **Linksbuendig ab LINE_X = 0**, der Schalter zum Zentrieren ist entfallen.
Zentriert standen die Zeilen um wenige Pixel gegeneinander versetzt, weil die
RA-Zeile mit ihrem schmalen Punkt kuerzer ist als die DEC-Zeile.
Ein Zwischenschritt, der wieder verworfen wurde und als Warnung im Code steht:
Ein Doppelpunkt als Trenner ("RA:18h36.9m") sah in Zeichensatz 0 zu wuchtig aus;
der aus Zeichensatz 1 ist schlanker, steht aber mitten in der obersten Zeile --
und jeder Zeichensatzwechsel zerstoert die Home-Zelle. Das erste Zeichen danach
noch einmal zu schreiben machte es schlimmer: Das nachgezogene Zeichen bemalt
GLYPH_WIDTH Pixel und frisst die linke Spalte seines rechten Nachbarn. Deshalb
steht in der obersten Zeile jetzt bewusst kein Sonderzeichen.
161 Tests gruen, am Geraet bestaetigt.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
419 lines
18 KiB
Python
419 lines
18 KiB
Python
"""Tests fuer den Anzeigetreiber -- Zeilenaufbau und die festen Hinweistexte.
|
|
|
|
python3 -m unittest test_display
|
|
"""
|
|
|
|
import unittest
|
|
|
|
import config
|
|
import migra
|
|
from display import Display
|
|
from transport import FakeTransport
|
|
|
|
|
|
def _lesbar(frame):
|
|
"""Telegramm als lesbarer Text; Steuerzeichen werden zu '.'."""
|
|
return "".join(chr(b) if 32 <= b < 127 else "." for b in frame)
|
|
|
|
|
|
def zellen(frames):
|
|
"""Aus gesendeten Telegrammen zurueckrechnen, was wo auf der Anzeige steht.
|
|
|
|
Seit jedes Zeichen einzeln positioniert wird (config.CELL_WIDTH), steht der
|
|
Text nicht mehr am Stueck im Telegramm -- zwischen je zwei Zeichen liegt eine
|
|
Cursor-Sequenz. Ein Test auf "AB " im Rohtelegramm ginge deshalb ins Leere.
|
|
Diese Funktion liest die Cursor-Sequenzen mit und liefert {(x, y): zeichen},
|
|
also das, was die Anzeige am Ende wirklich zeigt.
|
|
|
|
Aufbau je Zeichen: ESC 'C' xxx yyy SEP <zeichen>
|
|
Beim Gradzeichen schiebt sich ein Zeichensatzwechsel dazwischen
|
|
(ESC 'z' nn), das Zeichen ist dann das erste nach dem naechsten SEP.
|
|
"""
|
|
out = {}
|
|
for frame in frames:
|
|
i = 0
|
|
while i < len(frame):
|
|
if frame[i] == migra.ESC and i + 7 < len(frame) and frame[i + 1:i + 2] == b"C":
|
|
x = int(frame[i + 2:i + 5])
|
|
y = int(frame[i + 5:i + 8])
|
|
j = frame.find(bytes([migra.SEP]), i + 8)
|
|
if j >= 0 and j + 1 < len(frame):
|
|
ch = chr(frame[j + 1])
|
|
# Das Gradzeichen entsteht ueber einen Zeichensatzwechsel und
|
|
# steht als DEGREE_CHAR ("/") im Telegramm. Hier wieder in das
|
|
# zurueckuebersetzen, was auf der Anzeige zu sehen ist.
|
|
if (frame[i + 8:j].startswith(b"\x1bz")
|
|
and ch == config.DEGREE_CHAR):
|
|
ch = config.DEGREE_MARKER
|
|
out[(x, y)] = ch
|
|
i += 8
|
|
else:
|
|
i += 1
|
|
return out
|
|
|
|
|
|
def zeile(frames, index):
|
|
"""Den Text einer Anzeigezeile aus den Telegrammen rekonstruieren."""
|
|
y = config.LINE_Y[index]
|
|
treffer = [(x, ch) for (x, yy), ch in zellen(frames).items() if yy == y]
|
|
return "".join(ch for _, ch in sorted(treffer))
|
|
|
|
|
|
# So viele *volle* Zellen passen in eine Zeile. Das ist weniger als
|
|
# config.CHARS_PER_LINE: Dessen 11 Zeichen gehen nur auf, wenn mindestens ein
|
|
# schmales dabei ist (config.CELL_NARROW). Fuer Tests mit normalen Zeichen ist
|
|
# das hier die Zeilenbreite.
|
|
VOLLE_ZELLEN = (config.DISPLAY_WIDTH - config.LINE_X) // config.CELL_WIDTH
|
|
|
|
|
|
def aufbereitet(text):
|
|
"""Erwartungswert: Text so, wie er auf der Zeile landet.
|
|
|
|
Nutzt bewusst dieselbe Funktion wie der Treiber. Wie breit eine Zeile ist,
|
|
haengt seit config.CELL_NARROW davon ab, welche Zeichen darin stehen -- eine
|
|
zweite Nachbildung hier waere nur eine Fehlerquelle. Was der Wert *bedeutet*,
|
|
pruefen die Tests darunter mit eigenen Zusicherungen.
|
|
"""
|
|
return Display._aufbereiten(text)
|
|
|
|
|
|
class TestFesteTexte(unittest.TestCase):
|
|
"""Die Hinweiszeilen muessen in die Anzeige passen.
|
|
|
|
Am Geraet aufgefallen: "MONTIERUNG" hat 10 Zeichen, die Anzeige fasst 9 --
|
|
angezeigt wurde "MONTIERUN". _emit_line schneidet stillschweigend ab, also
|
|
faellt so etwas sonst erst auf der Anzeige auf.
|
|
"""
|
|
|
|
def test_hinweiszeilen_passen_in_die_zeilenbreite(self):
|
|
for name in ("NOLINK_LINES", "NOWIFI_LINES"):
|
|
for zeile in getattr(config, name):
|
|
self.assertLessEqual(
|
|
len(zeile), config.CHARS_PER_LINE,
|
|
"config.%s: %r hat %d Zeichen, die Anzeige fasst %d"
|
|
% (name, zeile, len(zeile), config.CHARS_PER_LINE))
|
|
|
|
def test_es_gibt_nicht_mehr_hinweiszeilen_als_zeilen(self):
|
|
for name in ("NOLINK_LINES", "NOWIFI_LINES"):
|
|
self.assertLessEqual(len(getattr(config, name)), len(config.LINE_Y))
|
|
|
|
|
|
class TestNurGeaenderteZellen(unittest.TestCase):
|
|
"""Der Grund fuer den Vergleich: eine ruhige Anzeige.
|
|
|
|
Mit Einzelpositionierung kostet eine volle Zeile rund 100 Bytes; bei 19200
|
|
Baud dauerte ein kompletter Bildwechsel damit rund 300 ms, und der Aufbau
|
|
war als Flackern zu sehen (am Geraet gemessen 2026-07-27). Deshalb wird nur
|
|
geschrieben, was sich geaendert hat.
|
|
"""
|
|
|
|
def setUp(self):
|
|
self.t = FakeTransport(echo=False)
|
|
self.d = Display(self.t, response=True)
|
|
|
|
def _neu(self):
|
|
"""Telegramme seit dem letzten Aufruf."""
|
|
frames = self.t.frames[:]
|
|
self.t.frames.clear()
|
|
return frames
|
|
|
|
def test_sekundenwechsel_schreibt_nur_die_noetigen_zellen(self):
|
|
"""Der Alltagsfall: RA tickt, alles andere steht still.
|
|
|
|
Geschrieben werden die geaenderte Ziffer *und* ihr rechter Nachbar --
|
|
siehe test_rechter_nachbar_wird_mitgeschrieben.
|
|
"""
|
|
self.d.show_lines("18h36m56s", "+38°47'01\"")
|
|
self._neu()
|
|
|
|
self.d.show_lines("18h36m57s", "+38°47'01\"")
|
|
frames = self._neu()
|
|
|
|
# Die Deklination ist unveraendert -- dafuer darf gar nichts gesendet werden.
|
|
self.assertEqual(len(frames), 1)
|
|
x = lambda i: config.LINE_X + i * config.CELL_WIDTH
|
|
self.assertEqual(zellen(frames), {(x(7), config.LINE_Y[0]): "7",
|
|
(x(8), config.LINE_Y[0]): "s"})
|
|
|
|
def test_rechter_nachbar_wird_mitgeschrieben(self):
|
|
"""Am Geraet aufgefallen (2026-07-27): dem "s" fehlten die linken Pixel.
|
|
|
|
Die Anzeige malt je Zeichen 7 px breit, gesetzt wird auf 6-px-Raster --
|
|
ein neu geschriebenes Zeichen loescht die erste Pixelspalte seines
|
|
rechten Nachbarn. Der muss deshalb mit, sonst bleibt er beschaedigt.
|
|
"""
|
|
self.d.show_lines("AAAAAAAAAA")
|
|
self._neu()
|
|
self.d.show_lines("AAAAXAAAAA") # nur Zelle 4 aendert sich
|
|
gesetzt = zellen(self._neu())
|
|
x = lambda i: config.LINE_X + i * config.CELL_WIDTH
|
|
y = config.LINE_Y[0]
|
|
self.assertIn((x(4), y), gesetzt) # die geaenderte Zelle
|
|
self.assertIn((x(5), y), gesetzt) # ihr rechter Nachbar
|
|
self.assertNotIn((x(3), y), gesetzt) # links davon bleibt unberuehrt
|
|
self.assertNotIn((x(6), y), gesetzt) # und uebernaechste auch
|
|
|
|
def test_letzte_zelle_hat_keinen_nachbarn(self):
|
|
"""Aendert sich die aeusserste rechte Zelle, gibt es nichts nachzuziehen."""
|
|
self.d.show_lines("AAAAAAAAAA")
|
|
self._neu()
|
|
self.d.show_lines("AAAAAAAAAX")
|
|
gesetzt = zellen(self._neu())
|
|
x = lambda i: config.LINE_X + i * config.CELL_WIDTH
|
|
self.assertEqual(list(gesetzt), [(x(9), config.LINE_Y[0])])
|
|
|
|
def test_unveraenderte_zeilen_erzeugen_kein_telegramm(self):
|
|
self.d.show_lines("18h36m56s", "+38°47'01\"")
|
|
self._neu()
|
|
self.d.show_lines("18h36m56s", "+38°47'01\"")
|
|
self.assertEqual(self._neu(), [])
|
|
|
|
def test_telegramm_wird_deutlich_kuerzer(self):
|
|
"""Vorher-nachher in Bytes -- das ist die eigentliche Wirkung."""
|
|
self.d.show_lines("18h36m56s", "+38°47'01\"")
|
|
voll = sum(len(f) for f in self._neu())
|
|
|
|
self.d.show_lines("18h36m57s", "+38°47'01\"")
|
|
diff = sum(len(f) for f in self._neu())
|
|
|
|
# Gemessen: 236 Bytes gegen 30 (Faktor knapp 8). Die Schranke liegt
|
|
# bewusst darunter, damit der Test nicht bei jeder Kleinigkeit kippt --
|
|
# er soll die Groessenordnung sichern, nicht eine exakte Zahl.
|
|
self.assertLess(diff * 5, voll,
|
|
"Der Sekundenwechsel sollte um ein Vielfaches "
|
|
"kuerzer sein als der Vollaufbau (%d vs %d Bytes)"
|
|
% (diff, voll))
|
|
|
|
def test_clear_erzwingt_vollstaendiges_neuschreiben(self):
|
|
self.d.show_lines("18h36m56s", "+38°47'01\"")
|
|
self._neu()
|
|
self.d.show_lines("18h36m56s", "+38°47'01\"", clear=True)
|
|
frames = self._neu()
|
|
# Loeschtelegramm + beide Zeilen vollstaendig
|
|
self.assertEqual(len(frames), 3)
|
|
self.assertEqual(len(zeile(frames, 0)), VOLLE_ZELLEN)
|
|
self.assertEqual(len(zeile(frames, 1)), VOLLE_ZELLEN)
|
|
|
|
def test_nach_clear_kein_rest_der_alten_anzeige(self):
|
|
"""clear muss den gemerkten Inhalt verwerfen.
|
|
|
|
Sonst haelt der Vergleich Zellen faelschlich fuer schon vorhanden und
|
|
die Anzeige bliebe nach dem Loeschen teilweise leer.
|
|
"""
|
|
self.d.show_lines("ABCDEFGHIJ", "0123456789")
|
|
self._neu()
|
|
self.d.clear()
|
|
self._neu()
|
|
self.d.show_lines("ABCDEFGHIJ", "0123456789")
|
|
frames = self._neu()
|
|
self.assertEqual(zeile(frames, 0), "ABCDEFGHIJ")
|
|
self.assertEqual(zeile(frames, 1), "0123456789")
|
|
|
|
def test_nach_sendefehler_wird_die_zeile_voll_neu_geschrieben(self):
|
|
"""Bei einem Fehler ist ungewiss, was ankam -- also nichts annehmen."""
|
|
self.d.show_lines("18h36m56s", "+38°47'01\"")
|
|
self._neu()
|
|
|
|
class Kaputt(Exception):
|
|
pass
|
|
|
|
def platzt(_):
|
|
raise Kaputt()
|
|
|
|
echt, self.d._t.write = self.d._t.write, platzt
|
|
with self.assertRaises(Kaputt):
|
|
self.d.show_lines("18h36m57s", "+38°47'01\"")
|
|
self.d._t.write = echt
|
|
self._neu()
|
|
|
|
# Dieselbe Zeile noch einmal: muss vollstaendig geschrieben werden.
|
|
self.d.show_lines("18h36m57s", "+38°47'01\"")
|
|
self.assertEqual(len(zeile(self._neu(), 0)), VOLLE_ZELLEN)
|
|
|
|
def test_gradzeichen_wird_nicht_staendig_neu_gesetzt(self):
|
|
"""Spart nicht nur Bytes: Jeder Zeichensatzwechsel beschaedigt (0,0)."""
|
|
self.d.show_lines("18h36m56s", "+38°47'01\"")
|
|
self._neu()
|
|
self.d.show_lines("18h36m57s", "+38°47'02\"")
|
|
gesendet = b"".join(self._neu())
|
|
self.assertNotIn(b"\x1bz01", gesendet)
|
|
|
|
|
|
|
|
def test_neues_gradzeichen_zieht_die_oberste_zeile_nach(self):
|
|
"""Wird der Zeichensatz doch gewechselt, ist die Home-Zelle hin.
|
|
|
|
Dann muss die oberste Zeile vollstaendig nachgezogen werden, sonst
|
|
bleibt ihr erstes Zeichen zerstoert.
|
|
"""
|
|
self.d.show_lines("18h36m56s", "kein Grad")
|
|
self._neu()
|
|
self.d.show_lines("18h36m56s", "+38°47'01\"") # Gradzeichen kommt neu dazu
|
|
frames = self._neu()
|
|
self.assertIn(b"\x1bz01", b"".join(frames)) # Wechsel fand statt
|
|
# Obere Zeile trotz unveraendertem Text komplett neu geschrieben.
|
|
self.assertEqual(len(zeile(frames, 0)), VOLLE_ZELLEN)
|
|
|
|
|
|
class TestSchmaleZeichen(unittest.TestCase):
|
|
"""Der Dezimalpunkt der Zehntelminuten braucht weniger als eine volle Zelle.
|
|
|
|
In der Sperrschrift stand "RA 18:37.1" sonst sehr luftig -- der Punkt belegt
|
|
6 px, obwohl er nur ein, zwei Pixel breit ist. 3 px am Geraet ausprobiert
|
|
(2026-07-27). Moeglich ist das nur, weil jedes Zeichen ohnehin einzeln
|
|
positioniert wird.
|
|
"""
|
|
|
|
def setUp(self):
|
|
self.t = FakeTransport(echo=False)
|
|
self.d = Display(self.t, response=True)
|
|
|
|
def _neu(self):
|
|
frames = self.t.frames[:]
|
|
self.t.frames.clear()
|
|
return frames
|
|
|
|
def test_punkt_bekommt_weniger_platz(self):
|
|
pos = Display._positionen("1.2")
|
|
self.assertEqual(pos[1] - pos[0], config.CELL_WIDTH) # vor dem Punkt
|
|
self.assertEqual(pos[2] - pos[1], config.CELL_NARROW["."]) # nach dem Punkt
|
|
|
|
def test_zeile_mit_punkt_wird_schmaler_und_bleibt_mittig(self):
|
|
def breite(positionen):
|
|
return positionen[-1] + config.CELL_WIDTH - positionen[0]
|
|
|
|
ohne = Display._positionen("RA 18:3701") # gleiche Laenge, kein Punkt
|
|
mit = Display._positionen("RA 18:37.1")
|
|
self.assertEqual(breite(ohne) - breite(mit),
|
|
config.CELL_WIDTH - config.CELL_NARROW["."])
|
|
# Weiterhin vollstaendig innerhalb der Anzeige.
|
|
self.assertGreaterEqual(mit[0], 0)
|
|
self.assertLessEqual(mit[-1] + config.CELL_WIDTH, config.DISPLAY_WIDTH)
|
|
|
|
def test_zehntel_wechsel_schreibt_weiter_nur_wenige_zellen(self):
|
|
"""Der Alltagsfall bei Niedrigpraezision -- das Nachfuehren muss greifen."""
|
|
self.d.show_lines("RA 18:37.1", "DE +38°47'")
|
|
self._neu()
|
|
self.d.show_lines("RA 18:37.2", "DE +38°47'")
|
|
frames = self._neu()
|
|
self.assertEqual(len(frames), 1) # DEC unveraendert
|
|
self.assertLessEqual(len(zellen(frames)), 2) # nur die Zehntelziffer
|
|
|
|
def test_strukturwechsel_schreibt_die_zeile_vollstaendig_neu(self):
|
|
"""Kommt ein Punkt dazu, sitzen alle folgenden Zellen woanders.
|
|
|
|
Ein Vergleich Zeichen fuer Zeichen waere dann sinnlos -- es muss alles
|
|
neu geschrieben werden.
|
|
"""
|
|
self.d.show_lines("RA 18:3701") # ohne Punkt: 10 volle Zellen
|
|
self._neu()
|
|
self.d.show_lines("RA 18:37.1") # mit Punkt: andere Positionen
|
|
gesetzt = zellen(self._neu())
|
|
# Alles neu -- und dank des schmalen Punktes passt sogar ein Zeichen mehr.
|
|
self.assertEqual(len(gesetzt), len(Display._aufbereiten("RA 18:37.1")))
|
|
self.assertGreater(len(gesetzt), VOLLE_ZELLEN)
|
|
|
|
|
|
class TestZeilenaufbau(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
self.t = FakeTransport(echo=False)
|
|
self.d = Display(self.t, response=True)
|
|
|
|
def _alle(self):
|
|
return self.t.frames
|
|
|
|
def test_zeile_wird_auf_volle_breite_aufgefuellt(self):
|
|
"""Ohne Auffuellen blieben Reste der vorigen Anzeige stehen.
|
|
|
|
Gleichzeitig die Regressionsprobe fuer str.ljust, das MicroPython
|
|
nicht kennt (am Geraet aufgefallen).
|
|
"""
|
|
self.d.show_lines("AB", "CD")
|
|
self.assertEqual(zeile(self._alle(), 0), aufbereitet("AB"))
|
|
self.assertEqual(zeile(self._alle(), 1), aufbereitet("CD"))
|
|
# Es wird immer die volle Breite geschrieben, damit nichts stehen bleibt.
|
|
self.assertEqual(len(zeile(self._alle(), 0)), VOLLE_ZELLEN)
|
|
|
|
def test_kuerzere_zeile_steht_linksbuendig(self):
|
|
"""Nutzerwunsch 2026-07-27: beide Zeilen buendig untereinander.
|
|
|
|
Zentriert standen sie um wenige Pixel gegeneinander versetzt, weil die
|
|
RA-Zeile mit ihrem schmalen Dezimalpunkt kuerzer ist als die DEC-Zeile.
|
|
"""
|
|
self.d.show_lines("+38°47'") # 7 Zeichen in 10 Zellen
|
|
text = zeile(self._alle(), 0)
|
|
self.assertEqual(text, "+38°47'" + " " * (VOLLE_ZELLEN - 7))
|
|
|
|
def test_beide_zeilen_beginnen_an_derselben_stelle(self):
|
|
"""Der eigentliche Punkt: RA und DE muessen buendig starten."""
|
|
self.d.show_lines("RA:18h37.1", "DE:+38°47'")
|
|
gesetzt = zellen(self._alle())
|
|
erste_oben = min(x for (x, y) in gesetzt if y == config.LINE_Y[0])
|
|
erste_unten = min(x for (x, y) in gesetzt if y == config.LINE_Y[1])
|
|
self.assertEqual(erste_oben, erste_unten)
|
|
|
|
def test_jedes_zeichen_sitzt_auf_seiner_zelle(self):
|
|
"""Der Auto-Vorschub der Sperrschrift ist 7 px und liesse nur 9 Zeichen
|
|
zu; die Matrix ist aber 6 px breit. Deshalb wird jedes Zeichen selbst
|
|
gesetzt -- x muss genau LINE_X + i*CELL_WIDTH sein (am Geraet gemessen)."""
|
|
self.d.show_lines("0123456789")
|
|
gesetzt = zellen(self._alle())
|
|
y = config.LINE_Y[0]
|
|
for i in range(VOLLE_ZELLEN):
|
|
self.assertIn((config.LINE_X + i * config.CELL_WIDTH, y), gesetzt)
|
|
|
|
def test_zeile_passt_in_die_anzeigenbreite(self):
|
|
"""Auch die letzte Zelle darf nicht ueber den rechten Rand hinausragen --
|
|
sonst quittiert die Anzeige mit Fehlercode 4 (ausserhalb)."""
|
|
rechts = config.LINE_X + VOLLE_ZELLEN * config.CELL_WIDTH
|
|
self.assertLessEqual(rechts, config.DISPLAY_WIDTH)
|
|
self.assertGreaterEqual(config.LINE_X, 0)
|
|
|
|
def test_zu_lange_zeile_wird_abgeschnitten(self):
|
|
"""Zu breit aufgefuellt bricht das Fuell-Leerzeichen um und
|
|
beschaedigt die andere Zeile -- deshalb hart abschneiden."""
|
|
lang = "X" * (config.CHARS_PER_LINE + 5)
|
|
self.d.show_lines(lang)
|
|
self.assertEqual(zeile(self._alle(), 0), "X" * VOLLE_ZELLEN)
|
|
|
|
def test_oberste_zeile_wird_zuletzt_gezeichnet(self):
|
|
"""Schutz der Home-Zelle: ein Zeichensatzwechsel zerstoert (0,0),
|
|
die oberste Zeile muss danach kommen und sie ueberschreiben."""
|
|
self.d.show_lines("OBEN", "UNTEN")
|
|
frames = self._alle()
|
|
self.assertEqual(len(frames), 2)
|
|
# Erst das Telegramm der unteren Zeile, dann das der oberen.
|
|
self.assertEqual(zeile(frames[:1], 1).strip(), "UNTEN")
|
|
self.assertEqual(zeile(frames[1:], 0).strip(), "OBEN")
|
|
|
|
def test_telegramme_bleiben_unter_der_groessengrenze(self):
|
|
"""Mit Einzelpositionierung kosten beide Zeilen zusammen 224 der
|
|
erlaubten 230 Bytes -- deshalb ein Telegramm je Zeile. Der Test haelt
|
|
fest, dass die Reserve nicht wieder verloren geht."""
|
|
self.d.show_lines("18h36m56s", "+38" + config.DEGREE_MARKER + "47'01\"",
|
|
clear=True)
|
|
for frame in self._alle():
|
|
self.assertLessEqual(len(frame), migra.MAX_DATA_UNIT)
|
|
|
|
def test_clear_erzeugt_genau_ein_vollbild_loeschen(self):
|
|
"""clear=True darf nur einmal loeschen -- sonst loescht das zweite
|
|
Telegramm die gerade geschriebene Zeile wieder weg."""
|
|
fuellen = bytes([migra.ESC]) + b"F" + config.BACKGROUND.encode("ascii")
|
|
|
|
self.d.show_lines("A", "B", clear=True)
|
|
mit = self.t.frames[:]
|
|
self.assertEqual(sum(f.count(fuellen) for f in mit), 1)
|
|
|
|
self.t.frames.clear()
|
|
self.d.show_lines("A", "B", clear=False)
|
|
self.assertEqual(sum(f.count(fuellen) for f in self.t.frames), 0)
|
|
|
|
def test_mehr_zeilen_als_die_anzeige_hat(self):
|
|
with self.assertRaises(ValueError):
|
|
self.d.show_lines(*(["X"] * (len(config.LINE_Y) + 1)))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|