| """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(): |
| |
| 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() == [] |
|
|