Stop tracking personal workflow artifacts at repo root, add CI and MIT license, align README and agent skills with artifacts/ defaults, and enable Ruff in dev/CI so releases are verifiable without local-only runs. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
171 lines
6.4 KiB
Python
171 lines
6.4 KiB
Python
"""Tests for the parse CLI command."""
|
|
|
|
import json
|
|
|
|
from click.testing import CliRunner
|
|
|
|
from vlm.cli import main
|
|
|
|
|
|
class TestParseCommand:
|
|
"""Tests for vlm parse command."""
|
|
|
|
def test_parse_without_inventory_v1_schema(self, tmp_path):
|
|
"""Test parse without --inventory flag produces v1 schema."""
|
|
# Create a simple inventory CSV (without metadata)
|
|
inventory_csv = tmp_path / "inventory.csv"
|
|
inventory_csv.write_text(
|
|
"# vlm inventory\n"
|
|
"path,filename,size_bytes,modified_timestamp,category,resolution,codec,duration_seconds,bitrate_kbps\n"
|
|
"/library/movie/Matrix (1999).mkv,Matrix (1999).mkv,1000000,2024-01-01T00:00:00,movie,,,\n"
|
|
"/library/series/Breaking Bad S01E01.mkv,Breaking Bad S01E01.mkv,500000,2024-01-02T00:00:00,series,,,\n"
|
|
)
|
|
|
|
output_json = tmp_path / "identities.json"
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
main,
|
|
[
|
|
"--config",
|
|
str(tmp_path / "config.yaml"),
|
|
"parse",
|
|
"--input",
|
|
str(inventory_csv),
|
|
"--output",
|
|
str(output_json),
|
|
],
|
|
)
|
|
|
|
# Command should succeed
|
|
assert result.exit_code == 0
|
|
|
|
# Load output and verify v1 schema (no version field or version is 1.0)
|
|
with open(output_json) as f:
|
|
data = json.load(f)
|
|
|
|
# v1 schema - no vlm_schema_version or it's "1.0"
|
|
assert data.get("vlm_schema_version", "1.0") == "1.0"
|
|
|
|
# Verify no video_metadata in records
|
|
if data.get("movies"):
|
|
for movie in data["movies"]:
|
|
assert "video_metadata" not in movie
|
|
if data.get("series"):
|
|
for series in data["series"]:
|
|
assert "video_metadata" not in series
|
|
|
|
def test_parse_with_inventory_v2_schema(self, tmp_path):
|
|
"""Test parse with --inventory flag produces v2 schema with embedded metadata."""
|
|
# Create inventory CSV with full metadata
|
|
inventory_csv = tmp_path / "inventory.csv"
|
|
inventory_csv.write_text(
|
|
"# vlm inventory\n"
|
|
"path,filename,size_bytes,modified_timestamp,category,resolution,codec,duration_seconds,bitrate_kbps\n"
|
|
"/library/movie/Matrix (1999).mkv,Matrix (1999).mkv,2000000000,2024-01-01T10:00:00+00:00,movie,1920x1080,h264,7200.5,5000\n"
|
|
"/library/series/Breaking Bad S01E01.mkv,Breaking Bad S01E01.mkv,500000000,2024-01-02T15:00:00+00:00,series,1280x720,h264,2700.0,3000\n"
|
|
)
|
|
|
|
output_json = tmp_path / "identities.json"
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
main,
|
|
[
|
|
"--config",
|
|
str(tmp_path / "config.yaml"),
|
|
"parse",
|
|
"--input",
|
|
str(inventory_csv),
|
|
"--output",
|
|
str(output_json),
|
|
"--inventory",
|
|
str(inventory_csv),
|
|
],
|
|
)
|
|
|
|
# Command should succeed
|
|
assert result.exit_code == 0
|
|
assert "Loading video metadata from:" in result.output
|
|
assert "Loaded metadata for 2 files" in result.output
|
|
|
|
# Load output and verify v2 schema
|
|
with open(output_json) as f:
|
|
data = json.load(f)
|
|
|
|
# v2 schema version
|
|
assert data["vlm_schema_version"] == "2.0"
|
|
|
|
# Verify video_metadata embedded in movie record
|
|
assert len(data["movies"]) == 1
|
|
movie = data["movies"][0]
|
|
assert "video_metadata" in movie
|
|
assert movie["video_metadata"]["size_bytes"] == 2000000000
|
|
assert movie["video_metadata"]["resolution"] == "1920x1080"
|
|
assert movie["video_metadata"]["codec"] == "h264"
|
|
assert movie["video_metadata"]["duration_seconds"] == 7200.5
|
|
assert movie["video_metadata"]["bitrate_kbps"] == 5000
|
|
|
|
# Verify video_metadata embedded in series record
|
|
assert len(data["series"]) == 1
|
|
series = data["series"][0]
|
|
assert "video_metadata" in series
|
|
assert series["video_metadata"]["size_bytes"] == 500000000
|
|
assert series["video_metadata"]["resolution"] == "1280x720"
|
|
assert series["video_metadata"]["codec"] == "h264"
|
|
assert series["video_metadata"]["duration_seconds"] == 2700.0
|
|
assert series["video_metadata"]["bitrate_kbps"] == 3000
|
|
|
|
def test_parse_with_inventory_partial_metadata(self, tmp_path):
|
|
"""Test parse with inventory that has partial metadata."""
|
|
# Create inventory with some files having metadata, some not
|
|
inventory_csv = tmp_path / "inventory.csv"
|
|
inventory_csv.write_text(
|
|
"# vlm inventory\n"
|
|
"path,filename,size_bytes,modified_timestamp,category,resolution,codec,duration_seconds,bitrate_kbps\n"
|
|
"/library/movie/Matrix (1999).mkv,Matrix (1999).mkv,2000000000,2024-01-01T10:00:00+00:00,movie,1920x1080,h264,,\n"
|
|
"/library/movie/Inception (2010).mkv,Inception (2010).mkv,1500000000,2024-01-02T10:00:00+00:00,movie,,,\n"
|
|
)
|
|
|
|
output_json = tmp_path / "identities.json"
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(
|
|
main,
|
|
[
|
|
"--config",
|
|
str(tmp_path / "config.yaml"),
|
|
"parse",
|
|
"--input",
|
|
str(inventory_csv),
|
|
"--output",
|
|
str(output_json),
|
|
"--inventory",
|
|
str(inventory_csv),
|
|
],
|
|
)
|
|
|
|
# Command should succeed
|
|
assert result.exit_code == 0
|
|
|
|
# Load output and verify
|
|
with open(output_json) as f:
|
|
data = json.load(f)
|
|
|
|
assert data["vlm_schema_version"] == "2.0"
|
|
assert len(data["movies"]) == 2
|
|
|
|
# First movie has partial metadata
|
|
movie1 = data["movies"][0]
|
|
assert movie1["video_metadata"]["size_bytes"] == 2000000000
|
|
assert movie1["video_metadata"]["resolution"] == "1920x1080"
|
|
assert movie1["video_metadata"]["codec"] == "h264"
|
|
assert movie1["video_metadata"]["duration_seconds"] is None
|
|
assert movie1["video_metadata"]["bitrate_kbps"] is None
|
|
|
|
# Second movie has minimal metadata
|
|
movie2 = data["movies"][1]
|
|
assert movie2["video_metadata"]["size_bytes"] == 1500000000
|
|
assert movie2["video_metadata"]["resolution"] is None
|
|
assert movie2["video_metadata"]["codec"] is None
|