"""Tests for the watchlist module.""" from __future__ import annotations import json import os import pytest from scanner import paths from scanner.watchlist import ( MAX_WATCHLIST, load_watchlist, parse_tickers, save_watchlist, ) def test_parse_simple(): assert parse_tickers("AAPL, MSFT, NVDA") == ["AAPL", "MSFT", "NVDA"] def test_parse_mixed_delimiters(): assert parse_tickers("AAPL MSFT;NVDA\nTSLA, , META") == [ "AAPL", "MSFT", "NVDA", "TSLA", "META"] def test_parse_lowercase_and_dedup(): assert parse_tickers("aapl, AAPL, msft") == ["AAPL", "MSFT"] def test_parse_rejects_invalid_symbols(): # Starts with digit -> rejected; too long -> rejected assert parse_tickers("AAPL, 1MSFT, ABCDEFGHIJK, NVDA") == ["AAPL", "NVDA"] def test_parse_empty_or_none(): assert parse_tickers(None) == [] assert parse_tickers("") == [] assert parse_tickers(" ") == [] def test_parse_caps_at_max(): many = ", ".join(f"TKR{i}" for i in range(MAX_WATCHLIST + 50)) out = parse_tickers(many) assert len(out) == MAX_WATCHLIST def test_save_and_load_round_trip(): saved = save_watchlist(["aapl", "MSFT", "nvda"]) assert saved == ["AAPL", "MSFT", "NVDA"] assert os.path.exists(paths.WATCHLIST_PATH) assert load_watchlist() == ["AAPL", "MSFT", "NVDA"] def test_load_missing_returns_empty(): assert load_watchlist() == [] def test_load_malformed_returns_empty(): with open(paths.WATCHLIST_PATH, "w", encoding="utf-8") as fh: fh.write("not json") assert load_watchlist() == []