Files
cproof/tests/unittests/test_ai_client.h
jabber.developer2 cac2aa856a
Some checks failed
CI Code / Check spelling (pull_request) Failing after 14s
CI Code / Check coding style (pull_request) Successful in 30s
CI Code / Linux (debian) (pull_request) Successful in 5m0s
CI Code / Linux (ubuntu) (pull_request) Successful in 5m8s
CI Code / Linux (arch) (pull_request) Successful in 6m36s
CI Code / Code Coverage (pull_request) Successful in 3m36s
fix(ai): bound response parsing and harden AUTO fallback errors
- bound _parse_responses scans to the output_text part's object and to
  the content array, so a later sibling item's "text" (e.g. a reasoning
  summary) can never be returned as the assistant reply
- do not retry the other flavour on a curl timeout: the request likely
  reached the server and may still be generating, so a re-POST of the
  conversation could trigger a second billed generation
- remember an unparseable 2xx from the first AUTO attempt and surface
  stashed first-attempt errors in both error paths, instead of showing
  only the final attempt's transport or HTTP error
- recognize Ollama's model-not-found wording in _names_model so a model
  typo is not misread as a missing endpoint
- drop the dead, racy provider-lookup fallback in the generic request
  thread: a missing provider ref is a caller bug and now fails loudly
- fix ai_providers_lists_defaults to expect the header the command
  actually prints ("Configured providers:"); the test was broken since
  its introduction but CI never ran it
- add functional test group 5 (AI command surface) to FUNC_TEST_GROUPS
  so the CI parallel target runs it; proftest.c port ranges already
  account for five groups
2026-07-10 12:07:34 +03:00

159 lines
7.7 KiB
C

/*
* test_ai_client.h - AI client unit test declarations
*/
int ai_client_setup(void** state);
int ai_client_teardown(void** state);
void test_ai_client_init(void** state);
void test_ai_add_provider(void** state);
void test_ai_remove_provider(void** state);
void test_ai_list_providers(void** state);
void test_ai_set_provider_key(void** state);
void test_ai_get_provider_key(void** state);
void test_ai_session_create(void** state);
void test_ai_session_ref_unref(void** state);
void test_ai_session_add_message(void** state);
void test_ai_session_clear_history(void** state);
void test_ai_session_set_model(void** state);
void test_ai_json_escape(void** state);
void test_ai_json_escape_null(void** state);
void test_ai_json_escape_empty(void** state);
void test_ai_json_escape_special_chars(void** state);
void test_ai_json_escape_percent_signs(void** state);
void test_ai_json_escape_backslash_quote(void** state);
void test_ai_session_api_key_is_copied(void** state);
void test_ai_add_provider_update_existing(void** state);
void test_ai_add_provider_null_name_returns_null(void** state);
void test_ai_add_provider_null_url_returns_null(void** state);
void test_ai_session_create_null_provider_returns_null(void** state);
void test_ai_session_create_null_model_returns_null(void** state);
void test_ai_session_api_key_null_when_no_key_set(void** state);
/* Provider autocomplete tests */
void test_ai_providers_find_forward(void** state);
void test_ai_providers_find_forward_custom(void** state);
void test_ai_providers_find_forward_no_match(void** state);
void test_ai_providers_find_forward_partial_match(void** state);
void test_ai_providers_find_next(void** state);
void test_ai_providers_find_previous(void** state);
void test_ai_providers_find_empty_search_str(void** state);
void test_ai_providers_find_null_search_str(void** state);
void test_ai_providers_find_case_insensitive(void** state);
/* Provider default model and settings tests */
void test_ai_set_provider_default_model(void** state);
void test_ai_get_provider_default_model(void** state);
void test_ai_set_provider_setting(void** state);
void test_ai_set_provider_setting_reserved_key(void** state);
void test_ai_get_provider_setting_keys(void** state);
void test_ai_set_provider_api_type(void** state);
void test_ai_api_type_string_round_trip(void** state);
void test_ai_get_provider_setting(void** state);
/* Model caching tests */
void test_ai_models_are_fresh_initial(void** state);
/* Model parsing tests */
void test_ai_parse_models_openai_format(void** state);
void test_ai_parse_models_perplexity_format(void** state);
void test_ai_parse_models_array_format(void** state);
void test_ai_parse_models_empty_json(void** state);
void test_ai_parse_models_null_handling(void** state);
void test_ai_parse_models_escaped_quotes(void** state);
void test_ai_parse_models_with_whitespace(void** state);
/* AI autocomplete integration tests */
void test_ai_start_provider_autocomplete_only_on_exact(void** state);
void test_ai_providers_find_cycling(void** state);
/* Setup that also initializes prefs for round-trip persistence tests. */
int ai_client_setup_with_prefs(void** state);
int ai_client_teardown_with_prefs(void** state);
/* Chat response parser tests (ai_parse_response) */
void test_ai_parse_response_openai_content(void** state);
void test_ai_parse_response_responses_output_text(void** state);
void test_ai_parse_response_responses_full_envelope(void** state);
void test_ai_parse_response_responses_reasoning_summary_skipped(void** state);
void test_ai_parse_response_choices_win_over_output(void** state);
void test_ai_parse_response_choices_in_string_value(void** state);
void test_ai_parse_response_content_before_choices(void** state);
void test_ai_parse_response_content_preferred_over_text(void** state);
void test_ai_parse_response_responses_brace_in_text(void** state);
void test_ai_parse_response_choices_logprobs_before_content(void** state);
void test_ai_parse_response_reasoning_not_leaked_without_text(void** state);
void test_ai_parse_response_responses_reasoning_only_returns_null(void** state);
void test_ai_parse_response_responses_reasoning_after_message_skipped(void** state);
void test_ai_parse_response_responses_empty_content_not_leaked(void** state);
void test_ai_parse_response_responses_text_value_before_later_item(void** state);
void test_ai_parse_response_responses_text_value_text(void** state);
void test_ai_parse_response_escaped_quote(void** state);
void test_ai_parse_response_newline_escape(void** state);
void test_ai_parse_response_empty_content(void** state);
void test_ai_parse_response_missing_field(void** state);
void test_ai_parse_response_null_input(void** state);
void test_ai_parse_response_empty_input(void** state);
void test_ai_parse_response_percent_signs_safe(void** state);
void test_ai_parse_response_braces_in_content(void** state);
void test_ai_parse_response_multiline_content(void** state);
/* Error response parser tests (ai_parse_error_message) */
void test_ai_parse_error_standard_envelope(void** state);
void test_ai_parse_error_with_escapes(void** state);
void test_ai_parse_error_no_error_field(void** state);
void test_ai_parse_error_no_message_field(void** state);
void test_ai_parse_error_null_input(void** state);
void test_ai_parse_error_empty_input(void** state);
void test_ai_parse_error_tab_escape(void** state);
void test_ai_parse_error_backslash_escape(void** state);
/* Extended JSON escape tests */
void test_ai_json_escape_backspace(void** state);
void test_ai_json_escape_formfeed(void** state);
void test_ai_json_escape_carriage_return(void** state);
void test_ai_json_escape_all_specials_combined(void** state);
void test_ai_json_escape_passes_utf8_through(void** state);
/* Autocomplete cycling with many providers */
void test_ai_providers_find_cycles_through_many(void** state);
void test_ai_providers_find_previous_walks_backwards(void** state);
void test_ai_providers_find_wraps_around(void** state);
/* Session edge cases */
void test_ai_session_add_message_null_session_no_crash(void** state);
void test_ai_session_add_message_null_role_no_crash(void** state);
void test_ai_session_add_message_null_content_no_crash(void** state);
void test_ai_session_history_preserves_large_order(void** state);
void test_ai_session_clear_empty_history(void** state);
void test_ai_session_set_model_null_keeps_old(void** state);
void test_ai_session_unref_null_no_crash(void** state);
void test_ai_session_ref_null_returns_null(void** state);
/* Provider edge cases */
void test_ai_get_provider_null_returns_null(void** state);
void test_ai_remove_provider_null_returns_false(void** state);
void test_ai_remove_provider_twice_second_fails(void** state);
void test_ai_provider_survives_via_session_after_removal(void** state);
/* Settings edge cases */
void test_ai_settings_multiple_keys_independent(void** state);
void test_ai_settings_get_missing_returns_null(void** state);
void test_ai_settings_isolated_between_providers(void** state);
/* Model parsing edge cases */
void test_ai_parse_models_data_not_array(void** state);
void test_ai_parse_models_empty_data_array(void** state);
void test_ai_parse_models_id_outside_data_ignored(void** state);
void test_ai_parse_models_multiple_models(void** state);
/* Prefs round-trip tests */
void test_ai_prefs_round_trip_api_key(void** state);
void test_ai_prefs_round_trip_remove_key(void** state);
void test_ai_prefs_round_trip_api_type(void** state);
void test_ai_prefs_multiple_providers_persist(void** state);
/* Autocomplete deeper coverage */
void test_ai_providers_find_after_remove_skips_removed(void** state);
/* Reset hook + persistence */
void test_ai_providers_reset_ac_restarts_cycle(void** state);
void test_ai_add_provider_persisted_across_init(void** state);
void test_ai_remove_provider_persisted_across_init(void** state);
void test_ai_models_persisted_across_init(void** state);