Files
mixxx/test_export_import.py

183 lines
6.7 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Test d'intégration : export + import des cues Mixxx via les modules mixxx_export et mixxx_import.
Nécessite que mixxx_export.py et mixxx_import_gui.py (ou mixxx_import.py) soient dans le même répertoire,
ou ajustez les imports.
"""
import sqlite3
import tempfile
import os
import json
from pathlib import Path
import subprocess
import sys
# ------------------------------------------------------------
# 1. Créer une base Mixxx temporaire avec les bonnes tables
# ------------------------------------------------------------
def create_temp_db(db_path: Path):
con = sqlite3.connect(db_path)
con.executescript("""
CREATE TABLE track_locations (
id INTEGER PRIMARY KEY,
location TEXT,
filename TEXT,
directory TEXT,
filesize INTEGER,
fs_deleted INTEGER DEFAULT 0,
needs_verification INTEGER DEFAULT 0
);
CREATE TABLE library (
id INTEGER PRIMARY KEY,
artist TEXT,
title TEXT,
album TEXT,
genre TEXT,
tracknumber INTEGER,
year INTEGER,
duration REAL,
samplerate INTEGER,
bitrate INTEGER,
channels INTEGER,
bpm REAL,
key TEXT,
rating INTEGER,
comment TEXT,
location INTEGER REFERENCES track_locations(id) -- clé manquante dans l'exemple précédent
);
CREATE TABLE cues (
id INTEGER PRIMARY KEY,
track_id INTEGER,
type INTEGER,
position REAL,
length REAL,
hotcue INTEGER,
label TEXT,
color INTEGER
);
CREATE TABLE IF NOT EXISTS Playlists (
id INTEGER PRIMARY KEY,
name TEXT,
position INTEGER,
hidden INTEGER DEFAULT 0,
date_created TEXT,
date_modified TEXT
);
CREATE TABLE IF NOT EXISTS PlaylistTracks (
id INTEGER PRIMARY KEY,
playlist_id INTEGER,
track_id INTEGER,
position INTEGER,
pl_datetime_added TEXT
);
""")
con.commit()
return con
# ------------------------------------------------------------
# 2. Insérer des données de test
# ------------------------------------------------------------
def populate_test_data(con, audio_file_path: Path):
# Une piste "test.flac"
tl_id = 1
con.execute("""
INSERT INTO track_locations (id, location, filename, directory, filesize)
VALUES (?, ?, ?, ?, ?)
""", (tl_id, str(audio_file_path), audio_file_path.name, str(audio_file_path.parent), 12345))
con.execute("""
INSERT INTO library (id, artist, title, album, genre, year, duration, location)
VALUES (?, 'Test', 'Ma Chanson', '', '', 2025, 200, ?)
""", (tl_id, tl_id)) # location pointe vers track_locations.id
# Deux hot cues
con.execute("INSERT INTO cues (track_id, type, position, length, hotcue, label, color) VALUES (?,1,10.5,0,1,'Intro',16744448)", (tl_id,))
con.execute("INSERT INTO cues (track_id, type, position, length, hotcue, label, color) VALUES (?,1,45.0,0,2,'Drop',0xFF8000)", (tl_id,))
# Une boucle (type=4)
con.execute("INSERT INTO cues (track_id, type, position, length, hotcue, label, color) VALUES (?,4,60.0,15.0,-1,'',0)", (tl_id,))
con.commit()
# ------------------------------------------------------------
# 3. Fonctions de test
# ------------------------------------------------------------
def run_export(db_path: Path, output_dir: Path):
# Utiliser le module mixxx_export directement
import mixxx_export
mixxx_export.export_cues(db_path, output_dir)
def run_import(music_dir: Path, db_path: Path, dry_run=False):
# Utiliser le module mixxx_import (v2)
import mixxx_import
mixxx_import.import_cues_v2(music_dir, db_path, dry_run=dry_run, log_callback=print)
def main():
with tempfile.TemporaryDirectory() as tmpdir:
tmp = Path(tmpdir)
db_path = tmp / "test_mixxxdb.sqlite"
audio_dir = tmp / "music"
audio_dir.mkdir()
audio_file = audio_dir / "test.flac"
audio_file.write_text("fake audio") # fichier factice
# 1. Créer DB et peupler
con = create_temp_db(db_path)
populate_test_data(con, audio_file)
con.close()
# 2. Exporter les cues dans un sous-dossier
export_dir = tmp / "export"
export_dir.mkdir()
run_export(db_path, export_dir)
expected_json = export_dir / "test.flac.mixxx"
assert expected_json.exists(), "Le fichier .mixxx n'a pas été créé"
with open(expected_json, "r") as f:
data = json.load(f)
assert data["version"] == 1
assert data["filename"] == "test.flac"
assert len(data["cues"]) == 3
print("[PASS] Export OK")
# 3. Préparer l'import : copier le .mixxx dans le dossier audio
import_audio_dir = tmp / "import"
import_audio_dir.mkdir()
import_audio_file = import_audio_dir / "test.flac"
import_audio_file.write_text("fake audio") # recréer le fichier audio
import_json = import_audio_dir / "test.flac.mixxx"
import_json.write_text(expected_json.read_text())
# Créer une nouvelle DB vierge pour l'import (même structure)
fresh_db = tmp / "fresh_mixxxdb.sqlite"
create_temp_db(fresh_db).close()
# 4. Importer
run_import(import_audio_dir, fresh_db, dry_run=False)
# 5. Vérifier que les cues ont été insérés
con = sqlite3.connect(fresh_db)
con.row_factory = sqlite3.Row
# Vérifier la piste
tl = con.execute("SELECT * FROM track_locations WHERE filename='test.flac'").fetchone()
assert tl is not None, "Piste non importée"
track_id = tl["id"]
# Vérifier les cues
cues = con.execute("SELECT * FROM cues WHERE track_id=?", (track_id,)).fetchall()
assert len(cues) == 3, f"Nombre de cues incorrect : {len(cues)} au lieu de 3"
# Vérifier les types
types = {c["type"] for c in cues}
assert types == {1, 4}, f"Types de cues inattendus: {types}"
print("[PASS] Import OK")
# 6. Test dry-run
# Créer une autre DB vide pour simuler
dry_db = tmp / "dry_db.sqlite"
create_temp_db(dry_db).close()
run_import(import_audio_dir, dry_db, dry_run=True)
con = sqlite3.connect(dry_db)
cues_dry = con.execute("SELECT count(*) FROM cues").fetchone()[0]
assert cues_dry == 0, "Le dry-run a écrit des données !"
print("[PASS] Dry-run OK")
print("\n✅ Tous les tests ont réussi !")
if __name__ == "__main__":
main()