Coverage for tests/test_main.py: 96%
52 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-22 22:47 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-22 22:47 +0000
1"""Tests for exporting the FJC's files and the command line."""
3from __future__ import annotations
5import pathlib
6import warnings
8import pandas as pd
9from conftest import SERVICE, tables
11import fjc_biographies
12from fjc_biographies import __main__ as cli
14# Where the tests save the roster of the invented judges in both formats, to
15# be looked at. The folder is not in the repository (see ".gitignore").
16OUTPUT = pathlib.Path(__file__).parent / 'output'
19def test_save_both_formats(tmp_path: pathlib.Path) -> None:
20 files = tables()
21 roster = fjc_biographies.build_roster(
22 files['service'], files['demographics'], files['career'])
23 formats = {
24 'roster_by_appointment.csv': roster,
25 'roster_by_judge.csv': fjc_biographies.roster_by_judge(roster)}
26 saved = {
27 name: pd.read_csv(fjc_biographies.export(table, tmp_path / name))
28 for name, table in formats.items()}
29 assert len(saved['roster_by_appointment.csv']) == len(SERVICE)
30 assert saved['roster_by_judge.csv']['nid'].is_unique
31 # The career text is kept in both files, with its line breaks.
32 for table in saved.values():
33 lynch = table.loc[table['nid'] == 101, 'career'].iloc[0]
34 assert lynch.splitlines()[1].startswith('Assistant attorney general')
35 # A file that is open in a spreadsheet (which locks it on Windows) is
36 # not replaced, which is not a failure of the package.
37 for name, table in formats.items():
38 try:
39 fjc_biographies.export(table, OUTPUT / name)
40 except PermissionError:
41 warnings.warn(
42 f'{OUTPUT / name} was not replaced because it is open in '
43 f'another program, such as Excel: close it and run the tests '
44 f'again to see the latest version',
45 stacklevel = 1)
48def test_version() -> None:
49 assert fjc_biographies.__version__ == '0.1.0'
52def test_run(requests: list[str], data_folder: pathlib.Path) -> None:
53 paths = fjc_biographies.run()
54 assert list(paths) == [
55 'demographics', 'service', 'other_service', 'education', 'career',
56 'other_nominations', 'roster_by_appointment', 'roster_by_judge']
57 assert paths['roster_by_appointment'] == data_folder / 'roster_by_appointment.csv'
58 roster = pd.read_csv(paths['roster_by_appointment'])
59 assert len(roster) == len(SERVICE)
60 by_judge = pd.read_csv(paths['roster_by_judge'])
61 assert len(by_judge) == len({row[0] for row in SERVICE})
62 assert by_judge.loc[by_judge['nid'] == 107, 'court_2'].iloc[0].endswith('First Circuit')
63 # Dates are written without times.
64 assert roster.loc[0, 'start_date'] == '1995-03-17'
65 service = pd.read_csv(paths['service'])
66 assert service.loc[0, 'commission_date'] == '1995-03-17'
67 assert len(requests) == 6
68 fjc_biographies.run(update = True)
69 assert len(requests) == 12
72def test_cli(requests: list[str], tmp_path: pathlib.Path) -> None:
73 cli.main(['--data-folder', str(tmp_path)])
74 assert (tmp_path / 'roster_by_appointment.csv').is_file()
75 assert (tmp_path / 'roster_by_judge.csv').is_file()
76 assert len(requests) == 6
77 cli.main(['--data-folder', str(tmp_path), '--download-only', '--update'])
78 assert len(requests) == 12
81def test_cli_download_only(requests: list[str], data_folder: pathlib.Path) -> None:
82 cli.main(['--download-only'])
83 assert len(requests) == 6
84 assert not (data_folder / 'roster_by_judge.csv').exists()
85 assert (data_folder / 'raw' / 'demographics.csv').is_file()