Coverage report: 98%

Files Functions Classes

coverage.py v7.16.2, created at 2026-11-13 19:28 +0000

File function   statements missing excluded   coverage
src/data_api/__init__.py (no function)   2 0 0   100%
src/data_api/api/__init__.py (no function)   1 0 0   100%
src/data_api/api/api.py lifespan   11 0 0   100%
src/data_api/api/api.py combined_lifespan   3 0 0   100%
src/data_api/api/api.py _SafeUnexpectedErrorsMiddleware.__init__   1 0 0   100%
src/data_api/api/api.py _SafeUnexpectedErrorsMiddleware.__call__   12 0 0   100%
src/data_api/api/api.py _SafeUnexpectedErrorsMiddleware.__call__.track_response   3 0 0   100%
src/data_api/api/api.py create_app   37 0 0   100%
src/data_api/api/api.py create_app.dataset_unavailable   1 0 0   100%
src/data_api/api/api.py create_app.upstream_failure   2 0 0   100%
src/data_api/api/api.py create_app.internal_error   2 2 0   0%
src/data_api/api/api.py create_app.add_process_time_header   5 0 0   100%
src/data_api/api/api.py create_app.metadata   1 0 0   100%
src/data_api/api/api.py create_app.favicon   2 2 0   0%
src/data_api/api/api.py (no function)   27 0 0   100%
src/data_api/api/errors.py service_errors   7 0 0   100%
src/data_api/api/errors.py (no function)   8 0 0   100%
src/data_api/api/main.py (no function)   5 5 0   0%
src/data_api/api/routers/__init__.py (no function)   2 0 0   100%
src/data_api/api/routers/announcements.py get_announcements   6 0 0   100%
src/data_api/api/routers/announcements.py get_announcements_list   4 0 0   100%
src/data_api/api/routers/announcements.py (no function)   9 0 0   100%
src/data_api/api/routers/buses.py add_custom_header   4 0 0   100%
src/data_api/api/routers/buses.py get_current_time_state   2 0 0   100%
src/data_api/api/routers/buses.py _query_bus_schedule   6 0 0   100%
src/data_api/api/routers/buses.py get_bus_route_metadata   2 0 0   100%
src/data_api/api/routers/buses.py get_bus_stops_information   2 0 0   100%
src/data_api/api/routers/buses.py get_bus_schedule   1 0 0   100%
src/data_api/api/routers/buses.py (no function)   19 0 0   100%
src/data_api/api/routers/calendars.py get_all_calendars   4 0 0   100%
src/data_api/api/routers/calendars.py get_calendar   6 0 0   100%
src/data_api/api/routers/calendars.py search_calendar_events   9 0 0   100%
src/data_api/api/routers/calendars.py get_calendar_event   6 0 0   100%
src/data_api/api/routers/calendars.py (no function)   17 0 0   100%
src/data_api/api/routers/courses.py latest_snapshot   1 0 0   100%
src/data_api/api/routers/courses.py semester_snapshot   4 0 0   100%
src/data_api/api/routers/courses.py counted_response   4 0 0   100%
src/data_api/api/routers/courses.py filter_courses   11 0 0   100%
src/data_api/api/routers/courses.py query_courses   4 0 0   100%
src/data_api/api/routers/courses.py get_courses   1 0 0   100%
src/data_api/api/routers/courses.py get_semesters   2 0 0   100%
src/data_api/api/routers/courses.py search_courses_by_condition   1 0 0   100%
src/data_api/api/routers/courses.py get_semester_courses   1 0 0   100%
src/data_api/api/routers/courses.py query_semester_courses   1 0 0   100%
src/data_api/api/routers/courses.py (no function)   33 0 0   100%
src/data_api/api/routers/dining.py get_dining_data   6 0 0   100%
src/data_api/api/routers/dining.py (no function)   7 0 0   100%
src/data_api/api/routers/directory.py get_directory   4 0 0   100%
src/data_api/api/routers/directory.py (no function)   8 0 0   100%
src/data_api/api/routers/energy.py get_realtime_electricity_usage   2 0 0   100%
src/data_api/api/routers/energy.py (no function)   8 0 0   100%
src/data_api/api/routers/libraries.py get_library_space_availability   2 0 0   100%
src/data_api/api/routers/libraries.py get_library_lost_and_found_items   2 0 0   100%
src/data_api/api/routers/libraries.py get_library_rss_data   6 0 0   100%
src/data_api/api/routers/libraries.py (no function)   14 0 0   100%
src/data_api/api/routers/locations.py get_locations   6 0 0   100%
src/data_api/api/routers/locations.py (no function)   8 0 0   100%
src/data_api/api/routers/newsletters.py get_all_newsletters   4 0 0   100%
src/data_api/api/routers/newsletters.py get_newsletter_sources   4 0 0   100%
src/data_api/api/routers/newsletters.py (no function)   9 0 0   100%
src/data_api/api/routers/ping.py _build_dataset_health   5 0 0   100%
src/data_api/api/routers/ping.py _readiness_status   3 0 0   100%
src/data_api/api/routers/ping.py ping   9 0 0   100%
src/data_api/api/routers/ping.py ping_head   4 0 0   100%
src/data_api/api/routers/ping.py (no function)   14 0 0   100%
src/data_api/api/schemas/__init__.py (no function)   2 0 0   100%
src/data_api/api/schemas/announcements.py (no function)   2 0 0   100%
src/data_api/api/schemas/buses.py (no function)   8 0 0   100%
src/data_api/api/schemas/calendars.py (no function)   2 0 0   100%
src/data_api/api/schemas/courses.py (no function)   2 0 0   100%
src/data_api/api/schemas/departments.py (no function)   2 0 0   100%
src/data_api/api/schemas/dining.py (no function)   2 0 0   100%
src/data_api/api/schemas/energy.py (no function)   7 0 0   100%
src/data_api/api/schemas/errors.py (no function)   9 0 0   100%
src/data_api/api/schemas/libraries.py (no function)   2 0 0   100%
src/data_api/api/schemas/locations.py (no function)   5 0 0   100%
src/data_api/api/schemas/meta.py (no function)   2 0 0   100%
src/data_api/api/schemas/newsletters.py (no function)   2 0 0   100%
src/data_api/api/schemas/ping.py (no function)   18 0 0   100%
src/data_api/api/schemas/responses.py (no function)   5 0 0   100%
src/data_api/checks/__init__.py (no function)   0 0 0   100%
src/data_api/checks/common.py CheckFailure.__str__   1 0 0   100%
src/data_api/checks/common.py fetch_json   20 0 0   100%
src/data_api/checks/common.py validation_reason   1 0 0   100%
src/data_api/checks/common.py report   7 0 0   100%
src/data_api/checks/common.py (no function)   12 0 0   100%
src/data_api/checks/mcp.py structural   5 0 0   100%
src/data_api/checks/mcp.py tool_contract   3 0 0   100%
src/data_api/checks/mcp.py main   12 12 0   0%
src/data_api/checks/mcp.py (no function)   13 1 0   92%
src/data_api/checks/openapi.py contract_projection   9 1 0   89%
src/data_api/checks/openapi.py contract_projection.strip_docs   5 0 0   100%
src/data_api/checks/openapi.py contract_differences   9 0 0   100%
src/data_api/checks/openapi.py main   14 14 0   0%
src/data_api/checks/openapi.py (no function)   12 1 0   92%
src/data_api/checks/published.py _check_serialization   14 3 0   79%
src/data_api/checks/published.py _check_download   14 2 0   86%
src/data_api/checks/published.py _check_local_responses   24 3 0   88%
src/data_api/checks/published.py _check_local_responses.serve_downloaded   4 1 0   75%
src/data_api/checks/published.py check_published   34 0 0   100%
src/data_api/checks/published.py run   2 2 0   0%
src/data_api/checks/published.py main   7 7 0   0%
src/data_api/checks/published.py (no function)   26 1 0   96%
src/data_api/checks/release.py version_tuple   3 0 0   100%
src/data_api/checks/release.py validate_version   10 0 0   100%
src/data_api/checks/release.py _resolve_context   9 0 0   100%
src/data_api/checks/release.py _is_new_constraint_or_required_input   6 1 0   83%
src/data_api/checks/release.py _child_context   11 0 0   100%
src/data_api/checks/release.py _should_skip_shared_key   3 0 0   100%
src/data_api/checks/release.py _dict_breaking_changes   11 0 0   100%
src/data_api/checks/release.py breaking_changes   8 0 0   100%
src/data_api/checks/release.py git_file   3 3 0   0%
src/data_api/checks/release.py initial_version_is_unpublished   12 0 0   100%
src/data_api/checks/release.py compare_base   17 1 0   94%
src/data_api/checks/release.py main   16 16 0   0%
src/data_api/checks/release.py (no function)   28 1 0   96%
src/data_api/checks/smoke.py _validate_endpoint_headers   11 0 0   100%
src/data_api/checks/smoke.py check_endpoints   12 0 0   100%
src/data_api/checks/smoke.py check_smoke   20 0 0   100%
src/data_api/checks/smoke.py run   2 2 0   0%
src/data_api/checks/smoke.py main   7 7 0   0%
src/data_api/checks/smoke.py (no function)   33 1 0   97%
src/data_api/core/__init__.py (no function)   1 0 0   100%
src/data_api/core/config.py (no function)   1 0 0   100%
src/data_api/core/exceptions.py (no function)   15 0 0   100%
src/data_api/core/settings.py (no function)   15 0 0   100%
src/data_api/core/upstream.py live_client   4 0 0   100%
src/data_api/core/upstream.py upstream_errors   8 0 0   100%
src/data_api/core/upstream.py (no function)   11 0 0   100%
src/data_api/data/__init__.py (no function)   2 0 0   100%
src/data_api/data/manager.py (no function)   3 0 0   100%
src/data_api/data/nthudata.py FetchFailure.__init__   3 0 0   100%
src/data_api/data/nthudata.py DatasetState.usable   1 0 0   100%
src/data_api/data/nthudata.py DataFetcher.__init__   2 0 0   100%
src/data_api/data/nthudata.py DataFetcher.fetch_json   27 0 0   100%
src/data_api/data/nthudata.py ManifestEntry.active_version   1 0 0   100%
src/data_api/data/nthudata.py parse_manifest   12 0 0   100%
src/data_api/data/nthudata.py FileDetailsManager.__init__   9 0 0   100%
src/data_api/data/nthudata.py FileDetailsManager.check   18 1 0   94%
src/data_api/data/nthudata.py NTHUDataManager.__init__   9 1 0   89%
src/data_api/data/nthudata.py NTHUDataManager.register   6 1 0   83%
src/data_api/data/nthudata.py NTHUDataManager.lifespan   9 1 0   89%
src/data_api/data/nthudata.py NTHUDataManager.reset   10 0 0   100%
src/data_api/data/nthudata.py NTHUDataManager.state_for   6 0 0   100%
src/data_api/data/nthudata.py NTHUDataManager.get_snapshot   12 0 0   100%
src/data_api/data/nthudata.py NTHUDataManager._record_load_failure   4 0 0   100%
src/data_api/data/nthudata.py NTHUDataManager._install_snapshot   6 0 0   100%
src/data_api/data/nthudata.py NTHUDataManager._refresh   28 0 0   100%
src/data_api/data/nthudata.py NTHUDataManager._load_candidate   12 1 0   92%
src/data_api/data/nthudata.py NTHUDataManager.get   2 0 0   100%
src/data_api/data/nthudata.py NTHUDataManager.prefetch   6 0 0   100%
src/data_api/data/nthudata.py NTHUDataManager.prefetch.load   5 0 0   100%
src/data_api/data/nthudata.py NTHUDataManager._normalize_endpoint_name   1 0 0   100%
src/data_api/data/nthudata.py (no function)   79 0 0   100%
src/data_api/data/validation.py _adapters   1 0 0   100%
src/data_api/data/validation.py _validate_calendar_events   8 0 0   100%
src/data_api/data/validation.py _normalize_library_rss   9 0 0   100%
src/data_api/data/validation.py _validate_calendars   5 0 0   100%
src/data_api/data/validation.py validate_dataset   12 0 0   100%
src/data_api/data/validation.py (no function)   25 0 0   100%
src/data_api/domain/__init__.py (no function)   2 0 0   100%
src/data_api/domain/announcements/__init__.py (no function)   2 0 0   100%
src/data_api/domain/announcements/services.py _matches_source_url   7 0 0   100%
src/data_api/domain/announcements/services.py _matches_source_url.split_url   4 0 0   100%
src/data_api/domain/announcements/services.py AnnouncementsService.__init__   1 0 0   100%
src/data_api/domain/announcements/services.py AnnouncementsService.get_announcements   10 0 0   100%
src/data_api/domain/announcements/services.py AnnouncementsService.get_announcements_list   4 0 0   100%
src/data_api/domain/announcements/services.py AnnouncementsService._matches_fuzzy_source   9 0 0   100%
src/data_api/domain/announcements/services.py AnnouncementsService.fuzzy_search_announcements   15 0 0   100%
src/data_api/domain/announcements/services.py (no function)   18 0 0   100%
src/data_api/domain/buses/__init__.py (no function)   2 0 0   100%
src/data_api/domain/buses/adapters.py (no function)   1 0 0   100%
src/data_api/domain/buses/enums.py (no function)   29 0 0   100%
src/data_api/domain/buses/graph.py create_route   8 0 0   100%
src/data_api/domain/buses/graph.py RouteResolver.resolve_main_campus_route   11 0 0   100%
src/data_api/domain/buses/graph.py RouteResolver.resolve_nanda_route   4 0 0   100%
src/data_api/domain/buses/graph.py RouteResolver.get_nanda_line   8 0 0   100%
src/data_api/domain/buses/graph.py (no function)   25 0 0   100%
src/data_api/domain/buses/models.py (no function)   11 0 0   100%
src/data_api/domain/buses/query.py resolve_bus_time   4 0 0   100%
src/data_api/domain/buses/query.py (no function)   5 0 0   100%
src/data_api/domain/buses/services.py after_specific_time   18 5 0   72%
src/data_api/domain/buses/services.py _extract_nested_value   6 1 0   83%
src/data_api/domain/buses/services.py add_time   5 2 0   60%
src/data_api/domain/buses/services.py sort_by_time   2 0 0   100%
src/data_api/domain/buses/services.py sort_by_time.get_sort_key   7 3 0   57%
src/data_api/domain/buses/services.py PreparedBusData.__init__   5 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._new_schedule_store   1 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData.prepare   18 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._validate_schedule_rows   8 3 0   62%
src/data_api/domain/buses/services.py PreparedBusData._process_all_data   7 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._reset_registries   4 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._populate_info_data   5 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._populate_raw_schedule   8 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._get_schedule_json_key   6 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._enhance_schedule_item   7 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._enhance_nanda_schedule   2 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._track_gen2_departures_if_needed   6 5 0   17%
src/data_api/domain/buses/services.py PreparedBusData._classify_bus_type   5 1 0   80%
src/data_api/domain/buses/services.py PreparedBusData._generate_detailed_schedule_and_stops   9 1 0   89%
src/data_api/domain/buses/services.py PreparedBusData._create_detailed_schedule_entry   6 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._calculate_stop_arrival_times   5 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._get_route_from_graph   5 1 0   80%
src/data_api/domain/buses/services.py PreparedBusData._resolve_main_campus_route   6 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._resolve_nanda_route   2 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._sort_schedule_store   3 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._derive_combined_views   4 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._combine_route_types_for_store   5 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._combine_directions_for_store   5 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData.get_route_info   5 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData._find_stop_schedule   8 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData.get_schedule   5 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData.query_schedule   5 0 0   100%
src/data_api/domain/buses/services.py PreparedBusData.gen_bus_stops_info   1 0 0   100%
src/data_api/domain/buses/services.py BusesService.__init__   4 0 0   100%
src/data_api/domain/buses/services.py BusesService.update_data   2 0 0   100%
src/data_api/domain/buses/services.py BusesService.reset   2 0 0   100%
src/data_api/domain/buses/services.py BusesService.data   3 1 0   67%
src/data_api/domain/buses/services.py BusesService.raw_schedule_data   1 0 0   100%
src/data_api/domain/buses/services.py BusesService.get_route_info   1 0 0   100%
src/data_api/domain/buses/services.py BusesService.get_schedule   1 0 0   100%
src/data_api/domain/buses/services.py BusesService.query_schedule   1 0 0   100%
src/data_api/domain/buses/services.py (no function)   67 0 0   100%
src/data_api/domain/calendars/__init__.py (no function)   0 0 0   100%
src/data_api/domain/calendars/services.py CalendarsService.__init__   1 0 0   100%
src/data_api/domain/calendars/services.py CalendarsService.get_all_calendars   7 0 0   100%
src/data_api/domain/calendars/services.py CalendarsService._get_data   1 0 0   100%
src/data_api/domain/calendars/services.py CalendarsService._library_calendar   1 0 0   100%
src/data_api/domain/calendars/services.py CalendarsService.get_calendar   8 0 0   100%
src/data_api/domain/calendars/services.py CalendarsService.search_calendar_events   5 0 0   100%
src/data_api/domain/calendars/services.py CalendarsService.get_calendar_event   6 0 0   100%
src/data_api/domain/calendars/services.py (no function)   20 0 0   100%
src/data_api/domain/courses/__init__.py (no function)   2 0 0   100%
src/data_api/domain/courses/models.py field_values   10 1 0   90%
src/data_api/domain/courses/models.py Condition.__post_init__   3 0 0   100%
src/data_api/domain/courses/models.py Condition.check   7 0 0   100%
src/data_api/domain/courses/models.py validate_condition_sequence   8 0 0   100%
src/data_api/domain/courses/models.py Conditions.__init__   5 0 0   100%
src/data_api/domain/courses/models.py Conditions.__and__   1 0 0   100%
src/data_api/domain/courses/models.py Conditions.__or__   1 0 0   100%
src/data_api/domain/courses/models.py Conditions._prepare_sequence   7 0 0   100%
src/data_api/domain/courses/models.py Conditions._prepare_sequence.evaluate   5 0 0   100%
src/data_api/domain/courses/models.py Conditions._prepare   9 1 0   89%
src/data_api/domain/courses/models.py Conditions._predicate   1 0 0   100%
src/data_api/domain/courses/models.py Conditions.accept   1 0 0   100%
src/data_api/domain/courses/models.py (no function)   29 0 0   100%
src/data_api/domain/courses/services.py prepare_courses   7 0 0   100%
src/data_api/domain/courses/services.py prepare_catalog   1 0 0   100%
src/data_api/domain/courses/services.py CoursesService.__init__   4 0 0   100%
src/data_api/domain/courses/services.py CoursesService.get_semesters   1 0 0   100%
src/data_api/domain/courses/services.py CoursesService.get_snapshot   12 0 0   100%
src/data_api/domain/courses/services.py CoursesService.query   1 0 0   100%
src/data_api/domain/courses/services.py (no function)   18 0 0   100%
src/data_api/domain/departments/__init__.py (no function)   2 0 0   100%
src/data_api/domain/departments/services.py _department_match_score   4 0 0   100%
src/data_api/domain/departments/services.py _person_match_score   7 0 0   100%
src/data_api/domain/departments/services.py DepartmentsService.__init__   1 0 0   100%
src/data_api/domain/departments/services.py DepartmentsService.get_all_departments   1 0 0   100%
src/data_api/domain/departments/services.py DepartmentsService.get_directory   14 0 0   100%
src/data_api/domain/departments/services.py DepartmentsService.search_departments_and_people   15 0 0   100%
src/data_api/domain/departments/services.py (no function)   16 0 0   100%
src/data_api/domain/dining/__init__.py (no function)   2 0 0   100%
src/data_api/domain/dining/enums.py (no function)   15 0 0   100%
src/data_api/domain/dining/services.py is_restaurant_open   6 0 0   100%
src/data_api/domain/dining/services.py _filter_by_schedule   12 0 0   100%
src/data_api/domain/dining/services.py DiningService.__init__   1 0 0   100%
src/data_api/domain/dining/services.py DiningService.get_dining_data   11 0 0   100%
src/data_api/domain/dining/services.py DiningService.get_open_restaurants   2 0 0   100%
src/data_api/domain/dining/services.py DiningService.fuzzy_search_dining_data   18 0 0   100%
src/data_api/domain/dining/services.py (no function)   18 0 0   100%
src/data_api/domain/energy/__init__.py (no function)   2 0 0   100%
src/data_api/domain/energy/services.py fetch_electricity_data   12 0 0   100%
src/data_api/domain/energy/services.py EnergyService.__init__   1 0 0   100%
src/data_api/domain/energy/services.py EnergyService.get_realtime_electricity_usage   8 0 0   100%
src/data_api/domain/energy/services.py (no function)   14 0 0   100%
src/data_api/domain/libraries/__init__.py (no function)   2 0 0   100%
src/data_api/domain/libraries/services.py parse_lost_items   26 0 0   100%
src/data_api/domain/libraries/services.py LibrariesService.__init__   2 0 0   100%
src/data_api/domain/libraries/services.py LibrariesService.get_space_availability   14 0 0   100%
src/data_api/domain/libraries/services.py LibrariesService.get_lost_and_found_items   8 0 0   100%
src/data_api/domain/libraries/services.py LibrariesService.get_rss_items   2 0 0   100%
src/data_api/domain/libraries/services.py (no function)   25 0 0   100%
src/data_api/domain/locations/__init__.py (no function)   2 0 0   100%
src/data_api/domain/locations/services.py LocationsService.__init__   1 0 0   100%
src/data_api/domain/locations/services.py LocationsService.get_all_locations   1 1 0   0%
src/data_api/domain/locations/services.py LocationsService.get_locations   3 0 0   100%
src/data_api/domain/locations/services.py LocationsService.fuzzy_search_locations   10 0 0   100%
src/data_api/domain/locations/services.py (no function)   12 0 0   100%
src/data_api/domain/newsletters/__init__.py (no function)   2 0 0   100%
src/data_api/domain/newsletters/services.py NewslettersService.__init__   1 0 0   100%
src/data_api/domain/newsletters/services.py NewslettersService.get_all_newsletters   1 0 0   100%
src/data_api/domain/newsletters/services.py NewslettersService._matches_newsletter_name   5 0 0   100%
src/data_api/domain/newsletters/services.py NewslettersService._filter_newsletter_articles   5 0 0   100%
src/data_api/domain/newsletters/services.py NewslettersService.get_newsletters   10 0 0   100%
src/data_api/domain/newsletters/services.py NewslettersService.get_newsletter_sources   3 0 0   100%
src/data_api/domain/newsletters/services.py (no function)   17 0 0   100%
src/data_api/mcp/__init__.py (no function)   2 0 0   100%
src/data_api/mcp/errors.py live_tool_errors   8 0 0   100%
src/data_api/mcp/errors.py (no function)   8 0 0   100%
src/data_api/mcp/server.py DatasetErrors.on_call_tool   8 1 0   88%
src/data_api/mcp/server.py create_mcp   4 0 0   100%
src/data_api/mcp/server.py create_mcp.RuntimeBinding.on_call_tool   2 0 0   100%
src/data_api/mcp/server.py (no function)   13 0 2   100%
src/data_api/mcp/tools/__init__.py (no function)   10 0 0   100%
src/data_api/mcp/tools/announcements.py _get_announcements   7 0 0   100%
src/data_api/mcp/tools/announcements.py get_announcements   1 0 0   100%
src/data_api/mcp/tools/announcements.py (no function)   7 0 0   100%
src/data_api/mcp/tools/buses.py _get_bus_schedule   10 0 0   100%
src/data_api/mcp/tools/buses.py get_bus_schedule   1 0 0   100%
src/data_api/mcp/tools/buses.py (no function)   12 0 0   100%
src/data_api/mcp/tools/courses.py _search_courses   17 0 0   100%
src/data_api/mcp/tools/courses.py search_courses   1 0 0   100%
src/data_api/mcp/tools/courses.py (no function)   15 0 0   100%
src/data_api/mcp/tools/dining.py _find_dining   8 0 0   100%
src/data_api/mcp/tools/dining.py find_dining   1 0 0   100%
src/data_api/mcp/tools/dining.py (no function)   7 0 0   100%
src/data_api/mcp/tools/directory.py _search_directory   2 0 0   100%
src/data_api/mcp/tools/directory.py search_directory   1 0 0   100%
src/data_api/mcp/tools/directory.py (no function)   6 0 0   100%
src/data_api/mcp/tools/energy.py _get_energy_usage   8 0 0   100%
src/data_api/mcp/tools/energy.py get_energy_usage   1 0 0   100%
src/data_api/mcp/tools/energy.py (no function)   7 0 0   100%
src/data_api/mcp/tools/library.py _get_library_info   6 0 0   100%
src/data_api/mcp/tools/library.py get_library_info   1 0 0   100%
src/data_api/mcp/tools/library.py (no function)   10 0 0   100%
src/data_api/mcp/tools/locations.py _search_locations   6 0 0   100%
src/data_api/mcp/tools/locations.py search_locations   1 0 0   100%
src/data_api/mcp/tools/locations.py (no function)   6 0 0   100%
src/data_api/mcp/tools/newsletters.py _get_newsletters   2 0 0   100%
src/data_api/mcp/tools/newsletters.py get_newsletters   1 0 0   100%
src/data_api/mcp/tools/newsletters.py (no function)   7 0 0   100%
src/data_api/mcp/tools/result_types.py (no function)   28 0 0   100%
src/data_api/models/__init__.py (no function)   0 0 0   100%
src/data_api/models/announcements.py (no function)   18 0 0   100%
src/data_api/models/buses.py BusCanonicalSchedule.qualify_line   1 0 0   100%
src/data_api/models/buses.py (no function)   34 0 0   100%
src/data_api/models/calendars.py (no function)   17 0 0   100%
src/data_api/models/courses.py CourseData.check_identity   5 0 0   100%
src/data_api/models/courses.py CourseCatalog.unique_semesters   3 0 0   100%
src/data_api/models/courses.py _is_valid_credits_matcher   5 0 0   100%
src/data_api/models/courses.py _is_valid_matcher_value   9 0 0   100%
src/data_api/models/courses.py validate_matcher   11 0 0   100%
src/data_api/models/courses.py CourseCondition.parse_field   1 0 0   100%
src/data_api/models/courses.py CourseCondition.check_matcher   2 0 0   100%
src/data_api/models/courses.py CourseQueryCondition.check_query   19 0 0   100%
src/data_api/models/courses.py (no function)   146 0 0   100%
src/data_api/models/departments.py (no function)   27 0 0   100%
src/data_api/models/dining.py (no function)   15 0 0   100%
src/data_api/models/libraries.py rss_image_url_corrector   5 0 0   100%
src/data_api/models/libraries.py (no function)   39 0 0   100%
src/data_api/models/newsletters.py (no function)   13 0 0   100%
src/data_api/runtime.py Runtime.create   2 0 0   100%
src/data_api/runtime.py Runtime.lifespan   13 0 0   100%
src/data_api/runtime.py get_runtime   2 0 0   100%
src/data_api/runtime.py bind_runtime   4 0 0   100%
src/data_api/runtime.py RuntimeMiddleware.__init__   2 0 0   100%
src/data_api/runtime.py RuntimeMiddleware.__call__   2 0 0   100%
src/data_api/runtime.py (no function)   33 0 0   100%
src/data_api/utils/__init__.py (no function)   1 0 0   100%
src/data_api/utils/calendars.py get_event_date_range   8 0 0   100%
src/data_api/utils/calendars.py filter_calendar_events   14 0 0   100%
src/data_api/utils/calendars.py (no function)   4 0 0   100%
src/data_api/utils/schema.py url_corrector   9 0 0   100%
src/data_api/utils/schema.py (no function)   1 0 0   100%
src/data_api/utils/search.py fuzzy_matches   7 0 0   100%
src/data_api/utils/search.py (no function)   2 0 0   100%
tests/conftest.py course_payload   2 0 0   100%
tests/conftest.py make_course   1 0 0   100%
tests/conftest.py set_courses   4 0 0   100%
tests/conftest.py no_external_network   2 0 0   100%
tests/conftest.py no_external_network.unavailable   1 0 0   100%
tests/conftest.py mock_upstream   2 0 0   100%
tests/conftest.py mock_upstream.install   3 0 0   100%
tests/conftest.py mock_upstream.install.handle_request   1 0 0   100%
tests/conftest.py library_space_payload   1 0 0   100%
tests/conftest.py lost_items_html   2 0 0   100%
tests/conftest.py lost_items_html.make   3 0 0   100%
tests/conftest.py lost_items_empty_page   1 0 0   100%
tests/conftest.py dataset_runtime   4 0 0   100%
tests/conftest.py dataset_runtime.handler   5 1 0   80%
tests/conftest.py (no function)   23 0 0   100%
tests/test_announcements.py announcement_sources   6 0 0   100%
tests/test_announcements.py announcement_sources.get_announcements   2 0 0   100%
tests/test_announcements.py TestAnnouncementsEndpoints.client   2 0 0   100%
tests/test_announcements.py TestAnnouncementsEndpoints.test_get_all_announcements   2 0 0   100%
tests/test_announcements.py TestAnnouncementsEndpoints.test_get_announcements_by_department   3 0 0   100%
tests/test_announcements.py TestAnnouncementsEndpoints.test_filter_by_source_url   10 0 0   100%
tests/test_announcements.py TestAnnouncementsEndpoints.test_url_combines_with_other_filters   3 0 0   100%
tests/test_announcements.py TestAnnouncementsEndpoints.test_get_announcements_sources   9 0 0   100%
tests/test_announcements.py TestAnnouncementsEndpoints.test_get_announcements_sources.get_sources   2 0 0   100%
tests/test_announcements.py test_announcements_openapi_contract   24 0 0   100%
tests/test_announcements.py test_fuzzy_filters_preserve_sources_and_cached_articles   15 0 0   100%
tests/test_announcements.py test_fuzzy_filters_preserve_sources_and_cached_articles.get_announcements   1 0 0   100%
tests/test_announcements.py (no function)   27 0 0   100%
tests/test_api_endpoints.py test_root_endpoints_and_slash_redirects   8 0 0   100%
tests/test_api_endpoints.py test_root_endpoints_openapi_migration   5 0 0   100%
tests/test_api_endpoints.py test_openapi_operation_ids_are_unique   2 0 0   100%
tests/test_api_endpoints.py TestAnnouncementsEndpoints.client   2 0 0   100%
tests/test_api_endpoints.py TestAnnouncementsEndpoints.test_announcements_with_title_filter   3 0 0   100%
tests/test_api_endpoints.py TestAnnouncementsEndpoints.test_announcements_with_fuzzy_search   3 0 0   100%
tests/test_api_endpoints.py TestAnnouncementsEndpoints.test_announcements_sources   2 0 0   100%
tests/test_api_endpoints.py TestAnnouncementsEndpoints.test_announcements_sources_with_department   3 0 0   100%
tests/test_api_endpoints.py TestDiningEndpoints.client   2 0 0   100%
tests/test_api_endpoints.py TestDiningEndpoints.test_dining_with_restaurant_name   3 0 0   100%
tests/test_api_endpoints.py TestDiningEndpoints.test_dining_with_building_name   3 0 0   100%
tests/test_api_endpoints.py TestDiningEndpoints.test_dining_fuzzy_search   3 0 0   100%
tests/test_api_endpoints.py TestLocationsEndpoints.client   2 0 0   100%
tests/test_api_endpoints.py TestLocationsEndpoints.test_locations_all   2 0 0   100%
tests/test_api_endpoints.py TestNewslettersEndpoints.client   2 0 0   100%
tests/test_api_endpoints.py TestNewslettersEndpoints.test_newsletters_all   2 0 0   100%
tests/test_api_endpoints.py TestCoursesEndpoints.client   2 0 0   100%
tests/test_api_endpoints.py TestCoursesEndpoints.test_courses_all   2 0 0   100%
tests/test_api_endpoints.py TestCoursesEndpoints.test_courses_search_with_params   3 0 0   100%
tests/test_api_endpoints.py TestBusesEndpoints.client   2 0 0   100%
tests/test_api_endpoints.py TestBusesEndpoints.test_buses_routes_basic   2 0 0   100%
tests/test_api_endpoints.py TestBusesEndpoints.test_buses_routes_with_params   2 0 0   100%
tests/test_api_endpoints.py TestBusesEndpoints.test_buses_routes_nanda   2 0 0   100%
tests/test_api_endpoints.py TestDirectoryEndpoints.client   2 0 0   100%
tests/test_api_endpoints.py TestDirectoryEndpoints.test_directory_search_multiple_keywords   5 0 0   100%
tests/test_api_endpoints.py test_openapi_documents_route_errors   2 0 0   100%
tests/test_api_endpoints.py test_openapi_live_errors_have_detail_schema   9 0 0   100%
tests/test_api_endpoints.py (no function)   50 0 0   100%
tests/test_app_lifespan.py _noop_lifespan   1 0 0   100%
tests/test_app_lifespan.py TestCombinedLifespan.test_runs_startup_tasks_in_order   12 0 0   100%
tests/test_app_lifespan.py TestCombinedLifespan.test_runs_startup_tasks_in_order.fake_prefetch   2 0 0   100%
tests/test_app_lifespan.py TestCombinedLifespan.test_runs_startup_tasks_in_order.fake_buses_update   1 0 0   100%
tests/test_app_lifespan.py TestCombinedLifespan.test_runs_startup_tasks_in_order.fake_courses_update   1 0 0   100%
tests/test_app_lifespan.py TestCombinedLifespan.test_reports_failed_endpoints_as_ascii   11 0 0   100%
tests/test_app_lifespan.py TestCombinedLifespan.test_reports_failed_endpoints_as_ascii.fake_prefetch   1 0 0   100%
tests/test_app_lifespan.py TestCombinedLifespan.test_reports_failed_endpoints_as_ascii.noop   1 0 0   100%
tests/test_app_lifespan.py TestCombinedLifespan.test_exported_lifespan_orders_and_unwinds_contexts   15 1 0   93%
tests/test_app_lifespan.py TestCombinedLifespan.test_exported_lifespan_orders_and_unwinds_contexts.fake_mcp_lifespan   5 0 0   100%
tests/test_app_lifespan.py TestCombinedLifespan.test_exported_lifespan_orders_and_unwinds_contexts.fake_data_lifespan   7 0 0   100%
tests/test_app_lifespan.py _fake_fetch   9 0 0   100%
tests/test_app_lifespan.py TestCoursesAfterStartup.test_courses_endpoint_returns_data_after_startup   9 0 0   100%
tests/test_app_lifespan.py test_unexpected_pre_response_errors_keep_safe_body_and_headers   18 0 0   100%
tests/test_app_lifespan.py test_unexpected_pre_response_errors_keep_safe_body_and_headers.update_data   2 0 0   100%
tests/test_app_lifespan.py test_expected_dependency_errors_keep_status_and_headers   8 0 0   100%
tests/test_app_lifespan.py test_expected_dependency_errors_keep_status_and_headers.update_data   1 0 0   100%
tests/test_app_lifespan.py test_error_after_stream_starts_is_not_replaced   8 0 0   100%
tests/test_app_lifespan.py test_error_after_stream_starts_is_not_replaced.fail_after_start   3 0 0   100%
tests/test_app_lifespan.py test_error_after_stream_starts_is_not_replaced.send   1 0 0   100%
tests/test_app_lifespan.py test_error_after_stream_starts_is_not_replaced.receive   1 1 0   0%
tests/test_app_lifespan.py test_cancelled_request_is_not_formatted   8 0 0   100%
tests/test_app_lifespan.py test_cancelled_request_is_not_formatted.cancel   1 0 0   100%
tests/test_app_lifespan.py test_cancelled_request_is_not_formatted.send   1 1 0   0%
tests/test_app_lifespan.py test_cancelled_request_is_not_formatted.receive   1 1 0   0%
tests/test_app_lifespan.py test_exported_app_serves_rest_and_mcp_with_middleware   43 0 0   100%
tests/test_app_lifespan.py test_exported_app_serves_rest_and_mcp_with_middleware.fake_prefetch   1 0 0   100%
tests/test_app_lifespan.py test_exported_app_serves_rest_and_mcp_with_middleware.noop   1 0 0   100%
tests/test_app_lifespan.py (no function)   36 0 0   100%
tests/test_bus_schedule.py prepared_service   10 0 0   100%
tests/test_bus_schedule.py populated_buses   4 0 0   100%
tests/test_bus_schedule.py test_stop_filters_actual_route_membership   7 0 0   100%
tests/test_bus_schedule.py get_schedule   1 0 0   100%
tests/test_bus_schedule.py canonical_schedules   2 0 0   100%
tests/test_bus_schedule.py test_route_metadata_filters   11 0 0   100%
tests/test_bus_schedule.py test_invalid_route_metadata_filter   4 0 0   100%
tests/test_bus_schedule.py test_shared_limit_caps_bus_results   4 0 0   100%
tests/test_bus_schedule.py test_invalid_shared_limit_is_rejected   4 0 0   100%
tests/test_bus_schedule.py test_rest_filters_before_limit_and_preserves_shape   18 0 0   100%
tests/test_bus_schedule.py test_stop_arrival_filter_matches_mcp   8 0 0   100%
tests/test_bus_schedule.py test_in_transit_bus_is_included_before_limit_for_selected_stop   11 0 0   100%
tests/test_bus_schedule.py test_filter_uses_selected_stop_not_other_stops   4 0 0   100%
tests/test_bus_schedule.py test_current_day_ignores_time   14 0 0   100%
tests/test_bus_schedule.py test_current_day_ignores_time.FixedDatetime.now   1 0 0   100%
tests/test_bus_schedule.py test_mcp_stop_time_limit_and_metadata   13 0 0   100%
tests/test_bus_schedule.py test_no_matching_stop_returns_empty   4 0 0   100%
tests/test_bus_schedule.py test_without_stop_preserves_existing_schedule   8 0 0   100%
tests/test_bus_schedule.py test_invalid_rest_filters_are_rejected   3 0 0   100%
tests/test_bus_schedule.py test_invalid_mcp_filters_are_rejected   3 0 0   100%
tests/test_bus_schedule.py test_openapi_bus_parameters   28 0 0   100%
tests/test_bus_schedule.py test_invalid_mcp_time_is_rejected_before_query   5 0 0   100%
tests/test_bus_schedule.py test_invalid_mcp_time_is_rejected_before_query.unexpected_query   1 1 0   0%
tests/test_bus_schedule.py test_valid_mcp_time_filters   4 0 0   100%
tests/test_bus_schedule.py test_canonical_defaults_query_upcoming_departures   6 0 0   100%
tests/test_bus_schedule.py test_canonical_default_limit   7 0 0   100%
tests/test_bus_schedule.py test_canonical_line_identifiers   5 0 0   100%
tests/test_bus_schedule.py test_published_nanda_line_rest_and_mcp   26 0 0   100%
tests/test_bus_schedule.py test_nanda_source_line_controls_schedule_and_stops   10 0 0   100%
tests/test_bus_schedule.py test_invalid_nanda_source_line_rejects_candidate   2 0 0   100%
tests/test_bus_schedule.py (no function)   75 0 0   100%
tests/test_buses.py test_missing_route_metadata_is_not_registered   5 0 0   100%
tests/test_buses.py test_internal_bus_errors_are_safe   9 0 0   100%
tests/test_buses.py test_internal_bus_errors_are_safe.fail   1 0 0   100%
tests/test_buses.py test_unexpected_bus_tool_errors_are_masked   8 0 0   100%
tests/test_buses.py test_unexpected_bus_tool_errors_are_masked.fail   1 0 0   100%
tests/test_buses.py TestBusesRoutes.client   2 0 0   100%
tests/test_buses.py TestBusesRoutes.test_get_bus_routes   2 0 0   100%
tests/test_buses.py TestBusesStopMetadata.client   2 0 0   100%
tests/test_buses.py TestBusesStopMetadata.test_get_bus_stops_info   6 0 0   100%
tests/test_buses.py TestBusesSchedules.client   2 0 0   100%
tests/test_buses.py TestBusesSchedules.test_get_bus_schedules   2 0 0   100%
tests/test_buses.py TestBusesStops.client   2 0 0   100%
tests/test_buses.py TestBusesStops.test_get_bus_stop_arrivals   2 0 0   100%
tests/test_buses.py (no function)   39 0 0   100%
tests/test_buses_graph.py TestStopsData.test_stops_data_exists   1 0 0   100%
tests/test_buses_graph.py TestStopsData.test_stop_has_required_fields   7 0 0   100%
tests/test_buses_graph.py TestCreateRoute.test_create_route   5 0 0   100%
tests/test_buses_graph.py TestCreateRoute.test_create_route_offsets_cumulative   2 0 0   100%
tests/test_buses_graph.py TestRouteDefinitions.test_red_routes_exist   4 0 0   100%
tests/test_buses_graph.py TestRouteDefinitions.test_green_routes_exist   4 0 0   100%
tests/test_buses_graph.py TestRouteDefinitions.test_nanda_routes_exist   4 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_main_campus_red_uphill   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_main_campus_red_downhill   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_main_campus_red_downhill_from_gen2   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_main_campus_red_from_gen2   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_main_campus_green_uphill   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_main_campus_green_downhill   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_main_campus_green_from_gen2   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_main_campus_unknown_stop   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_nanda_route_up_route1   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_nanda_route_up_route2   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_nanda_route_down_route1   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_resolve_nanda_route_down_route2   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_get_nanda_line_route1   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_get_nanda_line_route2   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_get_nanda_line_education_building   2 0 0   100%
tests/test_buses_graph.py TestRouteResolver.test_get_nanda_line_none   2 0 0   100%
tests/test_buses_graph.py test_published_nanda_line_selects_matching_graph   4 0 0   100%
tests/test_buses_graph.py test_unknown_published_nanda_line_is_rejected   2 0 0   100%
tests/test_buses_graph.py TestModels.test_stop_model   4 0 0   100%
tests/test_buses_graph.py TestModels.test_route_model   5 0 0   100%
tests/test_buses_graph.py TestModels.test_bus_schedule_model   3 0 0   100%
tests/test_buses_graph.py TestModels.test_bus_detailed_schedule_model   3 0 0   100%
tests/test_buses_graph.py (no function)   38 0 0   100%
tests/test_calendars.py make_event   1 0 0   100%
tests/test_calendars.py library_publisher   1 0 0   100%
tests/test_calendars.py runtime   6 0 0   100%
tests/test_calendars.py runtime.handler   8 0 0   100%
tests/test_calendars.py test_calendar_metadata_and_dynamic_ids   11 0 0   100%
tests/test_calendars.py test_event_filters   7 0 0   100%
tests/test_calendars.py test_pagination_after_filtering_and_sorting   8 0 0   100%
tests/test_calendars.py test_default_limit_and_blank_keyword   7 0 0   100%
tests/test_calendars.py test_invalid_queries_do_not_fetch   4 0 0   100%
tests/test_calendars.py test_single_event_preserves_source_shape   5 0 0   100%
tests/test_calendars.py test_missing_calendar_or_event   2 0 0   100%
tests/test_calendars.py test_empty_calendar_and_empty_dataset   12 0 0   100%
tests/test_calendars.py test_unavailable_dataset   5 0 0   100%
tests/test_calendars.py test_unknown_version_header_is_omitted   5 0 0   100%
tests/test_calendars.py test_invalid_payload_preserves_snapshot_and_fails_cold_start   13 0 0   100%
tests/test_calendars.py test_runtime_refresh_and_upstream_failure   14 0 0   100%
tests/test_calendars.py test_openapi_calendar_contract   13 0 0   100%
tests/test_calendars.py test_unified_list_and_all_library_branches   30 0 0   100%
tests/test_calendars.py test_individual_calendars_do_not_depend_on_other_dataset   10 0 0   100%
tests/test_calendars.py test_library_refresh_versions_and_stale_snapshot   24 0 0   100%
tests/test_calendars.py test_invalid_library_payload_preserves_snapshot   15 0 0   100%
tests/test_calendars.py test_unknown_library_version_omits_aggregate_header   5 0 0   100%
tests/test_calendars.py (no function)   47 0 0   100%
tests/test_courses.py courses   1 0 0   100%
tests/test_courses.py client   3 0 0   100%
tests/test_courses.py test_course_search_query_model_keeps_flat_optional_parameters   5 0 0   100%
tests/test_courses.py test_every_get_field_is_accepted   2 0 0   100%
tests/test_courses.py test_get_collection_filters   6 0 0   100%
tests/test_courses.py test_invalid_get_filters   1 0 0   100%
tests/test_courses.py test_get_invalid_regex   5 0 0   100%
tests/test_courses.py test_post_exact_text   3 0 0   100%
tests/test_courses.py test_post_invalid_regex   8 0 0   100%
tests/test_courses.py test_post_nested_regex_and_typed_matchers   5 0 0   100%
tests/test_courses.py test_large_integer_credit_matcher_does_not_overflow   3 0 0   100%
tests/test_courses.py test_response_is_full_normalized_shape_and_nullable   7 0 0   100%
tests/test_courses.py (no function)   30 0 0   100%
tests/test_courses_models.py test_complete_normalized_course_and_union_shapes   3 0 0   100%
tests/test_courses_models.py test_invalid_candidates_rejected   3 0 0   100%
tests/test_courses_models.py test_missing_published_fields_are_not_silently_filled   4 0 0   100%
tests/test_courses_models.py test_snapshot_identity_and_semester_validation   14 0 0   100%
tests/test_courses_models.py test_matcher_type_validation   2 0 0   100%
tests/test_courses_models.py test_array_leaves_and_null_do_not_match_absent_keys_or_empty_arrays   13 0 0   100%
tests/test_courses_models.py test_independent_any_conditions_and_cached_predicate   8 0 0   100%
tests/test_courses_models.py test_domain_invalid_conditions   4 0 0   100%
tests/test_courses_models.py test_conditions_require_a_field_or_sequence   2 0 0   100%
tests/test_courses_models.py (no function)   19 0 0   100%
tests/test_courses_query_grammar.py nested_query   4 0 0   100%
tests/test_courses_query_grammar.py wide_query   4 0 0   100%
tests/test_courses_query_grammar.py courses   1 0 0   100%
tests/test_courses_query_grammar.py test_schema_rejects_invalid_grammar   2 0 0   100%
tests/test_courses_query_grammar.py test_schema_preserves_legal_query_semantics   4 0 0   100%
tests/test_courses_query_grammar.py test_schema_enforces_exact_tree_limits   6 0 0   100%
tests/test_courses_query_grammar.py test_limits_include_prevalidated_nested_models   6 0 0   100%
tests/test_courses_query_grammar.py test_schema_accepts_prevalidated_conditions_and_nested_models   4 0 0   100%
tests/test_courses_query_grammar.py TestCourseQueryGrammarEndpoints.client   3 0 0   100%
tests/test_courses_query_grammar.py TestCourseQueryGrammarEndpoints.test_invalid_grammar_returns_422   7 0 0   100%
tests/test_courses_query_grammar.py TestCourseQueryGrammarEndpoints.test_legal_queries_keep_results   6 0 0   100%
tests/test_courses_query_grammar.py TestCourseQueryGrammarEndpoints.test_tree_limits_return_422   7 0 0   100%
tests/test_courses_query_grammar.py test_openapi_documents_grammar_validation   4 0 0   100%
tests/test_courses_query_grammar.py (no function)   41 0 0   100%
tests/test_courses_semesters.py SemesterPublisher.__init__   6 0 0   100%
tests/test_courses_semesters.py SemesterPublisher.__call__   13 2 0   85%
tests/test_courses_semesters.py SemesterPublisher.clients   5 0 0   100%
tests/test_courses_semesters.py test_discovery_and_default_latest_use_independent_versions   23 0 0   100%
tests/test_courses_semesters.py test_invalid_semester_is_rejected_without_upstream_calls   9 0 0   100%
tests/test_courses_semesters.py test_unknown_and_unavailable_semesters_do_not_fall_back   15 0 0   100%
tests/test_courses_semesters.py test_catalog_failure_does_not_block_latest_or_claim_unknown_is_missing   13 0 0   100%
tests/test_courses_semesters.py test_cross_semester_concurrency_coalesces_only_same_path_and_keeps_versions   15 0 0   100%
tests/test_courses_semesters.py test_cross_semester_concurrency_coalesces_only_same_path_and_keeps_versions.handler   4 0 0   100%
tests/test_courses_semesters.py test_failed_refresh_retains_only_same_semester_and_recovers_after_ttl   21 0 0   100%
tests/test_courses_semesters.py test_filters_apply_to_selected_semester_and_teacher_union   16 0 0   100%
tests/test_courses_semesters.py test_catalog_refresh_discovers_new_semester_and_rejects_invalid_replacement   16 0 0   100%
tests/test_courses_semesters.py test_cancellation_releases_semester_lock_and_allows_retry   16 0 0   100%
tests/test_courses_semesters.py test_cancellation_releases_semester_lock_and_allows_retry.handler   4 0 0   100%
tests/test_courses_semesters.py test_lazy_unavailable_semester_is_reported_by_readiness_without_refresh   9 0 0   100%
tests/test_courses_semesters.py (no function)   30 0 0   100%
tests/test_data_manager.py Clock.__init__   1 0 0   100%
tests/test_data_manager.py Clock.__call__   1 0 0   100%
tests/test_data_manager.py Clock.advance   1 0 0   100%
tests/test_data_manager.py Publisher.__init__   8 0 0   100%
tests/test_data_manager.py Publisher.manifest   4 0 0   100%
tests/test_data_manager.py Publisher.__call__   13 0 0   100%
tests/test_data_manager.py Publisher.client   1 0 0   100%
tests/test_data_manager.py test_prefetch_starts_datasets_concurrently_and_reports_failures   10 0 0   100%
tests/test_data_manager.py test_prefetch_starts_datasets_concurrently_and_reports_failures.get   7 0 0   100%
tests/test_data_manager.py test_successful_replacement_including_empty   12 0 0   100%
tests/test_data_manager.py test_fetch_failures_preserve_last_known_good   26 0 0   100%
tests/test_data_manager.py test_dns_category_preserves_cause   9 0 0   100%
tests/test_data_manager.py test_ttl_and_version_matching   15 0 0   100%
tests/test_data_manager.py test_only_version_changes_trigger_refresh   22 0 0   100%
tests/test_data_manager.py test_missing_version_never_falls_back_to_last_commit   16 0 0   100%
tests/test_data_manager.py test_unknown_versions_are_not_a_match   15 0 0   100%
tests/test_data_manager.py test_manifest_contract_failures   13 0 0   100%
tests/test_data_manager.py test_manifest_extra_fields_optional_metadata_and_nested_paths   8 0 0   100%
tests/test_data_manager.py test_manifest_outage_never_claims_freshness   14 0 0   100%
tests/test_data_manager.py test_candidate_failure_is_atomic   16 0 0   100%
tests/test_data_manager.py test_candidate_failure_is_atomic.prepare   7 0 0   100%
tests/test_data_manager.py test_twenty_concurrent_callers_single_refresh   19 0 0   100%
tests/test_data_manager.py test_twenty_concurrent_callers_single_refresh.handler   4 0 0   100%
tests/test_data_manager.py test_unrelated_dataset_downloads_do_not_block   13 0 0   100%
tests/test_data_manager.py test_unrelated_dataset_downloads_do_not_block.handler   4 0 0   100%
tests/test_data_manager.py test_checksum_prevents_mislabeled_snapshot_during_publication   12 0 0   100%
tests/test_data_manager.py test_course_validation_and_conversion_before_swap   25 0 0   100%
tests/test_data_manager.py test_course_validation_and_conversion_before_swap.fail   1 0 0   100%
tests/test_data_manager.py test_bus_indexes_are_built_before_swap   20 0 0   100%
tests/test_data_manager.py test_bus_indexes_are_built_before_swap.fail   1 0 0   100%
tests/test_data_manager.py test_bus_candidate_must_also_satisfy_response_schema   8 0 0   100%
tests/test_data_manager.py test_client_lifecycle_and_disposable_state   19 0 0   100%
tests/test_data_manager.py test_cancelled_refresh_can_retry   13 0 0   100%
tests/test_data_manager.py test_cancelled_refresh_can_retry.handler   4 0 0   100%
tests/test_data_manager.py test_shared_manifest_does_not_extend_freshness_for_later_readers   12 0 0   100%
tests/test_data_manager.py test_initial_course_schema_validation   11 0 0   100%
tests/test_data_manager.py test_dataset_schemas_validate_nested_records_before_install   14 0 0   100%
tests/test_data_manager.py test_concurrent_cold_failure_is_one_attempt_then_recover   10 0 0   100%
tests/test_data_manager.py test_instances_are_independent   12 0 0   100%
tests/test_data_manager.py test_duplicate_manifest_paths_are_malformed   6 0 0   100%
tests/test_data_manager.py test_runtime_settings_are_configurable_and_positive   10 0 0   100%
tests/test_data_manager.py (no function)   61 0 0   100%
tests/test_departments_services.py test_search_handles_missing_optional_person_title   5 0 0   100%
tests/test_departments_services.py test_search_handles_missing_optional_person_title.get_directory   1 0 0   100%
tests/test_departments_services.py (no function)   6 0 0   100%
tests/test_dining.py dining_candidates   11 0 0   100%
tests/test_dining.py dining_candidates.fake_get   2 0 0   100%
tests/test_dining.py dining_candidates.Saturday.now   2 0 0   100%
tests/test_dining.py TestDiningEndpoints.client   2 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_get_all_dining   2 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_get_dining_by_building   3 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_get_open_restaurants   3 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_combined_filters   22 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_no_schedule_matches   4 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_all_restaurants_closed   11 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_all_restaurants_closed.fake_get   1 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_schedule_respects_search_mode   4 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_invalid_schedule   3 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_unversioned_data   8 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_unversioned_data.fake_get   2 0 0   100%
tests/test_dining.py TestDiningEndpoints.test_open_route_removed   2 0 0   100%
tests/test_dining.py test_dining_openapi_contract   12 0 0   100%
tests/test_dining.py (no function)   37 0 0   100%
tests/test_directory.py directory_data   4 0 0   100%
tests/test_directory.py directory_data.get_directory   2 0 0   100%
tests/test_directory.py test_directory_query   17 0 0   100%
tests/test_directory.py test_directory_department_match_keeps_nonmatching_people   6 0 0   100%
tests/test_directory.py test_directory_title_match_threshold   6 0 0   100%
tests/test_directory.py test_directory_sorts_by_match_score   4 0 0   100%
tests/test_directory.py test_directory_search_keeps_separate_results   4 0 0   100%
tests/test_directory.py test_directory_without_commit_hash   7 0 0   100%
tests/test_directory.py test_directory_without_commit_hash.get_directory   1 0 0   100%
tests/test_directory.py test_directory_openapi   14 0 0   100%
tests/test_directory.py test_directory_search_path_is_not_registered   3 0 0   100%
tests/test_directory.py test_directory_unavailable_dataset   9 0 0   100%
tests/test_directory.py test_directory_unavailable_dataset.unavailable   1 0 0   100%
tests/test_directory.py test_directory_exact_rejects_partial_matches   6 0 0   100%
tests/test_directory.py test_directory_invalid_fuzzy   4 0 0   100%
tests/test_directory.py (no function)   28 0 0   100%
tests/test_energy.py TestEnergyEndpoints.client   2 0 0   100%
tests/test_energy.py TestEnergyEndpoints.test_get_electricity_usage   8 0 0   100%
tests/test_energy.py TestEnergyEndpoints.test_get_electricity_usage.handler   2 0 0   100%
tests/test_energy.py TestEnergyEndpoints.test_upstream_unavailable   3 0 0   100%
tests/test_energy.py (no function)   11 0 0   100%
tests/test_exceptions.py TestDataAPIException.test_base_exception   3 0 0   100%
tests/test_exceptions.py TestDataAPIException.test_base_exception_inheritance   2 0 0   100%
tests/test_exceptions.py TestDataNotAvailableException.test_data_not_available   3 0 0   100%
tests/test_exceptions.py TestDataNotAvailableException.test_inheritance   2 0 0   100%
tests/test_exceptions.py TestDataUpdateException.test_data_update_exception   3 0 0   100%
tests/test_exceptions.py TestDataUpdateException.test_inheritance   2 0 0   100%
tests/test_exceptions.py TestExceptionHierarchy.test_catch_specific_with_base   4 0 0   100%
tests/test_exceptions.py TestExceptionHierarchy.test_catch_data_update_with_base   4 0 0   100%
tests/test_exceptions.py test_upstream_exceptions_keep_public_details_safe   6 0 0   100%
tests/test_exceptions.py (no function)   16 0 0   100%
tests/test_external_checks.py publication   9 0 0   100%
tests/test_external_checks.py published_client   2 0 0   100%
tests/test_external_checks.py published_client.serve   10 1 0   90%
tests/test_external_checks.py test_complete_publication_accepts_url_regressions_and_serializes   5 0 0   100%
tests/test_external_checks.py test_publication_check_does_not_reset_an_active_runtime   9 0 0   100%
tests/test_external_checks.py test_legacy_manifest_and_empty_datasets_are_accepted   9 0 0   100%
tests/test_external_checks.py test_delivery_failures_identify_dataset_and_stage   4 0 0   100%
tests/test_external_checks.py test_schema_drift_fails_full_candidate   11 0 0   100%
tests/test_external_checks.py test_missing_required_manifest_entry_is_not_silently_loaded   6 0 0   100%
tests/test_external_checks.py test_published_semester_must_have_manifest_entry   5 0 0   100%
tests/test_external_checks.py test_published_semester_model_and_identity_are_validated   9 0 0   100%
tests/test_external_checks.py test_duplicate_manifest_is_rejected   5 0 0   100%
tests/test_external_checks.py test_json_failures_without_checksum   4 0 0   100%
tests/test_external_checks.py healthy_readiness   1 0 0   100%
tests/test_external_checks.py smoke_client   2 0 0   100%
tests/test_external_checks.py smoke_client.serve   5 0 0   100%
tests/test_external_checks.py test_smoke_accepts_empty_feeds_and_unknown_versions   4 0 0   100%
tests/test_external_checks.py test_published_serialization_checks_expected_version_header   12 0 0   100%
tests/test_external_checks.py test_smoke_reports_endpoint_schema_headers_and_availability   5 0 0   100%
tests/test_external_checks.py test_smoke_rejects_false_readiness   9 0 0   100%
tests/test_external_checks.py test_external_report_exit_status_and_safe_diagnostic   5 0 0   100%
tests/test_external_checks.py (no function)   41 0 0   100%
tests/test_libraries.py make_event   1 0 0   100%
tests/test_libraries.py client   2 0 0   100%
tests/test_libraries.py fake_data   2 0 0   100%
tests/test_libraries.py fake_data.fake_get   3 1 0   67%
tests/test_libraries.py no_data   2 0 0   100%
tests/test_libraries.py no_data.fake_get   1 0 0   100%
tests/test_libraries.py TestEventFiltering.test_all_day_end_is_exclusive   1 0 0   100%
tests/test_libraries.py TestEventFiltering.test_timed_event   1 0 0   100%
tests/test_libraries.py TestEventFiltering.test_timed_event_ending_at_midnight   1 0 0   100%
tests/test_libraries.py TestEventFiltering.test_filter_by_date_range   2 0 0   100%
tests/test_libraries.py TestEventFiltering.test_filter_by_keyword_matches_description   2 0 0   100%
tests/test_libraries.py TestEventFiltering.test_filter_keyword_is_case_insensitive   2 0 0   100%
tests/test_libraries.py TestLibraryRss.test_get_rss   6 0 0   100%
tests/test_libraries.py TestLibraryRss.test_nullable_fields   3 0 0   100%
tests/test_libraries.py TestLibraryRss.test_missing_feed   2 0 0   100%
tests/test_libraries.py TestLibraryRss.test_invalid_type   2 0 0   100%
tests/test_libraries.py TestLibraryRss.test_data_unavailable   2 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_list_calendars_without_events   6 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_get_calendar   7 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_calendar_missing_from_data   2 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_invalid_calendar_id   2 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_list_events   4 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_events_on_a_single_day   3 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_events_by_keyword   2 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_events_pagination   3 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_events_invalid_range   2 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_events_invalid_date   2 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_events_of_missing_calendar   2 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_get_event   3 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_get_missing_event   2 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_data_unavailable   2 0 0   100%
tests/test_libraries.py TestLibraryCalendars.test_old_endpoints_removed   3 0 0   100%
tests/test_libraries.py TestLibrariesLiveEndpoints.test_libraries_endpoints   3 0 0   100%
tests/test_libraries.py TestLibrariesLiveEndpoints.test_library_space   8 0 0   100%
tests/test_libraries.py TestLibrariesLiveEndpoints.test_lost_items   5 0 0   100%
tests/test_libraries.py TestLibrariesLiveEndpoints.test_lost_items.handler   2 0 0   100%
tests/test_libraries.py TestLibrariesLiveEndpoints.test_lost_items_empty   5 0 0   100%
tests/test_libraries.py (no function)   60 0 0   100%
tests/test_locations.py TestLocationsEndpoints.client   2 0 0   100%
tests/test_locations.py TestLocationsEndpoints.test_get_all_locations   4 0 0   100%
tests/test_locations.py TestLocationsEndpoints.test_search_locations_by_name   4 0 0   100%
tests/test_locations.py TestLocationsEndpoints.test_search_locations_no_matches   4 0 0   100%
tests/test_locations.py TestLocationsEndpoints.test_empty_name_returns_all_locations   8 0 0   100%
tests/test_locations.py TestLocationsEndpoints.test_explicit_fuzzy_search   4 0 0   100%
tests/test_locations.py TestLocationsEndpoints.test_exact_name_search   4 0 0   100%
tests/test_locations.py TestLocationsEndpoints.test_exact_search_does_not_match_substrings   5 0 0   100%
tests/test_locations.py TestLocationsEndpoints.test_invalid_fuzzy_parameter   3 0 0   100%
tests/test_locations.py TestLocationsEndpoints.test_slashless_endpoint_preserves_query   4 0 0   100%
tests/test_locations.py test_locations_openapi   13 0 0   100%
tests/test_locations.py (no function)   21 0 0   100%
tests/test_mcp_metadata.py test_tool_names_and_titles_exposed_to_clients   14 0 0   100%
tests/test_mcp_metadata.py (no function)   3 0 0   100%
tests/test_mcp_search.py fixed_course_refresh   1 0 0   100%
tests/test_mcp_search.py course_candidates   3 0 0   100%
tests/test_mcp_search.py test_course_filters_all_contribute   9 0 0   100%
tests/test_mcp_search.py test_course_search_uses_literal_substrings   11 0 0   100%
tests/test_mcp_search.py test_course_limit_rejected_by_implementation   2 0 0   100%
tests/test_mcp_search.py test_course_limit_schema_and_protocol_validation   15 0 0   100%
tests/test_mcp_search.py dining_candidates   11 0 0   100%
tests/test_mcp_search.py dining_candidates.fake_get   3 0 0   100%
tests/test_mcp_search.py dining_candidates.Saturday.now   1 0 0   100%
tests/test_mcp_search.py test_dining_filters_all_contribute   15 0 0   100%
tests/test_mcp_search.py test_dining_filters_before_limiting   6 0 0   100%
tests/test_mcp_search.py test_dining_filters_before_limiting.fake_get   2 0 0   100%
tests/test_mcp_search.py test_dining_impossible_filter_with_open_status   2 0 0   100%
tests/test_mcp_search.py test_dining_grouped_limits_over_protocol   21 0 0   100%
tests/test_mcp_search.py test_dining_grouped_limits_over_protocol.fake_get   3 0 0   100%
tests/test_mcp_search.py test_dining_omits_empty_buildings   8 0 0   100%
tests/test_mcp_search.py test_dining_omits_empty_buildings.fake_get   2 0 0   100%
tests/test_mcp_search.py directory_and_locations   7 0 0   100%
tests/test_mcp_search.py directory_and_locations.get_dataset   2 0 0   100%
tests/test_mcp_search.py test_registered_directory_search_modes   20 0 0   100%
tests/test_mcp_search.py test_registered_locations_search_modes   15 0 0   100%
tests/test_mcp_search.py test_search_tools_unavailable_dataset   6 0 0   100%
tests/test_mcp_search.py test_search_tools_unavailable_dataset.unavailable   2 0 0   100%
tests/test_mcp_search.py test_empty_directory_search_unavailable_dataset   6 0 0   100%
tests/test_mcp_search.py test_empty_directory_search_unavailable_dataset.unavailable   2 0 0   100%
tests/test_mcp_search.py test_search_tools_protocol_validation   6 0 0   100%
tests/test_mcp_search.py test_directory_exact_rest_shape_and_case   9 0 0   100%
tests/test_mcp_search.py test_directory_filters_before_caps_and_preserves_exact_order   8 0 0   100%
tests/test_mcp_search.py test_directory_filters_before_caps_and_preserves_exact_order.get_dataset   2 0 0   100%
tests/test_mcp_search.py (no function)   60 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_search_directory   6 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_search_locations   3 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_bus_schedule_default   6 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_bus_schedule_main_route   3 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_bus_schedule_nanda_route   3 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_search_courses_by_keyword   4 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_search_courses_by_teacher   4 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_search_courses_no_filter   4 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_announcements   4 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_announcements_with_department   4 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_find_dining   3 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_find_dining_by_building   3 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_find_dining_check_open   3 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_library_info_space   5 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_library_info_lost_and_found   3 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_newsletters   4 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_newsletters_with_search   4 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_energy_usage   7 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_bus_schedule_with_stop   9 0 0   100%
tests/test_mcp_tools.py TestMCPTools.test_get_bus_schedule_with_stop_name_string   9 0 0   100%
tests/test_mcp_tools.py TestMCPToolIntegration.test_search_directory_returns_limited_results   3 0 0   100%
tests/test_mcp_tools.py TestMCPToolIntegration.test_search_locations_returns_limited_results   2 0 0   100%
tests/test_mcp_tools.py TestMCPToolIntegration.test_get_bus_schedule_respects_limit   2 0 0   100%
tests/test_mcp_tools.py TestMCPToolIntegration.test_search_courses_respects_limit   2 0 0   100%
tests/test_mcp_tools.py TestMCPToolIntegration.test_course_search_result_format   5 0 0   100%
tests/test_mcp_tools.py TestMCPToolIntegration.test_announcements_result_format   9 7 0   22%
tests/test_mcp_tools.py TestMCPToolIntegration.test_get_bus_schedule_with_stop_respects_limit   3 0 0   100%
tests/test_mcp_tools.py TestRegisteredPayloads.test_empty_dataset_payloads   5 0 0   100%
tests/test_mcp_tools.py TestRegisteredPayloads.test_nested_dataset_payloads_and_nulls   12 0 0   100%
tests/test_mcp_tools.py TestRegisteredPayloads.test_bus_simple_detailed_and_stop_payloads   20 0 0   100%
tests/test_mcp_tools.py TestRegisteredPayloads.test_course_payload_preserves_normalized_values   6 0 0   100%
tests/test_mcp_tools.py TestRegisteredPayloads.test_live_payloads_and_empty_results   24 0 0   100%
tests/test_mcp_tools.py (no function)   66 0 0   100%
tests/test_meta.py test_metadata_available_without_datasets_or_upstream   12 0 0   100%
tests/test_meta.py test_metadata_available_without_datasets_or_upstream.unexpected_request   1 1 0   0%
tests/test_meta.py test_metadata_matches_application_configuration   17 0 0   100%
tests/test_meta.py test_metadata_hidden_from_openapi_and_swagger   10 0 0   100%
tests/test_meta.py (no function)   7 0 0   100%
tests/test_newsletters.py TestNewslettersEndpoints.client   2 0 0   100%
tests/test_newsletters.py TestNewslettersEndpoints.test_get_all_newsletters   4 0 0   100%
tests/test_newsletters.py TestNewslettersEndpoints.test_get_sources   5 0 0   100%
tests/test_newsletters.py newsletter_data   4 0 0   100%
tests/test_newsletters.py newsletter_data.get_dataset   2 0 0   100%
tests/test_newsletters.py test_combined_filters_preserve_cached_data   20 0 0   100%
tests/test_newsletters.py test_filter_edge_cases   6 0 0   100%
tests/test_newsletters.py test_fuzzy_threshold   3 0 0   100%
tests/test_newsletters.py test_mcp_and_rest_name_search_match   9 0 0   100%
tests/test_newsletters.py test_mcp_delegates_search_to_domain   4 0 0   100%
tests/test_newsletters.py test_rest_and_mcp_share_fuzzy_threshold   10 0 0   100%
tests/test_newsletters.py test_mcp_returns_all_matching_sources   13 0 0   100%
tests/test_newsletters.py test_empty_and_unavailable_dataset   8 0 0   100%
tests/test_newsletters.py test_empty_and_unavailable_dataset.get_dataset   3 0 0   100%
tests/test_newsletters.py test_openapi_newsletter_contract   8 0 0   100%
tests/test_newsletters.py (no function)   42 0 0   100%
tests/test_openapi_contract.py test_structured_openapi_baseline   3 0 0   100%
tests/test_openapi_contract.py test_compatibility_check_identifies_structural_changes   20 0 0   100%
tests/test_openapi_contract.py test_documentation_changes_are_ignored_but_title_fields_are_not   8 0 0   100%
tests/test_openapi_contract.py test_every_snapshot_operation_documents_availability_and_headers   13 0 0   100%
tests/test_openapi_contract.py test_manual_errors_and_course_validation_have_body_schemas   11 0 0   100%
tests/test_openapi_contract.py assert_error_matches_schema   6 0 0   100%
tests/test_openapi_contract.py test_actual_manual_and_validation_errors   4 0 0   100%
tests/test_openapi_contract.py test_snapshot_unavailable_matches_openapi   4 0 0   100%
tests/test_openapi_contract.py test_live_upstream_error_matches_openapi   5 0 0   100%
tests/test_openapi_contract.py test_live_upstream_error_matches_openapi.upstream   3 0 0   100%
tests/test_openapi_contract.py test_calendar_pagination_body_and_headers_match_openapi   12 0 0   100%
tests/test_openapi_contract.py test_calendar_pagination_body_and_headers_match_openapi.search   1 0 0   100%
tests/test_openapi_contract.py (no function)   25 0 0   100%
tests/test_ping.py ping_runtime   10 0 0   100%
tests/test_ping.py ping_runtime.handler   7 1 0   86%
tests/test_ping.py test_ping_ready_after_startup_including_empty_datasets   19 0 0   100%
tests/test_ping.py test_ping_head_matches_readiness_without_refresh   27 0 0   100%
tests/test_ping.py test_ping_head_sends_no_asgi_body   9 0 0   100%
tests/test_ping.py test_ping_head_sends_no_asgi_body.receive   1 1 0   0%
tests/test_ping.py test_ping_head_sends_no_asgi_body.send   1 0 0   100%
tests/test_ping.py test_ping_head_cors_preflight   7 0 0   100%
tests/test_ping.py test_ping_keeps_usable_fallback_ready   18 0 0   100%
tests/test_ping.py test_ping_expired_check_does_not_refresh_or_mutate   13 0 0   100%
tests/test_ping.py test_ping_missing_dataset_is_unavailable   28 0 0   100%
tests/test_ping.py test_ping_reports_additional_registered_datasets   6 0 0   100%
tests/test_ping.py test_ping_cold_registry_is_not_ready   7 0 0   100%
tests/test_ping.py test_ping_hidden_from_openapi_and_swagger   12 0 0   100%
tests/test_ping.py (no function)   25 0 0   100%
tests/test_refactoring.py test_request_duration_uses_monotonic_clock   7 0 0   100%
tests/test_refactoring.py test_bus_time_resolution   5 0 0   100%
tests/test_refactoring.py test_course_conditions_prepare_once_and_do_not_retain_course   9 0 0   100%
tests/test_refactoring.py _mcp_request   6 0 0   100%
tests/test_refactoring.py test_two_apps_isolate_snapshots_clients_and_mcp_http   45 0 0   100%
tests/test_refactoring.py test_two_apps_isolate_snapshots_clients_and_mcp_http.handler   7 0 0   100%
tests/test_refactoring.py test_runtime_closes_all_clients_on_startup_failure   13 0 0   100%
tests/test_refactoring.py test_runtime_closes_all_clients_on_startup_failure.fail   2 0 0   100%
tests/test_refactoring.py test_runtime_cannot_be_reentered_without_losing_live_clients   11 0 0   100%
tests/test_refactoring.py test_energy_reuses_one_injected_client   9 0 0   100%
tests/test_refactoring.py test_energy_reuses_one_injected_client.handler   2 0 0   100%
tests/test_refactoring.py test_bus_preparation_returns_data_without_runtime_state   5 0 0   100%
tests/test_refactoring.py test_app_factory_defaults_to_independent_runtimes   4 0 0   100%
tests/test_refactoring.py test_isolated_app_reports_missing_snapshots_through_rest_and_mcp   12 0 0   100%
tests/test_refactoring.py test_energy_failure_cancels_siblings_before_releasing_client   11 0 0   100%
tests/test_refactoring.py test_energy_failure_cancels_siblings_before_releasing_client.handler   10 0 0   100%
tests/test_refactoring.py test_library_live_calls_borrow_the_injected_client   10 0 0   100%
tests/test_refactoring.py test_library_live_calls_borrow_the_injected_client.handler   4 0 0   100%
tests/test_refactoring.py (no function)   32 0 0   100%
tests/test_release.py test_prepare_release_renders_current_pr_template   33 0 0   100%
tests/test_release.py test_installed_version_has_one_source   3 0 0   100%
tests/test_release.py test_nonstable_versions_rejected   2 0 0   100%
tests/test_release.py test_invalid_or_mismatched_tags_fail   3 0 0   100%
tests/test_release.py test_lock_mismatch_fails   4 0 0   100%
tests/test_release.py test_publication_uses_authoritative_remote_and_fails_closed   8 0 0   100%
tests/test_release.py test_publication_uses_authoritative_remote_and_fails_closed.run   3 0 0   100%
tests/test_release.py test_publication_network_failure_is_not_unpublished   4 0 0   100%
tests/test_release.py test_publication_network_failure_is_not_unpublished.run   1 0 0   100%
tests/test_release.py test_only_verified_unpublished_initial_version_can_update_contract   15 0 0   100%
tests/test_release.py test_only_verified_unpublished_initial_version_can_update_contract.git_file   1 0 0   100%
tests/test_release.py test_only_verified_unpublished_initial_version_can_update_contract.publication   3 0 0   100%
tests/test_release.py test_breaking_changes_detected   1 0 0   100%
tests/test_release.py test_new_required_parameter_is_breaking   1 0 0   100%
tests/test_release.py test_schema_names_are_not_keywords   4 0 0   100%
tests/test_release.py test_optional_type_named_argument_is_not_a_constraint   4 0 0   100%
tests/test_release.py test_tool_and_parameter_names_are_not_schema_keywords   2 0 0   100%
tests/test_release.py test_literal_schema_values_do_not_reenter_schema_context   7 0 0   100%
tests/test_release.py test_schema_valued_keywords_propagate_context   1 0 0   100%
tests/test_release.py test_nullable_stop_enum_compatibility   14 0 0   100%
tests/test_release.py test_compatible_additions_allowed   1 0 0   100%
tests/test_release.py test_refreshed_baseline_cannot_hide_same_major_removal   10 0 0   100%
tests/test_release.py test_refreshed_baseline_cannot_hide_same_major_removal.git_file   3 0 0   100%
tests/test_release.py test_same_major_mcp_snapshot_changes   31 0 0   100%
tests/test_release.py test_same_major_mcp_snapshot_changes.read_text   3 0 0   100%
tests/test_release.py test_same_major_mcp_snapshot_changes.git_file   5 0 0   100%
tests/test_release.py test_mcp_structured_baseline   1 0 0   100%
tests/test_release.py test_mcp_field_named_title_is_not_stripped   4 0 0   100%
tests/test_release.py (no function)   48 0 0   100%
tests/test_removed_endpoints.py test_retired_routes_are_not_served   5 0 0   100%
tests/test_removed_endpoints.py test_only_current_routes_are_registered   3 0 0   100%
tests/test_removed_endpoints.py (no function)   7 0 0   100%
tests/test_rss_contract.py published_rss   1 0 0   100%
tests/test_rss_contract.py test_fixed_cases_reproduce_original_single_uri_failures   8 0 0   100%
tests/test_rss_contract.py test_full_rss_candidate_preserves_text_and_unknown_fields   12 0 0   100%
tests/test_rss_contract.py test_invalid_images_still_fail   2 0 0   100%
tests/test_rss_contract.py test_rss_link_remains_nullable_text   2 0 0   100%
tests/test_rss_contract.py test_rss_cold_start_refresh_and_last_known_good   31 0 0   100%
tests/test_rss_contract.py test_invalid_rss_without_snapshot_returns_503   7 0 0   100%
tests/test_rss_contract.py (no function)   23 0 0   100%
tests/test_runtime_lifecycle.py test_rest_and_mcp_observe_runtime_course_refresh   30 0 0   100%
tests/test_runtime_lifecycle.py test_cold_start_empty_is_not_unavailable   18 0 0   100%
tests/test_runtime_lifecycle.py test_other_datasets_empty_unversioned_and_unavailable   15 0 0   100%
tests/test_runtime_lifecycle.py test_real_data_lifespan_client_cleanup   18 0 0   100%
tests/test_runtime_lifecycle.py test_real_data_lifespan_client_cleanup.handler   1 0 0   100%
tests/test_runtime_lifecycle.py test_app_startup_exception_closes_client   9 1 0   89%
tests/test_runtime_lifecycle.py test_app_startup_exception_closes_client.fail   2 0 0   100%
tests/test_runtime_lifecycle.py (no function)   18 0 0   100%
tests/test_schemas.py test_optional_metadata_can_be_omitted_or_null   11 0 0   100%
tests/test_schemas.py test_optional_urls_still_validate_supplied_values   4 0 0   100%
tests/test_schemas.py test_announcement_source_requires_metadata   7 0 0   100%
tests/test_schemas.py test_announcement_source_rejects_invalid_http_urls   2 0 0   100%
tests/test_schemas.py test_announcement_source_corrects_protocol_relative_urls   2 0 0   100%
tests/test_schemas.py (no function)   17 0 0   100%
tests/test_services.py TestDiningService.test_is_restaurant_open_no_note   2 0 0   100%
tests/test_services.py TestDiningService.test_is_restaurant_open_break_on_saturday   2 0 0   100%
tests/test_services.py TestDiningService.test_is_restaurant_open_break_different_day   2 0 0   100%
tests/test_services.py TestDiningService.test_is_restaurant_open_weekend   3 0 0   100%
tests/test_services.py TestDiningService.test_is_restaurant_open_weekday   2 0 0   100%
tests/test_services.py TestDiningScheduleKeyword.test_break_keywords_exist   1 0 0   100%
tests/test_services.py TestDiningScheduleKeyword.test_day_mapping_exists   3 0 0   100%
tests/test_services.py test_today_uses_taiwan_date   18 0 0   100%
tests/test_services.py test_today_uses_taiwan_date.FrozenDatetime.now   2 0 0   100%
tests/test_services.py test_today_uses_taiwan_date.fake_get   2 0 0   100%
tests/test_services.py (no function)   19 0 0   100%
tests/test_upstream_errors.py rest   2 0 0   100%
tests/test_upstream_errors.py test_live_http_failures   18 0 0   100%
tests/test_upstream_errors.py test_live_http_failures.handler   3 0 0   100%
tests/test_upstream_errors.py test_unexpected_live_failures_are_safe   12 0 0   100%
tests/test_upstream_errors.py test_unexpected_live_failures_are_safe.fail   1 0 0   100%
tests/test_upstream_errors.py test_invalid_live_responses   8 0 0   100%
tests/test_upstream_errors.py test_malformed_lost_rows_are_not_skipped   9 0 0   100%
tests/test_upstream_errors.py test_lost_items_reject_invalid_headers   11 0 0   100%
tests/test_upstream_errors.py test_lost_items_accept_reordered_headers   17 0 0   100%
tests/test_upstream_errors.py test_lost_items_reject_invalid_empty_pages   8 0 0   100%
tests/test_upstream_errors.py test_library_space_application_failure   8 0 0   100%
tests/test_upstream_errors.py test_live_protocol_success   12 0 0   100%
tests/test_upstream_errors.py test_live_protocol_success.handler   6 0 0   100%
tests/test_upstream_errors.py test_mcp_http_failure_is_tool_error   11 0 0   100%
tests/test_upstream_errors.py test_mcp_http_failure_is_tool_error.handler   1 0 0   100%
tests/test_upstream_errors.py (no function)   34 0 0   100%
tests/test_utils.py TestUrlCorrector.test_url_corrector_none_input   2 0 0   100%
tests/test_utils.py TestUrlCorrector.test_url_corrector_double_slash_prefix   2 0 0   100%
tests/test_utils.py TestUrlCorrector.test_url_corrector_valid_http   3 0 0   100%
tests/test_utils.py TestUrlCorrector.test_url_corrector_valid_https   3 0 0   100%
tests/test_utils.py TestUrlCorrector.test_url_corrector_invalid_protocol   2 0 0   100%
tests/test_utils.py TestUrlCorrector.test_url_corrector_strips_whitespace   2 0 0   100%
tests/test_utils.py TestUrlCorrector.test_url_corrector_no_protocol   3 0 0   100%
tests/test_utils.py test_fuzzy_matches_rank_stably_without_mutating_input   6 0 0   100%
tests/test_utils.py test_fuzzy_matches_normalizes_absent_titles   6 0 0   100%
tests/test_utils.py test_fuzzy_matches_normalizes_absent_titles.score   3 0 0   100%
tests/test_utils.py (no function)   16 0 0   100%
Total     7953 142 2   98%

No items found using the specified filter.