Testgetriebene Entwicklung für Fontlab Studio 5 Python-Makros und -Module.
Fakelab ist ein Ersatz für Fontlab Studio 5 zum Testen von Python -Code.
Alles wird nur so weit implementiert, dass Fontlab -Objekte außerhalb von Fontlab Studio 5 und Tests durchgeführt werden.
Es wird empfohlen, Fakelab in einer virtuellen Umgebung zu installieren, sodass Fontlab das gefälschte Modul beim Ausführen der Skripte im tatsächlichen Fontlab Studio nicht versehentlich importiert. Wenn Sie mit den Inkompatibiliten zwischen Python 2.7 und 3 leben können, können Sie auch Fakelab in Python 3 ausführen.
Das Speichern von VFBs wird nicht unterstützt, da das VFB -Format nicht öffentlich ist, aber Sie können Font als JSON speichern.
Die Implementierung von Fakelab basiert auf der unschätzbaren inoffiziellen Fontlab/Python -API -Referenz sowie auf dem Ausführen von Skripten in Fontlab Studio und der Überprüfung, was sie tun, abgesehen vom Absturz der Anwendung.
Wenn Sie Ihre virtuelle Umgebung aktiviert haben:
$ pip install -e .FL ist dann außerhalb des Fontlab Studio importierbar:
from FL import fl , Font
# Make an empty font
f = Font ()
# Add the font to the mock app
fl . Add ( f )
# Close the font
fl . Close () Wenn Sie in einer virtuellen Umgebung ausgeführt werden und Ihre Fontlab-Module importierbar machen müssen, fügen Sie eine .pth Datei in das Site-Packages-Verzeichnis Ihrer virtuellen Umgebung hinzu:
# fl5modules.pth
/Users/<yourname>/Code/FLMacros/System/Modules
Fakelab ist eine laufende Arbeit und wird nur soweit ich sie in meinen eigenen Skripten brauchte. Ich muss zugeben, dass der Großteil von ihnen immer noch keine Tests hat.
Wenn Sie beim Schreiben von Tests auf einen NotImplementedError Eingang stoßen, können Sie hier bei der Verbesserung dieses Projekts helfen.) Ich werde gerne Ihre Pull -Anfragen annehmen. Alternativ, öffnen Sie ein Problem, kaufen Sie mir einen Kaffee und hoffen, dass meine Kinder mich in Ruhe lassen, damit ich etwas Zeit finden kann, um an Ihrem Problem zu arbeiten.
Die Entwicklung von Skripten ohne automatisierte Tests ist wirklich nur für sehr kleine Projekte. Um die Ergebnisse eines Moduls oder Skripts sicherzustellen, sollten Sie immer Tests schreiben. Dies geschieht normalerweise mit PyTest.
Nehmen wir an, Sie haben ein Fontlab -Skript, um Glyphen mit Komponenten auszuwählen. Wenn Sie Ihre eigene Tools -Sammlung für Fontlab haben, kann dieses Skript aus zwei Teilen bestehen: ein Skript, das in der Makro -Symbolleiste von Fontlab aufgeführt ist, und ein Python -Modul, das die Logik implementiert, die vom Symbolleistenskript aufgerufen wird.
Studio 5
+- Macros
+- Selection
+- Select Composites.py
+- System
+- Modules
+- fakeLabDemo
+- selection
+- __init__.py
+- composites.py
Das Skript Select Composites.py sieht folgt aus:
#FLM: Select composites
# Studio 5/Macros/Selection/Select Composites.py
from fakeLabDemo . selection . composites import selectComposites
selectComposites ( fl . font )Und das Modul:
# Studio 5/Macros/System/Modules/fakeLabDemo/selection/composites.py
from __future__ import absolute_import , division , print_function
from FL import fl
def getFontIndex ( font ):
"""
Get the index of the supplied font.
We must iterate through the open fonts and compare file names,
because the == operator can not compare the font objects directly.
(FL font objects get a different id() each time they are called)
:param font: A title for the dialog.
:type font: :py:class:`FL.Font`
"""
for i in range ( len ( fl )):
cf = fl [ i ]
if cf . file_name == font . file_name :
if font . file_name is None :
if (
cf . family_name == font . family_name
and cf . style_name == font . style_name
):
return ( cf , i )
else :
return ( cf , i )
# Font was not found, probably there are no open fonts
return ( None , - 1 )
def setSelection ( font , glyph_names ):
"""
Set glyphs from the glyph_names list as selected in the font window.
"""
f , i = getFontIndex ( font )
if i > - 1 :
fl . ifont = i
fl . Unselect ()
for n in glyph_names :
fl . Select ( n )
def selectComposites ( font ):
"""
Select composites in font.
"""
setSelection (
font ,
[
glyph . name
for glyph in font . glyphs
if glyph . components
]
)Wie können wir sicher sein, dass dieses Skript das tut, was es tun soll? Für PyTest fügen wir der vorhandenen Struktur eine weitere parallele Ordnerstruktur hinzu:
Studio 5
+- Macros
+- Selection
+- Select Composites.py
+- System
+- Modules
+- fakeLabDemo
+- selection
+- __init__.py
+- composites.py
+- tests
+- fakeLabDemo
+- selection
+- composites_test.py
In der Datei composites_test.py , die analog zur Moduldatei bezeichnet wird, die sie bezieht, werden wir unsere Tests implementieren:
# Studio 5/Macros/System/Modules/tests/fakeLabDemo/selection/composites_test.py
import pytest
from FL import fl , Component , Font , Glyph , Point
from fakeLabDemo . selection . composites import selectComposites
def test_selectComposites ():
# Construct a fake FontLab font object
font = Font ()
g = Glyph ( 1 )
g . name = "A"
g . width = 500
g . unicode = 0x41
font . glyphs . append ( g )
g = Glyph ( 1 )
g . name = "dieresis"
g . width = 500
g . unicode = 0xA8
font . glyphs . append ( g )
g = Glyph ( 1 )
g . name = "Adieresis"
g . width = 500
g . unicode = 0xC4
g . components . append ( Component ( 0 ))
g . components . append ( Component ( 1 , Point ( 0 , 300 )))
font . glyphs . append ( g )
# Add the font to the FL object
fl . Add ( font )
fl . UpdateFont ()
# Run our script to be tested on the font
selectComposites ( fl . font )
# You could save the fake font to JSON instead of VFB.
# fl.font.Save("test_composites.vfb.json")
# Test if the correct glyphs have been selected
assert fl . Selected ( 0 ) == 0
assert fl . Selected ( 1 ) == 0
assert fl . Selected ( 2 ) == 1
# Close the fake font
fl . Close ()Wie Sie sehen, können Sie die Objekte genauso verwenden, wie Sie es in Fontlab tun würden. Sie können einfach keine Schriftart aus einem vorhandenen VFB öffnen, was viel einfacher wäre. Das VFB -Dateiformat ist jedoch nicht öffentlich.
Stattdessen müssen Sie eine Testschrift mit der Fl -Python -API erstellen.
Rufen Sie das Testskript in ein Terminalfenster auf, während Ihre virtuelle Umgebung aktiv ist:
cd " Studio 5/Macros/System/Modules "
python -m pytest tests/fakeLabDemo/selection/composites_test.pyWenn alles funktioniert, sehen Sie eine solche Ausgabe wie folgt:
============================ test session starts ===============================
platform darwin -- Python 3.8.7, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: /Users/jens/Code/fakelab
collected 1 item
tests/fakeLabDemo/selection/composites_test.py . [100%]
============================= 1 passed in 0.02s ================================