mirror of
https://github.com/beetbox/beets.git
synced 2026-02-08 16:34:12 +01:00
189 lines
5.2 KiB
Python
189 lines
5.2 KiB
Python
# This file is part of beets.
|
||
#
|
||
# Permission is hereby granted, free of charge, to any person obtaining
|
||
# a copy of this software and associated documentation files (the
|
||
# "Software"), to deal in the Software without restriction, including
|
||
# without limitation the rights to use, copy, modify, merge, publish,
|
||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||
# permit persons to whom the Software is furnished to do so, subject to
|
||
# the following conditions:
|
||
#
|
||
# The above copyright notice and this permission notice shall be
|
||
# included in all copies or substantial portions of the Software.
|
||
|
||
import pytest
|
||
|
||
from beets.library import Item, Library
|
||
from beets.ui.commands.stats import show_overview_report
|
||
|
||
|
||
# --- Fixtures ---
|
||
@pytest.fixture
|
||
def library(tmp_path):
|
||
"""Create a temporary empty Beets library."""
|
||
lib_path = tmp_path / "beets.db"
|
||
lib = Library(str(lib_path))
|
||
return lib
|
||
|
||
|
||
def add_item(
|
||
lib,
|
||
title="Test",
|
||
artist="Artist",
|
||
album="Album",
|
||
genre="Genre",
|
||
year=2000,
|
||
length=180,
|
||
bitrate=320000,
|
||
format="MP3",
|
||
):
|
||
"""Add a single Item to the test library."""
|
||
item = Item(
|
||
path=f"/tmp/{title}.mp3",
|
||
title=title,
|
||
artist=artist,
|
||
album=album,
|
||
genre=genre,
|
||
year=year,
|
||
length=length,
|
||
bitrate=bitrate,
|
||
format=format,
|
||
)
|
||
lib.add(item)
|
||
|
||
|
||
# --- Tests for show_overview_report ---
|
||
|
||
|
||
def test_empty_library_overview(capsys, library):
|
||
"""Test empty library with overview report."""
|
||
show_overview_report(library, [])
|
||
captured = capsys.readouterr()
|
||
assert "Your Beets library is empty." in captured.out
|
||
|
||
|
||
def test_single_item_overview(capsys, library):
|
||
"""Test library with a single track using overview report."""
|
||
|
||
add_item(
|
||
library,
|
||
title="Single Track",
|
||
artist="Solo Artist",
|
||
genre="Indie",
|
||
year=2019,
|
||
bitrate=256000,
|
||
)
|
||
|
||
show_overview_report(library, [])
|
||
captured = capsys.readouterr()
|
||
|
||
# --- Check basic statistics ---
|
||
# Format is "Tracks: X" (3 spaces after colon)
|
||
assert "Tracks: 1" in captured.out
|
||
assert "Albums: 1" in captured.out
|
||
assert "Artists: 1" in captured.out
|
||
assert "Genres: 1" in captured.out
|
||
|
||
# --- Wrapped-style insights ---
|
||
assert "Top artist: Solo Artist (1 tracks)" in captured.out
|
||
assert "Top genre: Indie (1 tracks)" in captured.out
|
||
|
||
# Decade format: "10s (2010-2019): 1 tracks (100.0%)"
|
||
assert "10s (2010-2019" in captured.out
|
||
assert "1 tracks" in captured.out
|
||
|
||
# Year format
|
||
assert "Top year: 2019 (1 tracks)" in captured.out
|
||
|
||
|
||
def test_multiple_items_overview(capsys, library):
|
||
"""Test library with multiple tracks using overview report."""
|
||
|
||
# 1995 – 2 tracks Rock
|
||
add_item(library, "Track1", "Artist A", "Album X", "Rock", 1995)
|
||
add_item(library, "Track2", "Artist A", "Album X", "Rock", 1995)
|
||
|
||
# 2002 – 1 track Pop
|
||
add_item(library, "Track3", "Artist B", "Album Y", "Pop", 2002)
|
||
|
||
# 2018 – 1 track Electronic
|
||
add_item(library, "Track4", "Artist C", "Album Z", "Electronic", 2018)
|
||
|
||
show_overview_report(library, [])
|
||
captured = capsys.readouterr()
|
||
|
||
# --- Basic stats ---
|
||
assert "Tracks: 4" in captured.out
|
||
assert "Albums: 3" in captured.out
|
||
assert "Artists: 3" in captured.out
|
||
assert "Genres: 3" in captured.out
|
||
|
||
# --- Wrapped insights ---
|
||
assert "Top artist: Artist A (2 tracks)" in captured.out
|
||
assert "Top genre: Rock (2 tracks)" in captured.out
|
||
|
||
# Decade format check
|
||
assert "90s (1990-1999" in captured.out
|
||
assert "2 tracks" in captured.out
|
||
|
||
# Year format
|
||
assert "Top year: 1995 (2 tracks)" in captured.out
|
||
|
||
# --- Decade distribution ---
|
||
assert "90s (1990-1999" in captured.out
|
||
assert "00s (2000-2009" in captured.out
|
||
assert "10s (2010-2019" in captured.out
|
||
|
||
|
||
def test_missing_metadata_overview(capsys, library):
|
||
"""Test library with missing tags using overview report."""
|
||
|
||
# Missing genre
|
||
add_item(
|
||
library,
|
||
"Track1",
|
||
"Artist",
|
||
"Album",
|
||
None,
|
||
2000,
|
||
length=200,
|
||
bitrate=256000,
|
||
)
|
||
# Missing year
|
||
add_item(
|
||
library,
|
||
"Track2",
|
||
"Artist",
|
||
"Album",
|
||
"Rock",
|
||
None,
|
||
length=180,
|
||
bitrate=256000,
|
||
)
|
||
|
||
show_overview_report(library, [])
|
||
captured = capsys.readouterr()
|
||
|
||
# Format has 2 spaces after colon for year tags
|
||
assert "Missing genre tags: 1" in captured.out
|
||
assert "Missing year tags: 1" in captured.out
|
||
|
||
|
||
def test_various_lengths_and_bitrates_overview(capsys, library):
|
||
"""Test track lengths and bitrate classification."""
|
||
|
||
add_item(library, "Short", "A", "X", "Pop", 2010, length=60, bitrate=128000)
|
||
add_item(
|
||
library, "Long", "B", "Y", "Rock", 2015, length=3600, bitrate=1024000
|
||
)
|
||
|
||
show_overview_report(library, [])
|
||
captured = capsys.readouterr()
|
||
|
||
# --- Check durations ---
|
||
assert "Total playtime:" in captured.out
|
||
assert "Avg track length:" in captured.out
|
||
|
||
# --- Check bitrate and quality classification ---
|
||
assert "Avg bitrate:" in captured.out
|
||
assert "kbps" in captured.out
|