Refactoring & portable Testpfade

This commit is contained in:
Tim
2026-07-06 21:51:48 +02:00
parent 9ed66dacbc
commit fc37f44d26
9 changed files with 246 additions and 206 deletions
+18 -4
View File
@@ -72,11 +72,25 @@ Jeder Mock liest seine Konfiguration aus einer State-Datei in `fixtures/`.
Die Tests können diese States über Hilfsfunktionen setzen:
```bash
set_wget_latest_version "0.10.16" # Neueste Version simulieren
set_find_installed_version "0.10.14" # Installierte Version simulieren
set_pgrep_running 1 # Prozess läuft (1) oder nicht (0)
set_wget_latest_version "${VERSION_LATEST}" # Neueste Version simulieren
set_find_installed_version "${VERSION_INSTALLED}" # Installierte Version simulieren
set_pgrep_running 1 # Prozess läuft (1) oder nicht (0)
```
## Versions-Variablen
Versionsnummern sind **nicht hartkodiert** in den Tests, sondern als Variablen
am Anfang der Testdatei definiert. Dummy-AppImages werden on-the-fly erstellt:
```bash
VERSION_LATEST="0.10.15" # Neueste verfügbare Version
VERSION_INSTALLED="0.10.14" # Ältere installierte Version
VERSION_OUTDATED="0.10.13" # Noch ältere Version (für Cleanup-Tests)
```
Um die Tests an eine neue Version anzupassen, reicht es, diese drei Variablen
zu ändern. Die Dummy-AppImages und State-Dateien werden automatisch angepasst.
## Neuen Test hinzufügen
In `test/logseq-installer.bats`:
@@ -84,7 +98,7 @@ In `test/logseq-installer.bats`:
```bash
@test "mein neuer Test" {
# Mock-States setzen
set_wget_latest_version "0.10.16"
set_wget_latest_version "${VERSION_LATEST}"
set_find_installed_version ""
set_pgrep_running 0
+2
View File
@@ -0,0 +1,2 @@
#!/bin/bash
echo "Logseq 0.10.13 dummy"
+1 -1
View File
@@ -1,3 +1,3 @@
WGET_LATEST_VERSION="0.10.15"
WGET_DOWNLOAD_SUCCESS="true"
WGET_DOWNLOAD_FILE="${FIXTURES_DIR}/Logseq-linux-x64-0.10.15.AppImage"
WGET_DOWNLOAD_FILE="Logseq-linux-x64-0.10.15.AppImage"
+110 -118
View File
@@ -3,8 +3,27 @@
# Test-Suite für logseq-install.sh
# Verwendet Mocks für wget, pgrep, find, update-desktop-database
# Test-Setup
# =============================================================================
# VERSIONS-KONSTANTEN (nur hier ändern, Tests passen sich automatisch an)
# =============================================================================
# Version, die als "neueste" von GitHub gemeldet wird
VERSION_LATEST="0.10.15"
# Version, die als bereits installiert simuliert wird (älter als LATEST)
VERSION_INSTALLED="0.10.14"
# Noch ältere Version für Cleanup-Tests (mehrere alte Versionen)
VERSION_OUTDATED="0.10.13"
# =============================================================================
# TEST-SETUP / TEARDOWN
# =============================================================================
setup() {
# Pfade relativ zur Testdatei ableiten (funktioniert unabhängig vom Ablageort)
# BATS_TEST_DIRNAME zeigt immer auf das Verzeichnis der .bats-Datei.
export MOCKS_DIR="${BATS_TEST_DIRNAME}/mocks"
export FIXTURES_DIR="${BATS_TEST_DIRNAME}/fixtures"
export SCRIPT_PATH="${BATS_TEST_DIRNAME}/../logseq-install.sh"
# Test-Verzeichnis
export TEST_DIR="$(mktemp -d)"
export HOME="${TEST_DIR}/home"
@@ -12,63 +31,79 @@ setup() {
export DESKTOP_DIR="${HOME}/.local/share/applications"
# Mock-PATH vorbereiten (Mocks vor echten Befehlen)
export PATH="/home/tim/Dokumente/Sourcen/Logseq-Installer/test/mocks:${PATH}"
# Fixtures-Verzeichnis
export FIXTURES_DIR="/home/tim/Dokumente/Sourcen/Logseq-Installer/test/fixtures"
export PATH="${MOCKS_DIR}:${PATH}"
# Home-Verzeichnis erstellen
mkdir -p "${HOME}"
mkdir -p "${INSTALL_DIR}"
mkdir -p "${DESKTOP_DIR}"
mkdir -p "${HOME}" "${INSTALL_DIR}" "${DESKTOP_DIR}"
# Dummy-AppImages für alle benötigten Versionen on-the-fly erstellen
create_dummy_appimage "${VERSION_LATEST}"
create_dummy_appimage "${VERSION_INSTALLED}"
create_dummy_appimage "${VERSION_OUTDATED}"
# Mock-States zurücksetzen
reset_mocks
}
# Test-Cleanup
teardown() {
rm -rf "${TEST_DIR}"
}
# Mock-States zurücksetzen
# =============================================================================
# HELPER-FUNKTIONEN
# =============================================================================
# Erzeugt ein Dummy-AppImage für eine bestimmte Version (falls nicht vorhanden)
create_dummy_appimage() {
local version="$1"
local file="${FIXTURES_DIR}/Logseq-linux-x64-${version}.AppImage"
if [[ ! -f "${file}" ]]; then
{
echo "#!/bin/bash"
echo "echo \"Logseq ${version} dummy\""
} > "${file}"
chmod +x "${file}"
fi
}
# Mock-States auf Default zurücksetzen
reset_mocks() {
# wget: neueste Version 0.10.15
cat > "${FIXTURES_DIR}/wget_state" <<'EOF'
WGET_LATEST_VERSION="0.10.15"
WGET_DOWNLOAD_SUCCESS="true"
WGET_DOWNLOAD_FILE="${FIXTURES_DIR}/Logseq-linux-x64-0.10.15.AppImage"
EOF
# pgrep: kein Prozess läuft
cat > "${FIXTURES_DIR}/pgrep_state" <<'EOF'
PGREP_MATCH_COUNT=0
EOF
# find: nichts installiert
cat > "${FIXTURES_DIR}/find_state" <<'EOF'
FIND_INSTALLED_VERSION=""
FIND_FILES_RAW=""
EOF
set_wget_latest_version "${VERSION_LATEST}"
set_wget_download_success "true"
set_pgrep_running 0
set_find_installed_version ""
}
# Hilfsfunktion: Mock-State für wget setzen
# Mock-State für wget: neueste Version setzen
set_wget_latest_version() {
local version="$1"
create_dummy_appimage "${version}"
cat > "${FIXTURES_DIR}/wget_state" <<EOF
WGET_LATEST_VERSION="${1}"
WGET_DOWNLOAD_SUCCESS="true"
WGET_DOWNLOAD_FILE="${FIXTURES_DIR}/Logseq-linux-x64-${1}.AppImage"
WGET_LATEST_VERSION="${version}"
WGET_DOWNLOAD_SUCCESS="${WGET_DOWNLOAD_SUCCESS:-true}"
WGET_DOWNLOAD_FILE="Logseq-linux-x64-${version}.AppImage"
EOF
}
# Hilfsfunktion: Mock-State für pgrep setzen
# Mock-State für wget: Download-Erfolg steuern
set_wget_download_success() {
WGET_DOWNLOAD_SUCCESS="$1"
# State-Datei neu schreiben mit aktuellem Erfolgswert
cat > "${FIXTURES_DIR}/wget_state" <<EOF
WGET_LATEST_VERSION="${VERSION_LATEST}"
WGET_DOWNLOAD_SUCCESS="${1}"
WGET_DOWNLOAD_FILE="Logseq-linux-x64-${VERSION_LATEST}.AppImage"
EOF
}
# Mock-State für pgrep: Prozess läuft (1) oder nicht (0)
set_pgrep_running() {
cat > "${FIXTURES_DIR}/pgrep_state" <<EOF
PGREP_MATCH_COUNT=${1}
EOF
}
# Hilfsfunktion: Mock-State für find setzen (installierte Version)
# Mock-State für find: installierte Version setzen
set_find_installed_version() {
cat > "${FIXTURES_DIR}/find_state" <<EOF
FIND_INSTALLED_VERSION="${1}"
@@ -76,7 +111,7 @@ FIND_FILES_RAW=""
EOF
}
# Hilfsfunktion: Mock-State für find setzen (mehrere Dateien)
# Mock-State für find: mehrere Dateien setzen (pipe-getrennt)
set_find_files() {
cat > "${FIXTURES_DIR}/find_state" <<EOF
FIND_INSTALLED_VERSION=""
@@ -84,12 +119,19 @@ FIND_FILES_RAW="${1}"
EOF
}
# Erzeugt eine echte Dummy-AppImage-Datei im Installationsverzeichnis
create_installed_appimage() {
local version="$1"
local file="${INSTALL_DIR}/Logseq-linux-x64-${version}.AppImage"
touch "${file}"
chmod +x "${file}"
}
# Das Skript mit Test-Umgebung ausführen
run_installer() {
# Umgebungsvariablen für das Skript setzen
HOME="${HOME}" \
PATH="${PATH}" \
/home/tim/Dokumente/Sourcen/Logseq-Installer/logseq-install.sh "$@"
"${SCRIPT_PATH}" "$@"
}
# =============================================================================
@@ -124,7 +166,6 @@ run_installer() {
}
@test "root-Option ohne Root-Rechte wird akzeptiert" {
# Nicht als root, aber -r angegeben -> sollte nicht fehlschlagen
run run_installer -r --hilfe
[ "$status" -eq 1 ] # Hilfe wird angezeigt
[[ "$output" == *"Logseq Installer"* ]]
@@ -135,8 +176,7 @@ run_installer() {
# =============================================================================
@test "uninstall entfernt Dateien und exited mit 0" {
# Dummy-Dateien erstellen
touch "${INSTALL_DIR}/Logseq-linux-x64-0.10.14.AppImage"
create_installed_appimage "${VERSION_INSTALLED}"
touch "${INSTALL_DIR}/Logseq"
touch "${DESKTOP_DIR}/logseq.desktop"
touch "${DESKTOP_DIR}/logseq.png"
@@ -145,8 +185,7 @@ run_installer() {
[ "$status" -eq 0 ]
[[ "$output" == *"deinstalliert"* ]]
# Dateien sollten weg sein
[ ! -f "${INSTALL_DIR}/Logseq-linux-x64-0.10.14.AppImage" ]
[ ! -f "${INSTALL_DIR}/Logseq-linux-x64-${VERSION_INSTALLED}.AppImage" ]
[ ! -f "${INSTALL_DIR}/Logseq" ]
[ ! -f "${DESKTOP_DIR}/logseq.desktop" ]
[ ! -f "${DESKTOP_DIR}/logseq.png" ]
@@ -157,25 +196,18 @@ run_installer() {
# =============================================================================
@test "get_latest_version ermittelt Version aus GitHub" {
# Wir testen die Funktion indirekt durch den Hauptablauf
# aber hier prüfen wir, ob wget-Mock korrekt funktioniert
run run_installer --hilfe
[ "$status" -eq 1 ]
}
@test "get_current_version erkennt installierte Version" {
set_find_installed_version "0.10.14"
# Simuliere Installation durch direkten Aufruf (wir testen intern)
# Da wir Funktionen nicht direkt testen können, testen wir über den Hauptablauf
# mit --hilfe nur als Dummy - eigentlicher Test passiert in Integrationstests
set_find_installed_version "${VERSION_INSTALLED}"
run run_installer --hilfe
[ "$status" -eq 1 ]
}
@test "get_current_version erkennt keine Installation" {
set_find_installed_version ""
run run_installer --hilfe
[ "$status" -eq 1 ]
}
@@ -185,55 +217,37 @@ run_installer() {
# =============================================================================
@test "Installation: neueste Version wird heruntergeladen und installiert" {
# Setup: Version 0.10.15 ist neueste, nichts installiert
set_wget_latest_version "0.10.15"
set_wget_latest_version "${VERSION_LATEST}"
set_find_installed_version ""
# Mock: pgrep sagt, kein Prozess läuft
set_pgrep_running 0
run run_installer
[ "$status" -eq 0 ]
[[ "$output" == *"erfolgreich installiert"* ]] || [[ "$output" == *"erfolgreich"* ]]
[[ "$output" == *"erfolgreich"* ]]
# AppImage sollte existieren
[ -f "${INSTALL_DIR}/Logseq-linux-x64-0.10.15.AppImage" ]
# Symlink sollte existieren
[ -f "${INSTALL_DIR}/Logseq-linux-x64-${VERSION_LATEST}.AppImage" ]
[ -L "${INSTALL_DIR}/Logseq" ]
[ "$(readlink "${INSTALL_DIR}/Logseq")" = "${INSTALL_DIR}/Logseq-linux-x64-0.10.15.AppImage" ]
# Desktop-Datei sollte existieren
[ "$(readlink "${INSTALL_DIR}/Logseq")" = "${INSTALL_DIR}/Logseq-linux-x64-${VERSION_LATEST}.AppImage" ]
[ -f "${DESKTOP_DIR}/logseq.desktop" ]
}
@test "Update: alte Version wird durch neue ersetzt" {
# Setup: 0.10.14 installiert, 0.10.15 verfügbar
set_find_installed_version "0.10.14"
set_wget_latest_version "0.10.15"
set_find_installed_version "${VERSION_INSTALLED}"
set_wget_latest_version "${VERSION_LATEST}"
set_pgrep_running 0
# Dummy-Datei für alte Version
touch "${INSTALL_DIR}/Logseq-linux-x64-0.10.14.AppImage"
chmod +x "${INSTALL_DIR}/Logseq-linux-x64-0.10.14.AppImage"
create_installed_appimage "${VERSION_INSTALLED}"
run run_installer
[ "$status" -eq 0 ]
# Neue Version installiert
[ -f "${INSTALL_DIR}/Logseq-linux-x64-0.10.15.AppImage" ]
# Alte Version gelöscht
[ ! -f "${INSTALL_DIR}/Logseq-linux-x64-0.10.14.AppImage" ]
# Symlink zeigt auf neue Version
[ "$(readlink "${INSTALL_DIR}/Logseq")" = "${INSTALL_DIR}/Logseq-linux-x64-0.10.15.AppImage" ]
[ -f "${INSTALL_DIR}/Logseq-linux-x64-${VERSION_LATEST}.AppImage" ]
[ ! -f "${INSTALL_DIR}/Logseq-linux-x64-${VERSION_INSTALLED}.AppImage" ]
[ "$(readlink "${INSTALL_DIR}/Logseq")" = "${INSTALL_DIR}/Logseq-linux-x64-${VERSION_LATEST}.AppImage" ]
}
@test "Kein Update: bereits aktuelle Version beendet mit Code 0" {
# Setup: 0.10.15 installiert, 0.10.15 verfügbar
set_find_installed_version "0.10.15"
set_wget_latest_version "0.10.15"
set_find_installed_version "${VERSION_LATEST}"
set_wget_latest_version "${VERSION_LATEST}"
run run_installer
[ "$status" -eq 0 ]
@@ -241,10 +255,9 @@ run_installer() {
}
@test "Abbruch: Logseq läuft noch" {
# Setup: Prozess läuft
set_pgrep_running 1
set_find_installed_version "0.10.14"
set_wget_latest_version "0.10.15"
set_find_installed_version "${VERSION_INSTALLED}"
set_wget_latest_version "${VERSION_LATEST}"
run run_installer
[ "$status" -eq 1 ]
@@ -252,13 +265,7 @@ run_installer() {
}
@test "Fehler: Download fehlschlägt" {
# Setup: Download fehlschlägt
cat > "${FIXTURES_DIR}/wget_state" <<'EOF'
WGET_LATEST_VERSION="0.10.15"
WGET_DOWNLOAD_SUCCESS="false"
WGET_DOWNLOAD_FILE="${FIXTURES_DIR}/Logseq-linux-x64-0.10.15.AppImage"
EOF
set_wget_download_success "false"
set_find_installed_version ""
set_pgrep_running 0
@@ -272,7 +279,7 @@ EOF
# =============================================================================
@test "Desktop-Datei wird korrekt erstellt" {
set_wget_latest_version "0.10.15"
set_wget_latest_version "${VERSION_LATEST}"
set_find_installed_version ""
set_pgrep_running 0
@@ -282,25 +289,22 @@ EOF
desktop_file="${DESKTOP_DIR}/logseq.desktop"
[ -f "${desktop_file}" ]
# Inhalt prüfen
grep -q "Name=Logseq" "${desktop_file}"
grep -q "Exec=${HOME}/.local/bin/Logseq-linux-x64-0.10.15.AppImage --no-sandbox" "${desktop_file}"
grep -q "Exec=${HOME}/.local/bin/Logseq-linux-x64-${VERSION_LATEST}.AppImage --no-sandbox" "${desktop_file}"
grep -q "Icon=${DESKTOP_DIR}/logseq.png" "${desktop_file}"
grep -q "Categories=Office;" "${desktop_file}"
}
@test "Icon wird heruntergeladen wenn nicht vorhanden" {
set_wget_latest_version "0.10.15"
set_wget_latest_version "${VERSION_LATEST}"
set_find_installed_version ""
set_pgrep_running 0
# Icon nicht vorhanden
[ ! -f "${DESKTOP_DIR}/logseq.png" ]
run run_installer
[ "$status" -eq 0 ]
# Icon sollte jetzt da sein
[ -f "${DESKTOP_DIR}/logseq.png" ]
}
@@ -309,13 +313,7 @@ EOF
# =============================================================================
@test "Root-Check: als root ohne -r Option schlägt fehl" {
# Simuliere root durch Überschreiben von whoami
# Wir können whoami nicht einfach mocken, aber wir können testen
# dass die Logik im Skript stimmt indem wir den Code prüfen
# (Integrationstest würde sudo erfordern)
# Prüfen dass der Code die Prüfung enthält
run grep -q "whoami.*root" /home/tim/Dokumente/Sourcen/Logseq-Installer/logseq-install.sh
run grep -q "whoami.*root" "${SCRIPT_PATH}"
[ "$status" -eq 0 ]
}
@@ -324,24 +322,19 @@ EOF
# =============================================================================
@test "Cleanup: mehrere alte Versionen werden entfernt" {
# Setup: mehrere alte Versionen vorhanden
set_find_files "Logseq-linux-x64-0.10.13.AppImage|Logseq-linux-x64-0.10.14.AppImage"
set_wget_latest_version "0.10.15"
set_find_files "Logseq-linux-x64-${VERSION_OUTDATED}.AppImage|Logseq-linux-x64-${VERSION_INSTALLED}.AppImage"
set_wget_latest_version "${VERSION_LATEST}"
set_pgrep_running 0
# Dateien erstellen
touch "${INSTALL_DIR}/Logseq-linux-x64-0.10.13.AppImage"
touch "${INSTALL_DIR}/Logseq-linux-x64-0.10.14.AppImage"
chmod +x "${INSTALL_DIR}/Logseq-linux-x64-0.10.13.AppImage"
chmod +x "${INSTALL_DIR}/Logseq-linux-x64-0.10.14.AppImage"
create_installed_appimage "${VERSION_OUTDATED}"
create_installed_appimage "${VERSION_INSTALLED}"
run run_installer
[ "$status" -eq 0 ]
# Nur neue Version da
[ -f "${INSTALL_DIR}/Logseq-linux-x64-0.10.15.AppImage" ]
[ ! -f "${INSTALL_DIR}/Logseq-linux-x64-0.10.13.AppImage" ]
[ ! -f "${INSTALL_DIR}/Logseq-linux-x64-0.10.14.AppImage" ]
[ -f "${INSTALL_DIR}/Logseq-linux-x64-${VERSION_LATEST}.AppImage" ]
[ ! -f "${INSTALL_DIR}/Logseq-linux-x64-${VERSION_OUTDATED}.AppImage" ]
[ ! -f "${INSTALL_DIR}/Logseq-linux-x64-${VERSION_INSTALLED}.AppImage" ]
}
# =============================================================================
@@ -349,8 +342,7 @@ EOF
# =============================================================================
@test "Farbcodes werden gesetzt (tput)" {
# Prüfen dass tput-Codes im Skript sind
run grep -q "tput setaf" /home/tim/Dokumente/Sourcen/Logseq-Installer/logseq-install.sh
run grep -q "tput setaf" "${SCRIPT_PATH}"
[ "$status" -eq 0 ]
}
@@ -359,11 +351,11 @@ EOF
# =============================================================================
@test "Fehlerbehandlung: Trap für ERR gesetzt" {
run grep -q "trap.*handle_error.*ERR" /home/tim/Dokumente/Sourcen/Logseq-Installer/logseq-install.sh
run grep -q "trap.*handle_error.*ERR" "${SCRIPT_PATH}"
[ "$status" -eq 0 ]
}
@test "require_command prüft Abhängigkeiten" {
run grep -q "require_command" /home/tim/Dokumente/Sourcen/Logseq-Installer/logseq-install.sh
run grep -q "require_command" "${SCRIPT_PATH}"
[ "$status" -eq 0 ]
}
+1 -1
View File
@@ -3,7 +3,7 @@
# - Bei Versions-Erkennung: simulierte Pfade aus State
# - Bei Cleanup mit -delete: echte Dateien löschen
MOCK_DIR="/home/tim/Dokumente/Sourcen/Logseq-Installer/test/fixtures"
MOCK_DIR="$(cd "$(dirname "$0")/../fixtures" && pwd)"
MOCK_STATE_FILE="${MOCK_DIR}/find_state"
# Echten find über absoluten Pfad aufrufen (vermeidet Rekursion über PATH)
REAL_FIND=""
+1 -1
View File
@@ -2,7 +2,7 @@
# Mock für pgrep - steuert Prozess-Erkennung
# pgrep -c: gibt Anzahl aus, Exit-Code 0 wenn >0, sonst 1
MOCK_DIR="/home/tim/Dokumente/Sourcen/Logseq-Installer/test/fixtures"
MOCK_DIR="$(cd "$(dirname "$0")/../fixtures" && pwd)"
MOCK_STATE_FILE="${MOCK_DIR}/pgrep_state"
if [[ -f "${MOCK_STATE_FILE}" ]]; then
+6 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash
# Mock für wget - simuliert GitHub API und Downloads
MOCK_DIR="$(dirname "$0")/../fixtures"
MOCK_DIR="$(cd "$(dirname "$0")/../fixtures" && pwd)"
MOCK_STATE_FILE="${MOCK_DIR}/wget_state"
# State laden (welche Version soll zurückgegeben werden?)
@@ -15,6 +15,11 @@ WGET_LATEST_VERSION="${WGET_LATEST_VERSION:-0.10.15}"
WGET_DOWNLOAD_SUCCESS="${WGET_DOWNLOAD_SUCCESS:-true}"
WGET_DOWNLOAD_FILE="${WGET_DOWNLOAD_FILE:-${MOCK_DIR}/Logseq-linux-x64-0.10.15.AppImage}"
# Relativen Download-Pfad gegen das Fixtures-Verzeichnis auflösen (portable State-Dateien)
if [[ "${WGET_DOWNLOAD_FILE}" != /* ]]; then
WGET_DOWNLOAD_FILE="${MOCK_DIR}/${WGET_DOWNLOAD_FILE}"
fi
case "$*" in
*releases/latest*)
# Simuliere GitHub Release-Seite