canonical / discourse-gatekeeper

Experimental GitHub Action to upload charm documentation to charmhub
Apache License 2.0
7 stars 7 forks source link

Extend hierarchy calculation for deeply nested pages #250

Open a-velasco opened 1 month ago

a-velasco commented 1 month ago

Overview

A small change to the calculation of page hierarchy to account for navigation tables with large jumps in nesting.

Previously, the difference in whitespace only got evaluated once, which only accounts for cases where the next item is nested one level higher or lower - but not more.

Rationale

This change is needed because the action fails on documentation sets with hierarchy jumps greater than 1. More context + examples in issue #249.

Module Changes

None

Checklist

jdkandersson commented 1 month ago

/canonical/self-hosted-runners/run-workflows 1d27df709c2e16cb56f91310322eac572c1328af

github-actions[bot] commented 1 month ago

Lint checks failed for 1d27df709c2e16cb56f91310322eac572c1328af

```

/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/tests/unit/test_index_contents_hierarchy.py:282:19: W291 trailing whitespace

github-actions[bot] commented 1 month ago

Unit tests failed for 1d27df709c2e16cb56f91310322eac572c1328af

```

============================= test session starts ============================== platform linux -- Python 3.10.12, pytest-8.2.2, pluggy-1.5.0 -- /home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/bin/python cachedir: .tox/unit/.pytest_cache rootdir: /home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper configfile: pyproject.toml plugins: asyncio-0.21.2, Faker-26.0.0, operator-0.35.0 asyncio: mode=strict collecting ... collected 746 items

tests/unit/action/test_other_actions.py::testcreate_directory[dry run mode enabled] PASSED tests/unit/action/test_other_actions.py::test__create_directory[dry run mode disabled] PASSED tests/unit/action/test_other_actions.py::testcreate_external_ref[dry run mode enabled] PASSED tests/unit/action/test_other_actions.py::testcreate_external_ref[dry run mode disabled] PASSED tests/unit/action/test_other_actions.py::testcreate_file_dry_run PASSED tests/unit/action/test_other_actions.py::testcreate_file_fail PASSED tests/unit/action/test_other_actions.py::testcreate_file[not hidden] PASSED tests/unit/action/test_other_actions.py::testcreate_file[hidden] PASSED tests/unit/action/test_other_actions.py::test__noop_dir_external_ref[directory] PASSED tests/unit/action/test_other_actions.py::testnoop_dir_external_ref[external ref] PASSED tests/unit/action/test_other_actions.py::testnoop_file PASSED tests/unit/action/test_other_actions.py::test__delete_not_delete_page[dry run mode enabled] PASSED tests/unit/action/test_other_actions.py::testdelete_not_delete_page[delete pages false enabled] PASSED tests/unit/action/test_other_actions.py::testdelete_not_delete_group_external_ref[group dry run enabled] PASSED tests/unit/action/test_other_actions.py::test__delete_not_delete_group_external_ref[group dry run disabled] PASSED tests/unit/action/test_other_actions.py::testdelete_not_delete_group_external_ref[external ref dry run enabled] PASSED tests/unit/action/test_other_actions.py::testdelete_not_delete_group_external_ref[external ref dry run disabled] PASSED tests/unit/action/test_other_actions.py::test__delete_error PASSED tests/unit/action/test_other_actions.py::testdelete PASSED tests/unit/action/test_other_actions.py::testrun_one[create page] PASSED tests/unit/action/test_other_actions.py::test__run_one[create group] PASSED tests/unit/action/test_other_actions.py::testrun_one[create external ref] PASSED tests/unit/action/test_other_actions.py::testrun_one[noop pae] PASSED tests/unit/action/test_other_actions.py::test__run_one[noop group] PASSED tests/unit/action/test_other_actions.py::testrun_one[noop external ref] PASSED tests/unit/action/test_other_actions.py::testrun_one[update] PASSED tests/unit/action/test_other_actions.py::test__run_one[delete page] PASSED tests/unit/action/test_other_actions.py::testrun_one[delete group] PASSED tests/unit/action/test_other_actions.py::testrun_one[delete external ref] PASSED tests/unit/action/test_other_actions.py::test__run_index_dry_run[create] PASSED tests/unit/action/test_other_actions.py::testrun_index_dry_run[noop] PASSED tests/unit/action/test_other_actions.py::testrun_index_dry_run[update] PASSED tests/unit/action/test_other_actions.py::test__run_index_create_error PASSED tests/unit/action/test_other_actions.py::testrun_index_create PASSED tests/unit/action/test_other_actions.py::testrun_index_noop PASSED tests/unit/action/test_other_actions.py::testrun_index_update_error PASSED tests/unit/action/test_other_actions.py::testrun_index_update PASSED tests/unit/action/test_other_actions.py::test_run_all[empty] PASSED tests/unit/action/test_other_actions.py::test_run_all[single] PASSED tests/unit/action/test_other_actions.py::test_run_all[multiple] PASSED tests/unit/action/test_update_action.py::testupdate_directory[external ref dry run mode enabled] PASSED tests/unit/action/test_update_action.py::testupdate_directory[external ref dry run mode disabled] PASSED tests/unit/action/test_update_action.py::test__update_directory[group dry run mode enabled] PASSED tests/unit/action/test_update_action.py::testupdate_directory[group dry run mode disabled] PASSED tests/unit/action/test_update_action.py::testupdate_file_dry_run PASSED tests/unit/action/test_update_action.py::testupdate_file_navlink_title_change PASSED tests/unit/action/test_update_action.py::testupdate_file_navlink_hidden_change PASSED tests/unit/action/test_update_action.py::testupdate_file_navlink_content_change_discourse_error PASSED tests/unit/action/test_update_action.py::testupdate_file_navlink_content_change_conflict[merge conflict] PASSED tests/unit/action/test_update_action.py::testupdate_file_navlink_content_change_conflict[no base] PASSED tests/unit/action/test_update_action.py::testupdate_file_navlink_content_change_post_check_conflict PASSED tests/unit/action/test_update_action.py::test__update_file_navlink_contentchange PASSED tests/unit/testinit.py::test_setup_clients[] PASSED tests/unit/test_init.py::test_setupclients[charm] PASSED tests/unit/testinit.py::testrun_reconcile_empty_local_server PASSED tests/unit/test_init.py::testrun_reconcile_empty_local_server_from_non_basebranch PASSED tests/unit/testinit.py::testrun_reconcile_local_empty_server PASSED tests/unit/test_init.py::test_run_reconcile_same_content_local_andserver[main] PASSED tests/unit/testinit.py::test_run_reconcile_same_content_local_andserver[other-main] PASSED tests/unit/testinit.py::testrun_reconcile_local_contentsindex PASSED tests/unit/testinit.py::testrun_reconcile_hidden_item PASSED tests/unit/test_init.py::testrun_reconcile_invalid_externalitem PASSED tests/unit/testinit.py::testrun_reconcile_external_item PASSED tests/unit/test_init.py::testrun_reconcile_local_empty_server_dryrun PASSED tests/unit/testinit.py::testrun_reconcile_local_empty_server_dry_run_no_tag PASSED tests/unit/test_init.py::testrun_reconcile_local_empty_server_error PASSED tests/unit/test_init.py::test__run_reconcile_local_serverconflict PASSED tests/unit/testinit.py::testrun_reconcile_no_docs PASSED tests/unit/test_init.py::testrun_reconcile_on_tagcommit PASSED tests/unit/testinit.py::testrun_migrate_server_error_index PASSED tests/unit/test_init.py::testrun_migrate_server_errortopic PASSED tests/unit/testinit.py::testrun_migrate_no_docs_information PASSED tests/unit/test_init.py::testrun_migrate PASSED tests/unit/test_init.py::test__run_migrate_with_pullrequest PASSED tests/unit/testinit.py::testrun_migrate_with_pull_request_no_modification PASSED tests/unit/test_init.py::test_run_no_docs_emptydir PASSED tests/unit/testinit__.py::test_run_no_docsdir PASSED tests/unit/testinit.py::test_run_no_docs_dir_no_tag PASSED tests/unit/test_init.py::test_run_migrate_same_content_local_and_server PASSED tests/unit/test_init.py::test_run_migrate_same_content_local_and_server_open_pr PASSED tests/unit/test_init.py::test_run_migrate_same_content_local_and_server_tag_notmoved PASSED tests/unit/testinit.py::test_pre_flight_checks_ok PASSED tests/unit/test_init.py::test_pre_flight_checks_ok_tag_not_exists PASSED tests/unit/test_init.py::test_pre_flight_checks_fail PASSED tests/unit/test_check.py::test_track_paths_with_diff[empty] PASSED tests/unit/test_check.py::test_track_paths_with_diff[single group] PASSED tests/unit/test_check.py::test_track_paths_with_diff[single external ref] PASSED tests/unit/test_check.py::test_track_paths_with_diff[single no diff] PASSED tests/unit/test_check.py::test_track_paths_with_diff[single base local diff] PASSED tests/unit/test_check.py::test_track_paths_with_diff[single base server diff] PASSED tests/unit/test_check.py::test_track_paths_with_diff[single base diff server local same] PASSED tests/unit/test_check.py::test_track_paths_with_diff[single all diff] PASSED tests/unit/test_check.py::test_track_paths_with_diff[single all diff base None] PASSED tests/unit/test_check.py::test_track_paths_with_diff[multiple all diff] PASSED tests/unit/test_check.py::test_track_paths_with_diff[multiple base diff local server same] PASSED tests/unit/test_check.py::test_conflicts[empty] PASSED tests/unit/test_check.py::test_conflicts[single create] PASSED tests/unit/test_check.py::test_conflicts[single noop] PASSED tests/unit/test_check.py::test_conflicts[single delete] PASSED tests/unit/test_check.py::test_conflicts[single group update] PASSED tests/unit/test_check.py::test_conflicts[single external ref update] PASSED tests/unit/test_check.py::test_conflicts[single update no base content same] PASSED tests/unit/test_check.py::test_conflicts[single update no base content different] PASSED tests/unit/test_check.py::test_conflicts[single update no conflict] PASSED tests/unit/test_check.py::test_conflicts[single update conflict] PASSED tests/unit/test_check.py::test_conflicts[multiple actions no problems] PASSED tests/unit/test_check.py::test_conflicts[multiple actions single problem first] PASSED tests/unit/test_check.py::test_conflicts[multiple actions single problem second] PASSED tests/unit/test_check.py::test_conflicts[multiple actions multiple problems] PASSED tests/unit/test_check.py::test_conflicts[multiple actions one has base and local other has local and server diff, tag applied] PASSED tests/unit/test_check.py::test_external_refs[empty] PASSED tests/unit/test_check.py::test_external_refs[single valid link] PASSED tests/unit/test_check.py::test_external_refs[single invalid link connection error] PASSED tests/unit/test_check.py::test_external_refs[single invalid link 404] PASSED tests/unit/test_check.py::test_external_refs[multiple first invalid] PASSED tests/unit/test_check.py::test_external_refs[multiple second invalid] PASSED tests/unit/test_check.py::test_external_refs[multiple invalid] PASSED tests/unit/test_check.py::test_external_refs[multiple valid links] PASSED tests/unit/test_commit.py::test_parse_git_show_empty PASSED tests/unit/test_commit.py::test_parse_git_show_unsupported PASSED tests/unit/test_commit.py::test_parse_git_show_added PASSED tests/unit/test_commit.py::test_parse_git_show_modified PASSED tests/unit/test_commit.py::test_parse_git_show_deleted PASSED tests/unit/test_commit.py::test_parse_git_show_renamed PASSED tests/unit/test_commit.py::test_parse_git_show_copied PASSED tests/unit/test_commit.py::test_parse_git_show_multiple PASSED tests/unit/test_content.py::test_conflicts[all same] PASSED tests/unit/test_content.py::test_conflicts[base and theirs the same] PASSED tests/unit/test_content.py::test_conflicts[base and ours the same] PASSED tests/unit/test_content.py::test_conflicts[theirs and ours the same] PASSED tests/unit/test_content.py::test_conflicts[all different conflict] PASSED tests/unit/test_content.py::test_conflicts[all different no git conflict] PASSED tests/unit/test_content.py::test_merge[all same] PASSED tests/unit/test_content.py::test_merge[base and theirs the same] PASSED tests/unit/test_content.py::test_merge[base and ours the same] PASSED tests/unit/test_content.py::test_merge[theirs and ours the same] PASSED tests/unit/test_content.py::test_merge[all different no conflict] PASSED tests/unit/test_content.py::test_merge_conflict PASSED tests/unit/test_content.py::test_diff[single line same] PASSED tests/unit/test_content.py::test_diff[single line different] PASSED tests/unit/test_content.py::test_diff[multiple line same] PASSED tests/unit/test_content.py::test_diff[multiple line different] PASSED tests/unit/test_discourse.py::test_topic_url_valid[empty] PASSED tests/unit/test_discourse.py::test_topic_url_valid[all components missing] PASSED tests/unit/test_discourse.py::test_topic_url_valid[2 components missing] PASSED tests/unit/test_discourse.py::test_topic_url_valid[1 component missing] PASSED tests/unit/test_discourse.py::test_topic_url_valid[too many components] PASSED tests/unit/test_discourse.py::test_topic_url_valid[first component wrong no character] PASSED tests/unit/test_discourse.py::test_topic_url_valid[first component wrong single character] PASSED tests/unit/test_discourse.py::test_topic_url_valid[first component wrong multi character] PASSED tests/unit/test_discourse.py::test_topic_url_valid[slug empty] PASSED tests/unit/test_discourse.py::test_topic_url_valid[topic id wrong character] PASSED tests/unit/test_discourse.py::test_topic_url_valid[topic id wrong integer and character] PASSED tests/unit/test_discourse.py::test_topic_url_valid[valid] PASSED tests/unit/test_discourse.py::test_topic_url_valid[valid trailing /] PASSED tests/unit/test_discourse.py::test_topic_url_valid[valid no protocol host] PASSED tests/unit/test_discourse.py::test_function_call_invalid_url[check_topic_write_permission] PASSED tests/unit/test_discourse.py::test_function_call_invalid_url[check_topic_read_permission] PASSED tests/unit/test_discourse.py::test_function_call_invalid_url[retrieve_topic] PASSED tests/unit/test_discourse.py::test_function_call_invalid_url[delete_topic] PASSED tests/unit/test_discourse.py::test_function_call_invalid_url[update_topic] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission None] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission string] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission empty] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission post_stream None] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission post_stream posts missing] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission post_stream posts None] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission post_stream posts empty] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission post_stream posts contains None] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission post_stream posts post empty] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission post_stream posts post post_number does not include 1] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission post_stream posts post user_deleted missing] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission post_stream posts post can_edit missing] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_write_permission post_stream posts post can_edit not boolean] PASSED tests/unit/test_discourse.py::test_check_topic_malformed[check_topic_read_permission None] PASSED tests/unit/test_discourse.py::test_check_topic_write_permission_user_deleted PASSED tests/unit/test_discourse.py::test_check_topic_success[check_topic_write_permission post_stream posts post can_edit False] PASSED tests/unit/test_discourse.py::test_check_topic_success[check_topic_write_permission post_stream posts post can_edit True] PASSED tests/unit/test_discourse.py::test_check_topic_success[check_topic_write_permission post_stream posts multiple post first has post_number == 1] PASSED tests/unit/test_discourse.py::test_check_topic_success[check_topic_write_permission post_stream posts multiple post second has post_number == 1] PASSED tests/unit/test_discourse.py::test_check_topic_success[check_topic_read_permission] PASSED tests/unit/test_discourse.py::test_create_topic_post_malformed[None] PASSED tests/unit/test_discourse.py::test_create_topic_post_malformed[topic_slug missing] PASSED tests/unit/test_discourse.py::test_create_topic_post_malformed[topic_slug not string] PASSED tests/unit/test_discourse.py::test_create_topic_post_malformed[topic_id missing] PASSED tests/unit/test_discourse.py::test_create_topic_post_malformed[topic_id not int] PASSED tests/unit/test_discourse.py::test_create_topic PASSED tests/unit/test_discourse.py::test_delete_topic PASSED tests/unit/test_discourse.py::test_update_topic_malformed[id missing] PASSED tests/unit/test_discourse.py::test_update_topic_malformed[id not integer] PASSED tests/unit/test_discourse.py::test_update_topic_discourse_error PASSED tests/unit/test_discourse.py::test_update_topic PASSED tests/unit/test_discourse.py::test_function_discourse_error[check_topic_write_permission] PASSED tests/unit/test_discourse.py::test_function_discourse_error[check_topic_read_permission] PASSED tests/unit/test_discourse.py::test_function_discourse_error[create_topic] PASSED tests/unit/test_discourse.py::test_function_discourse_error[delete_topic] PASSED tests/unit/test_discourse.py::test__parse_raw_content[version 2.6.0 response] PASSED tests/unit/test_discourse.py::testparse_raw_content[version 2.8.14 response] PASSED tests/unit/test_discourse.py::testparse_raw_content[version 2.8.14 response with post replies] PASSED tests/unit/test_discourse.py::test_retrieve_topic_read_error PASSED tests/unit/test_discourse.py::test_retrieve_topic_head_http_error PASSED tests/unit/test_discourse.py::test_retrieve_topic_get_http_error PASSED tests/unit/test_discourse.py::test_retrieve_topic PASSED tests/unit/test_discourse.py::test_absolute_url PASSED tests/unit/test_discourse.py::test_create_discourse_error[hostname empty] PASSED tests/unit/test_discourse.py::test_create_discourse_error[hostname has http] PASSED tests/unit/test_discourse.py::test_create_discourse_error[hostname has HTTP] PASSED tests/unit/test_discourse.py::test_create_discourse_error[hostname has https] PASSED tests/unit/test_discourse.py::test_create_discourse_error[empty category_id] PASSED tests/unit/test_discourse.py::test_create_discourse_error[category_id str that is not convertible to int] PASSED tests/unit/test_discourse.py::test_create_discourse_error[api_username empty] PASSED tests/unit/test_discourse.py::test_create_discourse_error[api_key empty] PASSED tests/unit/test_discourse.py::test_create_discourse[category_id string that is convertible to an integer] PASSED tests/unit/test_docs_directory.py::testget_directories_files[empty] PASSED tests/unit/test_docs_directory.py::testget_directories_files[single directory] PASSED tests/unit/test_docs_directory.py::testget_directories_files[single directory called index] PASSED tests/unit/test_docs_directory.py::testget_directories_files[multiple directories] PASSED tests/unit/test_docs_directory.py::testget_directories_files[nested directory] PASSED tests/unit/test_docs_directory.py::testget_directories_files[single file] PASSED tests/unit/test_docs_directory.py::testget_directories_files[single file upper case suffix] PASSED tests/unit/test_docs_directory.py::testget_directories_files[single file not documentation] PASSED tests/unit/test_docs_directory.py::testget_directories_files[single file index] PASSED tests/unit/test_docs_directory.py::testget_directories_files[single file index capitalised] PASSED tests/unit/test_docs_directory.py::testget_directories_files[multiple files] PASSED tests/unit/test_docs_directory.py::testget_directories_files[single directory and single file] PASSED tests/unit/test_docs_directory.py::testget_directories_files[file in directory] PASSED tests/unit/test_docs_directory.py::testget_directories_files[multiple files in multiple directories] PASSED tests/unit/test_docs_directory.py::test__calculate_level[file in docs] PASSED tests/unit/test_docs_directory.py::testcalculate_level[directory in docs] PASSED tests/unit/test_docs_directory.py::testcalculate_level[directory file in docs] PASSED tests/unit/test_docs_directory.py::test__calculate_level[multiple directories in docs] PASSED tests/unit/test_docs_directory.py::testcalculate_level[multiple directories file in docs] PASSED tests/unit/test_docs_directory.py::testcalculate_level[many directories in docs] PASSED tests/unit/test_docs_directory.py::testcalculate_level[many directories file in docs] PASSED tests/unit/test_docs_directory.py::test_calculate_table_path[file in docs] PASSED tests/unit/test_docs_directory.py::test_calculate_table_path[file in docs including space] PASSED tests/unit/test_docs_directory.py::test_calculate_table_path[file in docs including underscore] PASSED tests/unit/test_docs_directory.py::test_calculate_table_path[file in docs upper case suffix] PASSED tests/unit/test_docs_directory.py::test_calculate_table_path[file upper case in docs] PASSED tests/unit/test_docs_directory.py::test_calculate_table_path[directory in docs] PASSED tests/unit/test_docs_directory.py::test_calculate_table_path[directory file in docs] PASSED tests/unit/test_docs_directory.py::test_calculate_table_path[multiple directories in docs] PASSED tests/unit/test_docs_directory.py::test_calculate_table_path[multiple directories file in docs] PASSED tests/unit/test_docs_directory.py::test_calculate_table_path[many directories in docs] PASSED tests/unit/test_docs_directory.py::test_calculate_table_path[many directories file in docs] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[directory in docs] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[nested directory in docs] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[directory in docs with -] PASSED tests/unit/test_docs_directory.py::test__calculate_navlinktitle[directory in docs with ] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[file in docs empty] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[file in subdirectory empty] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[file including - in docs empty] PASSED tests/unit/test_docs_directory.py::testcalculate_navlinktitle[file including in docs empty] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[file in docs empty string] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[file in docs single line no title] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[file in docs multiple line no title] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[file in docs title on first line] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[file in docs title on first line with more lines] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[file in docs title on second line] PASSED tests/unit/test_docs_directory.py::testcalculate_navlink_title[file in docs title on second line with more lines] PASSED tests/unit/test_docs_directory.py::testget_path_info PASSED tests/unit/test_docs_directory.py::test_read[empty] PASSED tests/unit/test_docs_directory.py::test_read[single directory] PASSED tests/unit/test_docs_directory.py::test_read[multiple directories] PASSED tests/unit/test_docs_directory.py::test_read[multiple directories alternate order] PASSED tests/unit/test_docs_directory.py::test_read[single file] PASSED tests/unit/test_docs_directory.py::test_read[single file in directory] PASSED tests/unit/test_docs_directory.py::test_read[multiple files] PASSED tests/unit/test_docs_directory.py::test_read[multiple files alternate order] PASSED tests/unit/test_docs_directory.py::test_read_indico PASSED tests/unit/test_download.py::test_recreate_docs PASSED tests/unit/test_index.py::testread_docs_index_docs_directory_missing PASSED tests/unit/test_index.py::testread_docs_index_index_file_missing PASSED tests/unit/test_index.py::testread_docs_index_index_file PASSED tests/unit/test_index.py::test_get_metadata_yaml_retrieve_discourse_error PASSED tests/unit/test_index.py::test_get_metadata_yaml_retrieve_local_and_server PASSED tests/unit/test_index.py::test_get_metadata_yaml_retrieve_empty PASSED tests/unit/test_index.py::test_get_contents_from_page[navigation table only] PASSED tests/unit/test_index.py::test_get_contents_from_page[page content only] PASSED tests/unit/test_index.py::test_get_contents_from_page[multiline content only] PASSED tests/unit/test_index.py::test_get_contents_from_page[page with content and navigation table] PASSED tests/unit/test_index.py::test_get_contents_from_page[page with content and navigation header] PASSED tests/unit/test_index.py::test_get_contents_from_page[page with content and navigation header lower case] PASSED tests/unit/test_index.py::test_get_contents_from_page[page with content and navigation header upper case] PASSED tests/unit/test_index.py::test_get_contents_from_page[page with content after the navigation table] PASSED tests/unit/test_index.py::test_get_content_for_server[no file] PASSED tests/unit/test_index.py::test_get_content_for_server[empty] PASSED tests/unit/test_index.py::test_get_content_for_server[no contents section] PASSED tests/unit/test_index.py::test_get_content_for_server[no contents section multiple lines] PASSED tests/unit/test_index.py::test_get_content_for_server[only contents header] PASSED tests/unit/test_index.py::test_get_content_for_server[contents single line] PASSED tests/unit/test_index.py::test_get_content_for_server[contents multiple lines line] PASSED tests/unit/test_index.py::test_get_content_for_server[contents followed by header] PASSED tests/unit/test_index.py::test_get_content_for_server[contents followed by header with single line] PASSED tests/unit/test_index.py::test_get_content_for_server[contents followed by header with multiple lines] PASSED tests/unit/test_index.py::test_get_content_for_server[contents multiple lines line followed by header] PASSED tests/unit/test_index.py::test_get_content_for_server[contents followed by header followed by another contents] PASSED tests/unit/test_index_contents_get.py::test_get_contents[empty] PASSED tests/unit/test_index_contents_get.py::test_get_contents[single file] PASSED tests/unit/test_index_contents_get.py::test_get_contents[single directory] PASSED tests/unit/test_index_contents_get.py::test_get_contents[multiple files] PASSED tests/unit/test_index_contents_get.py::test_get_contents[multiple directories] PASSED tests/unit/test_index_contents_get.py::test_get_contents[file and directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[invalid external reference] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[file doesn't exist] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[file wrong extension] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[file wrong whitespace] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[directory not exist] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[directory wrong whitespace] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[hidden directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[hierarchy wrong whitespace] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[file wrong nesting] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[file wrong directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[directory wrong directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[file in wrong directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[directory in wrong directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid[dir following an item nested more than once] FAILED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy_invalid_dir_not_in_contents PASSED tests/unit/test_index_contents_hierarchy.py::test__calculate_contents_hierarchy[empty] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single file] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single external link] PASSED tests/unit/test_index_contents_hierarchy.py::test__calculate_contents_hierarchy[single external link upper case] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single external link http] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single file hidden] PASSED tests/unit/test_index_contents_hierarchy.py::test__calculate_contents_hierarchy[single file upper case extension] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[multiple files] PASSED tests/unit/test_index_contents_hierarchy.py::test__calculate_contents_hierarchy[multiple directories] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single file single directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single directory single file] PASSED tests/unit/test_index_contents_hierarchy.py::test__calculate_contents_hierarchy[single directory single external link0] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single directory single file in directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single directory single external link1] PASSED tests/unit/test_index_contents_hierarchy.py::test__calculate_contents_hierarchy[single directory single file in directory larger whitespace] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single directory single directory in directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[many files] PASSED tests/unit/test_index_contents_hierarchy.py::test__calculate_contents_hierarchy[many directories] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single file in directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[multiple files in directory] PASSED tests/unit/test_index_contents_hierarchy.py::test__calculate_contents_hierarchy[single directory single nested directory single file in nested directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[single directory single nested directory single directory in nested directory] PASSED tests/unit/test_index_contents_hierarchy.py::testcalculate_contents_hierarchy[multiple files in multiple directories] PASSED tests/unit/test_index_contents_parse.py::test__get_contents_parsed_items_invalid[first item only leader] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items_invalid[first item leader and reference title] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items_invalid[first item malformed reference title] PASSED tests/unit/test_index_contents_parse.py::test__get_contents_parsed_items_invalid[first item malformed reference value] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items_invalid[first item space between reference title and value] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items_invalid[first item has single leading space] PASSED tests/unit/test_index_contents_parse.py::test__get_contents_parsed_items_invalid[first item has multiple leading space] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items_invalid[first item trailing non-whitespace] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items_invalid[single malformed line] PASSED tests/unit/test_index_contents_parse.py::test__get_contents_parsed_items_invalid[multiple lines single malformed line second] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items_invalid[multiple lines single malformed line first] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items_invalid[multiple malformed lines] PASSED tests/unit/test_index_contents_parse.py::test__get_contents_parsed_items_invalid[multiple lines second missing leader] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items_invalid[multiple lines second missing leader alternate] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[missing file] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[empty file] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item hidden] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item new line between header and start] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item multiple whitespace after leader] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item trailing whitespace] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item multiple trailing whitespace] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item empty line after] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item numbered] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item numbered multiple digits] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item alphabetical] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item alphabetical multiple letters] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item star] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item content before] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item content after] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[single item content after with duplicate heading] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[multiple items flat] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[multiple items nested] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[multiple items nested alternate spacing single space] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[multiple items empty line middle] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[multiple items nested alternate leader] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[many items flat] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[many items second nested] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[many items last nested] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[many items nested] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[many items deeply nested] PASSED tests/unit/test_index_contents_parse.py::testget_contents_parsed_items[many items deeply nested different leaders] PASSED tests/unit/test_metadata.py::test_get_yaml_missing PASSED tests/unit/test_metadata.py::test_get_metadata_yaml_malformed[malformed0] PASSED tests/unit/test_metadata.py::test_get_metadata_yaml_malformed[malformed1] PASSED tests/unit/test_metadata.py::test_get_metadata_yaml_malformed[not dict] PASSED tests/unit/test_metadata.py::test_get_invalid_metadata[key: value-expected_error_msg_contents0] PASSED tests/unit/test_metadata.py::test_get_invalid_metadata[name: 1-expected_error_msg_contents1] PASSED tests/unit/test_metadata.py::test_get_invalid_metadata[name: name\ndocs: 1-expected_error_msg_contents2] PASSED tests/unit/test_metadata.py::test_get_invalid_metadata[name: name\ndocs: -expected_error_msg_contents3] PASSED tests/unit/test_metadata.py::test_get_metadata[name only] PASSED tests/unit/test_metadata.py::test_get_metadata[name and docs] PASSED tests/unit/test_metadata.py::test_get_charmcraft_yaml_malformed[malformed0] PASSED tests/unit/test_metadata.py::test_get_charmcraft_yaml_malformed[malformed1] PASSED tests/unit/test_metadata.py::test_get_charmcraft_yaml_malformed[not dict] PASSED tests/unit/test_metadata.py::test_get_invalid_charmcraft[key: value-expected_error_msg_contents0] PASSED tests/unit/test_metadata.py::test_get_invalid_charmcraft[name: 1-expected_error_msg_contents1] PASSED tests/unit/test_metadata.py::test_get_invalid_charmcraft[name: name\nlinks: 1-expected_error_msg_contents2] PASSED tests/unit/test_metadata.py::test_get_invalid_charmcraft[name: name\nlinks:\n documentation: 1-expected_error_msg_contents3] PASSED tests/unit/test_metadata.py::test_get_charmcraft[name only] PASSED tests/unit/test_metadata.py::test_get_charmcraft[name and docs] PASSED tests/unit/test_migration/test_private.py::testvalidate_table_rows_invalid_rows[Invalid starting row] PASSED tests/unit/test_migration/test_private.py::testvalidate_table_rows_invalid_rows[Invalid level(0)] PASSED tests/unit/test_migration/test_private.py::testvalidate_table_rows_invalid_rows[Invalid level(negative value)] PASSED tests/unit/test_migration/test_private.py::testvalidate_table_rows_invalid_rows[Invalid level sequence jump] PASSED tests/unit/test_migration/test_private.py::testvalidate_table_rows_invalid_rows[document sequence level increase(no group)] PASSED tests/unit/test_migration/test_private.py::testvalidate_table_rows_invalid_rows[document group sequence level increase(no group)] PASSED tests/unit/test_migration/test_private.py::testvalidate_table_rows_invalid_rows[document group sequence level increase(doc doesn't increase group level)] PASSED tests/unit/test_migration/test_private.py::testvalidate_table_rows[Valid starting row] PASSED tests/unit/test_migration/test_private.py::testvalidate_table_rows[Valid row sequence(increase)] PASSED tests/unit/test_migration/test_private.py::testvalidate_table_rows[Valid row sequence(decrease)] PASSED tests/unit/test_migration/test_private.py::testvalidate_table_rows[Valid row sequence(decrease multi)] PASSED tests/unit/test_migration/test_private.py::testcreate_document_meta[single doc file] PASSED tests/unit/test_migration/test_private.py::testcreate_document_meta[nested doc file] PASSED tests/unit/test_migration/test_private.py::testcreate_document_meta[typo in nested doc file path] PASSED tests/unit/test_migration/test_private.py::testcreate_gitkeep_meta[single group row] PASSED tests/unit/test_migration/test_private.py::testcreate_gitkeep_meta[nested group row with correct current path] PASSED tests/unit/test_migration/test_private.py::testindex_file_from_content PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[no table rows] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[single initial document] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[single initial group] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[single initial external ref] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[two documents] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[distinct two groups] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[distinct document and group] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[distinct document and external ref] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[distinct group and document] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[distinct external ref and document] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[nested document in group] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[nested group in group] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[distinct rows(group, group, group)] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[distinct rows(group, doc, group)] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[multi rows 1 nested(group, nested-doc, group)] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[multi rows 2 separately nested(group, nested-group, nested-doc)0] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[multi rows 2 nested in group(group, nested-doc, nested-doc)] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[multi rows 2 separately nested(group, nested-group, doc)] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[multi rows 2 separately nested(group, nested-group, nested-doc)1] PASSED tests/unit/test_migration/test_private.py::testextract_docs_from_table_rows[multi rows nested(group, nested-group, nested-group-nested-doc)] PASSED tests/unit/test_migration/test_private.py::test__migrate_gitkeep[single .gitkeep] PASSED tests/unit/test_migration/test_private.py::testmigrate_gitkeep[nested .gitkeep] PASSED tests/unit/test_migration/test_private.py::testtable_row_to_contents_index_line[page top level path0] PASSED tests/unit/test_migration/test_private.py::test__table_row_to_contents_index_line[page nested path path0] PASSED tests/unit/test_migration/test_private.py::testtable_row_to_contents_index_line[page deeply nested path0] PASSED tests/unit/test_migration/test_private.py::testtable_row_to_contents_index_line[group top level path] PASSED tests/unit/test_migration/test_private.py::test__table_row_to_contents_index_line[group nested path path] PASSED tests/unit/test_migration/test_private.py::testtable_row_to_contents_index_line[group deeply nested path] PASSED tests/unit/test_migration/test_private.py::testtable_row_to_contents_index_line[page top level path1] PASSED tests/unit/test_migration/test_private.py::test__table_row_to_contents_index_line[page nested path path1] PASSED tests/unit/test_migration/test_private.py::testtable_row_to_contents_index_line[page deeply nested path1] PASSED tests/unit/test_migration/test_private.py::testmigrate_navigation_table[empty rows] PASSED tests/unit/test_migration/test_private.py::testmigrate_navigation_table[single row] PASSED tests/unit/test_migration/test_private.py::testmigrate_navigation_table[multiple rows] PASSED tests/unit/test_migration/test_private.py::testmigrate_document_fail PASSED tests/unit/test_migration/test_private.py::testmigrate_document PASSED tests/unit/test_migration/test_private.py::test__migrate_index PASSED tests/unit/test_migration/test_private.py::testrun_one[gitkeep file] PASSED tests/unit/test_migration/test_private.py::testrun_one[document file] PASSED tests/unit/test_migration/test_private.py::test__run_one[index file] PASSED tests/unit/test_migration/test_private.py::testget_docs_metadata PASSED tests/unit/test_migration/test_public.py::test_run_error PASSED tests/unit/test_migration/test_public.py::test_run[single doc] PASSED tests/unit/test_migration/test_public.py::test_run[nested doc] PASSED tests/unit/test_migration/test_public.py::test_run[nested group no docs] PASSED tests/unit/test_navigation_table.py::testfilter_line[empty] PASSED tests/unit/test_navigation_table.py::test__filter_line[does not match any line regex] PASSED tests/unit/test_navigation_table.py::testfilter_line[line with nothing] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches the header lower case] PASSED tests/unit/test_navigation_table.py::test__filter_line[matches the header upper case] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches the header mixed case] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches the header single leading space] PASSED tests/unit/test_navigation_table.py::test__filter_line[matches the header multiple leading space] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches the header leading tab] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches the header space before level] PASSED tests/unit/test_navigation_table.py::test__filter_line[matches the header space after level] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches the header space before path] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches the header space after path] PASSED tests/unit/test_navigation_table.py::test__filter_line[matches the header space before navlink] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches the header space after navlink] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches the header trailing space] PASSED tests/unit/test_navigation_table.py::test__filter_line[matches filler single dash] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches filler multiple dash] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches filler leading space] PASSED tests/unit/test_navigation_table.py::test__filter_line[matches filler space before first column] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches filler space after first column] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches filler space before second column] PASSED tests/unit/test_navigation_table.py::test__filter_line[matches filler space after second column] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches filler space before third column] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches filler space after third column] PASSED tests/unit/test_navigation_table.py::test__filter_line[matches filler trailing space] PASSED tests/unit/test_navigation_table.py::testfilter_line[first column character] PASSED tests/unit/test_navigation_table.py::testfilter_line[second column empty] PASSED tests/unit/test_navigation_table.py::test__filter_line[second column forward slash] PASSED tests/unit/test_navigation_table.py::testfilter_line[third column empty] PASSED tests/unit/test_navigation_table.py::testfilter_line[third column leading square bracket missing] PASSED tests/unit/test_navigation_table.py::test__filter_line[third column title missing] PASSED tests/unit/test_navigation_table.py::testfilter_line[third column closing square bracket missing] PASSED tests/unit/test_navigation_table.py::testfilter_line[third column opening link bracket missing] PASSED tests/unit/test_navigation_table.py::test__filter_line[third column link includes backslash] PASSED tests/unit/test_navigation_table.py::testfilter_line[third column link is external] PASSED tests/unit/test_navigation_table.py::testfilter_line[third column closing link bracket missing] PASSED tests/unit/test_navigation_table.py::test__filter_line[matches row] PASSED tests/unit/test_navigation_table.py::testfilter_line[matches hidden row] PASSED tests/unit/test_navigation_table.py::testline_to_row[simple] PASSED tests/unit/test_navigation_table.py::testline_to_row[hidden] PASSED tests/unit/test_navigation_table.py::testline_to_row[simple leading space] PASSED tests/unit/test_navigation_table.py::testline_to_row[simple space before first column] PASSED tests/unit/test_navigation_table.py::testline_to_row[simple space after first column] PASSED tests/unit/test_navigation_table.py::testline_to_row[simple space before second column] PASSED tests/unit/test_navigation_table.py::testline_to_row[simple space after second column] PASSED tests/unit/test_navigation_table.py::testline_to_row[simple space before third column] PASSED tests/unit/test_navigation_table.py::testline_to_row[simple space after third column] PASSED tests/unit/test_navigation_table.py::testline_to_row[simple trailing space] PASSED tests/unit/test_navigation_table.py::testline_to_row[first column multiple digits] PASSED tests/unit/test_navigation_table.py::testline_to_row[second column multiple characters] PASSED tests/unit/test_navigation_table.py::testline_to_row[second column upper case] PASSED tests/unit/test_navigation_table.py::testline_to_row[second column digit] PASSED tests/unit/test_navigation_table.py::testline_to_row[second column underscore] PASSED tests/unit/test_navigation_table.py::testline_to_row[second column dash] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title multiple characters] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title capital character] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title digit] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title underscore] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title dash] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title punctuation colon] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title punctuation exclamation] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title punctuation plus] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title punctuation question] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title space] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title space before] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title space after] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column title embedded space] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column link defined] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column white spave between title and link] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column link whitespace before] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column link whitespace after] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column link multiple characters] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column link upper case] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column link digit] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column link forward slash] PASSED tests/unit/test_navigation_table.py::testline_to_row[third column link dash] PASSED tests/unit/test_navigation_table.py::testline_to_row_no_match PASSED tests/unit/test_navigation_table.py::testcheck_table_row_write_permission_group PASSED tests/unit/test_navigation_table.py::testcheck_table_row_write_permission_external PASSED tests/unit/test_navigation_table.py::testcheck_table_row_write_permission_page_error PASSED tests/unit/test_navigation_table.py::testcheck_table_row_write_permission_page_false PASSED tests/unit/test_navigation_table.py::test__check_table_row_write_permission_page_true PASSED tests/unit/test_navigation_table.py::test_from_page_missing_write_permission PASSED tests/unit/test_navigation_table.py::test_from_page[empty] PASSED tests/unit/test_navigation_table.py::test_from_page[header only] PASSED tests/unit/test_navigation_table.py::test_from_page[header, filler] PASSED tests/unit/test_navigation_table.py::test_from_page[header, filler and single row] PASSED tests/unit/test_navigation_table.py::test_from_page[header, filler and single hidden row] PASSED tests/unit/test_navigation_table.py::test_from_page[header, single row] PASSED tests/unit/test_navigation_table.py::test_from_page[text, header, single row] PASSED tests/unit/test_navigation_table.py::test_from_page[header, multiple rows] PASSED tests/unit/test_navigation_table.py::test_from_page[header, multiple rows second hidden] PASSED tests/unit/test_navigation_table.py::test_from_page[header, many rows last hidden] PASSED tests/unit/test_navigation_table.py::test_from_page_indico PASSED tests/unit/test_navigation_table.py::test_from_page_indico_path PASSED tests/unit/test_reconcile.py::testlocal_only_file[not hidden] PASSED tests/unit/test_reconcile.py::testlocal_only_file[hidden] PASSED tests/unit/test_reconcile.py::test__local_only_directory PASSED tests/unit/test_reconcile.py::testlocal_only_external_ref[not hidden] PASSED tests/unit/test_reconcile.py::testlocal_only_external_ref[hidden] PASSED tests/unit/test_reconcile.py::testlocal_and_server_error[level mismatch] PASSED tests/unit/test_reconcile.py::testlocal_and_server_error[table path mismatch] PASSED tests/unit/test_reconcile.py::testlocal_and_server_error[level and table path mismatch] PASSED tests/unit/test_reconcile.py::testget_server_content_missing_link PASSED tests/unit/test_reconcile.py::test__get_server_content_server_error PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_same[same] PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_same[local leading whitespace] PASSED tests/unit/test_reconcile.py::test__local_and_server_file_same[local leading whitespace new line] PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_same[local trailing whitespace] PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_same[server leading whitespace] PASSED tests/unit/test_reconcile.py::test__local_and_server_file_same[server leading whitespace new line] PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_same[server trailing whitespace] PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_content_change_repo_error PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_content_change_repo_tag_not_found PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_content_change_file_not_in_repo PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_content_change PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_content_change_base_content_ws PASSED tests/unit/test_reconcile.py::test__local_and_server_file_navlink_title_change PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_navlink_hidden_change PASSED tests/unit/test_reconcile.py::testlocal_and_server_directory_same PASSED tests/unit/test_reconcile.py::test__local_and_server_directory_navlink_title_changed PASSED tests/unit/test_reconcile.py::testlocal_and_server_external_ref_same PASSED tests/unit/test_reconcile.py::testlocal_and_server_external_ref_navlink_changed[title changed] PASSED tests/unit/test_reconcile.py::test__local_and_server_external_ref_navlink_changed[link changed] PASSED tests/unit/test_reconcile.py::testlocal_and_server_group_external_ref_to_file[group not hidden] PASSED tests/unit/test_reconcile.py::testlocal_and_server_group_external_ref_to_file[group hidden] PASSED tests/unit/test_reconcile.py::testlocal_and_server_group_external_ref_to_file[external ref not hidden] PASSED tests/unit/test_reconcile.py::testlocal_and_server_group_external_ref_to_file[external ref hidden] PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_to_directory PASSED tests/unit/test_reconcile.py::testlocal_and_server_file_to_external_ref PASSED tests/unit/test_reconcile.py::test__local_and_server_external_ref_to_directory PASSED tests/unit/test_reconcile.py::testlocal_and_server_directory_to_external_ref PASSED tests/unit/test_reconcile.py::testserver_only_file PASSED tests/unit/test_reconcile.py::test__server_only_file_discourse_error PASSED tests/unit/test_reconcile.py::testserver_only_directory PASSED tests/unit/test_reconcile.py::testserver_only_external_ref PASSED tests/unit/test_reconcile.py::testcalculate_action_error PASSED tests/unit/test_reconcile.py::testcalculate_action[path info defined table row None] PASSED tests/unit/test_reconcile.py::testcalculate_action[path info defined table row defined] PASSED tests/unit/test_reconcile.py::testcalculate_action[path info None table row defined] PASSED tests/unit/test_reconcile.py::test_run[empty path infos empty table rows] PASSED tests/unit/test_reconcile.py::test_run[single path info empty table rows] PASSED tests/unit/test_reconcile.py::test_run[multiple path infos empty table rows] PASSED tests/unit/test_reconcile.py::test_run[multiple path infos empty table rows alternate order] PASSED tests/unit/test_reconcile.py::test_run[empty path infos single table row] PASSED tests/unit/test_reconcile.py::test_run[empty path infos multiple table rows] PASSED tests/unit/test_reconcile.py::test_run[single path info single table row match] PASSED tests/unit/test_reconcile.py::test_run[single path info single table row level mismatch] PASSED tests/unit/test_reconcile.py::test_run[single path info single table row path mismatch] PASSED tests/unit/test_reconcile.py::test_index_page[empty local only empty rows] PASSED tests/unit/test_reconcile.py::test_index_page[local only empty rows] PASSED tests/unit/test_reconcile.py::test_index_page[local only single row] PASSED tests/unit/test_reconcile.py::test_index_page[local only multiple rows] PASSED tests/unit/test_reconcile.py::test_index_page[local server same empty rows] PASSED tests/unit/test_reconcile.py::test_index_page[local server whitespace different same empty rows] PASSED tests/unit/test_reconcile.py::test_index_page[local whitespace server different same empty rows] PASSED tests/unit/test_reconcile.py::test_index_page[local server different empty rows] PASSED tests/unit/test_reconcile.py::testis_same_content_actions[Noop action] PASSED tests/unit/test_reconcile.py::testis_same_content_actions[Create action] PASSED tests/unit/test_reconcile.py::testis_same_content_actions[Delete action] PASSED tests/unit/test_reconcile.py::testis_same_content_actions[Update action] PASSED tests/unit/test_reconcile.py::testis_same_content_actions[Update action with same content] PASSED tests/unit/test_reconcile.py::testis_same_content_index[same index] PASSED tests/unit/test_reconcile.py::testis_same_content_index[different index] PASSED tests/unit/test_reconcile.py::testis_same_content_index[missing server content] PASSED tests/unit/test_reconcile.py::testis_same_content_index[missing local content] PASSED tests/unit/test_repository.py::testcommit_file_to_tree_element_added PASSED tests/unit/test_repository.py::testcommit_file_to_tree_element_deleted PASSED tests/unit/test_repository.py::testinit PASSED tests/unit/test_repository.py::testinitname_email_set PASSED tests/unit/test_repository.py::test_current_branch_switch_main PASSED tests/unit/test_repository.py::test_current_branch_switch_to_tag PASSED tests/unit/test_repository.py::test_commit_in_branch_check PASSED tests/unit/test_repository.py::test_commit_in_branch_non_existing_hash PASSED tests/unit/test_repository.py::test_commit_in_branch_unknown_error PASSED tests/unit/test_repository.py::test_create_branch_error PASSED tests/unit/test_repository.py::test_create_branch PASSED tests/unit/test_repository.py::test_create_branch_checkout_clash_default PASSED tests/unit/test_repository.py::test_create_branch_checkout_clash_created PASSED tests/unit/test_repository.py::test_create_pull_request_error PASSED tests/unit/test_repository.py::test_create_pull_request PASSED tests/unit/test_repository.py::test_tag_commit_tag_error PASSED tests/unit/test_repository.py::test_tag_commit_tag_not_exists PASSED tests/unit/test_repository.py::test_tag_commit_tag_update PASSED tests/unit/test_repository.py::test_tag_other_commit PASSED tests/unit/test_repository.py::test_get_file_content_from_tag_tag_github_error PASSED tests/unit/test_repository.py::test_get_file_content_from_tag_tag_unknown_object_error PASSED tests/unit/test_repository.py::test_get_file_content_from_tag_content_github_error PASSED tests/unit/test_repository.py::test_get_file_content_from_tag_unknown_object_error PASSED tests/unit/test_repository.py::test_get_file_content_from_tag_list PASSED tests/unit/test_repository.py::test_get_file_content_from_tag_content_none PASSED tests/unit/test_repository.py::test_get_file_content_from_tag PASSED tests/unit/test_repository.py::test_get_file_content_from_tag_commit_tag PASSED tests/unit/test_repository.py::test_get_repository_name_invalid[non-github url] PASSED tests/unit/test_repository.py::test_get_repository_name_invalid[http url] PASSED tests/unit/test_repository.py::test_get_repository_name_invalid[ssh url] PASSED tests/unit/test_repository.py::test_get_repository_name[valid url] PASSED tests/unit/test_repository.py::test_get_repository_name[valid git url] PASSED tests/unit/test_repository.py::test_create_repository_client_no_token PASSED tests/unit/test_repository.py::test_create_repository_client PASSED tests/unit/test_repository.py::test_create_repository_client_with_charm_dir PASSED tests/unit/test_repository.py::test_repository_summary_modified[docs folder only] PASSED tests/unit/test_repository.py::test_repository_summary_modified[all path] PASSED tests/unit/test_repository.py::test_repository_summary_new[docs folder only] PASSED tests/unit/test_repository.py::test_repository_summary_new[all path] PASSED tests/unit/test_repository.py::test_repository_summary_remove[docs folder only] PASSED tests/unit/test_repository.py::test_repository_summary_remove[all path] PASSED tests/unit/test_repository.py::test_commit_file_outside_of_folder PASSED tests/unit/test_repository.py::test_repository_summary_invalid_operation PASSED tests/unit/test_repository.py::test_repository_pull_default_branch PASSED tests/unit/test_repository.py::test_repository_pull_other_branch PASSED tests/unit/test_repository.py::test_switch_branch_pop_error PASSED tests/unit/test_repository.py::testgithub_client_push_single PASSED tests/unit/test_repository.py::testgithub_client_push_multiple PASSED tests/unit/test_repository.py::test_update_branch_unknown_error PASSED tests/unit/test_repository.py::test_update_branch_github_api_git_error PASSED tests/unit/test_repository.py::test_update_branch_github_api_github_error PASSED tests/unit/test_repository.py::test_update_branch_github_api PASSED tests/unit/test_repository.py::test_get_single_pull_request PASSED tests/unit/test_repository.py::test_get_non_existing_pull_request PASSED tests/unit/test_repository.py::test_get_multiple_pull_request_error PASSED tests/unit/test_repository.py::test_create_pull_request_no_dirty_files PASSED tests/unit/test_repository.py::test_create_pull_request_existing_branch PASSED tests/unit/test_repository.py::test_create_pull_request_function PASSED tests/unit/test_sort.py::test_using_contents_index[empty] PASSED tests/unit/test_sort.py::test_using_contents_index[single path info file no contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[single path info directory no contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[single path info file matching contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[single path info file matching hidden contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[single external contents index item] PASSED tests/unit/test_sort.py::test_using_contents_index[single path info directory matching contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[multiple path info wrong order no contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[multiple path info contents index wrong order] PASSED tests/unit/test_sort.py::test_using_contents_index[multiple path info contents index first] PASSED tests/unit/test_sort.py::test_using_contents_index[multiple path info contents index second] PASSED tests/unit/test_sort.py::test_using_contents_index[multiple path info file contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[multiple path info directory contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[multiple path info file and directory contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[multiple path info file in directory contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[single path info external item in directory contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[multiple path info directory in directory contents index] PASSED tests/unit/test_sort.py::test_using_contents_index[many path info in directory contents index first] PASSED tests/unit/test_sort.py::test_using_contents_index[many path info in directory contents index second] PASSED tests/unit/test_sort.py::test_using_contents_index[many path info in nested directory contents index directories only] PASSED tests/unit/test_sort.py::test_using_contents_index[many path info in nested directory contents index directories all] PASSED tests/unit/test_sort.py::test_using_contents_index[many path info in nested directory contents index directories included item follows not included] PASSED tests/unit/test_sort.py::test_using_contents_index[many path info in nested directory contents index directories included item follows multiple not included] PASSED tests/unit/test_sort.py::test_using_contents_index[many path info in nested directory contents index directories included item multiple follows not included] PASSED tests/unit/testtypes.py::test_table_row_is_group[not group] PASSED tests/unit/testtypes.py::test_table_row_is_group[is group] PASSED tests/unit/testtypes.py::test_table_row_is_external[group] PASSED tests/unit/testtypes.py::test_table_row_is_external[local link] PASSED tests/unit/testtypes.py::test_table_row_is_external[link matching server url] PASSED tests/unit/testtypes.py::test_table_row_is_external[link matching server url different case] PASSED tests/unit/testtypes.py::test_table_row_is_external[external link] PASSED tests/unit/testtypes.py::test_table_row_is_external[external link query string] PASSED tests/unit/testtypes.py::test_table_row_is_external[external link anchor] PASSED tests/unit/testtypes.py::test_table_row_is_external[external link upper case] PASSED tests/unit/testtypes.py::test_table_row_is_external[external link http] PASSED tests/unit/testtypes.py::test_table_row_to_markdown[not group] PASSED tests/unit/testtypes.py::test_table_row_to_markdown[not group hidden] PASSED tests/unit/testtypes.py::test_table_row_to_markdown[url with protocol and host matching server hostname] PASSED tests/unit/testtypes.py::test_table_row_to_markdown[url with protocol and host matching server hostname different case] PASSED tests/unit/testtypes.py::test_table_row_to_markdown[is group0] PASSED tests/unit/testtypes.py::test_table_row_to_markdown[is group hidden] PASSED tests/unit/testtypes.py::test_table_row_to_markdown[is group1] PASSED tests/unit/testtypes.py::test_table_row_to_markdown[is external] PASSED tests/unit/testtypes.py::test_table_row_to_markdown[is external hidden] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[top level dir] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[top level file] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[dir in dir] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[file in dir] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[dir in dir in dir] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[external] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[external with path] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[external with query] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[external with anchor] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[external with single special characters] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[external with multiple special characters] PASSED tests/unit/testtypes.py::test_index_contens_list_item_table_path[external with deep path] PASSED

=================================== FAILURES =================================== _ testcalculate_contents_hierarchyinvalid[dir following an item nested more than once] Traceback (most recent call last): File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/runner.py", line 341, in from_call result: Optional[TResult] = func() File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/runner.py", line 241, in lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_hooks.py", line 513, in call return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_manager.py", line 120, in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_callers.py", line 139, in _multicall raise exception.with_traceback(exception.traceback) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/threadexception.py", line 87, in pytest_runtest_call yield from thread_exception_runtest_hook() File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/threadexception.py", line 63, in thread_exception_runtest_hook yield File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/unraisableexception.py", line 90, in pytest_runtest_call yield from unraisable_exception_runtest_hook() File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/unraisableexception.py", line 65, in unraisable_exception_runtest_hook yield File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/logging.py", line 850, in pytest_runtest_call yield from self._runtest_for(item, "call") File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/logging.py", line 833, in _runtest_for yield File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/capture.py", line 878, in pytest_runtest_call return (yield) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_callers.py", line 122, in _multicall teardown.throw(exception) # type: ignore[union-attr] File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/skipping.py", line 257, in pytest_runtest_call return (yield) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_callers.py", line 103, in _multicall res = hook_impl.function(args) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/runner.py", line 173, in pytest_runtest_call item.runtest() File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/python.py", line 1632, in runtest self.ihook.pytest_pyfunc_call(pyfuncitem=self) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_hooks.py", line 513, in call return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_manager.py", line 120, in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_callers.py", line 182, in _multicall return outcome.get_result() File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_result.py", line 100, in get_result raise exc.with_traceback(exc.traceback) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/pluggy/_callers.py", line 103, in _multicall res = hook_impl.function(args) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/python.py", line 162, in pytest_pyfunc_call result = testfunction(**testargs) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/tests/unit/test_index_contents_hierarchy.py", line 339, in test__calculate_contents_hierarchy_invalid with pytest.raises(exceptions.InputError) as exc_info: File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/python_api.py", line 997, in exit__ fail(self.message) File "/home/ubuntu/github-runner/_work/discourse-gatekeeper/discourse-gatekeeper/.tox/unit/lib/python3.10/site-packages/_pytest/outcomes.py", line 177, in fail raise Failed(msg=reason, pytrace=pytrace) Failed: DID NOT RAISE <class 'gatekeeper.exceptions.InputError'> =============================== warnings summary =============================== tests/unit/test_repository.py::test_switch_branch_pop_error tests/unit/test_repository.py::test_update_branch_unknown_error tests/unit/test_repository.py::test_update_branch_github_api_git_error tests/unit/test_repository.py::test_update_branch_github_api_github_error tests/unit/test_repository.py::test_update_branch_github_api /usr/lib/python3.10/unittest/mock.py:505: DeprecationWarning: Git.USE_SHELL is deprecated, because only its default value of False is safe. It will be removed in a future release. if iscoroutinefunction(getattr(spec, attr, None)):

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html =========================== short test summary info ============================ FAILED tests/unit/test_index_contents_hierarchy.py::test__calculate_contents_hierarchy_invalid[dir following an item nested more than once] - Failed: DID NOT RAISE <class 'gatekeeper.exceptions.InputError'> ================== 1 failed, 745 passed, 5 warnings in 34.00s ==================

github-actions[bot] commented 1 month ago

Test coverage for 1d27df709c2e16cb56f91310322eac572c1328af

Name                                 Stmts   Miss Branch BrPart  Cover   Missing
--------------------------------------------------------------------------------
src/gatekeeper/__init__.py              96      0     42      0   100%
src/gatekeeper/action.py               158      0     48      0   100%
src/gatekeeper/check.py                 62      0     25      0   100%
src/gatekeeper/clients.py               11      0      0      0   100%
src/gatekeeper/commit.py                41      0     12      0   100%
src/gatekeeper/constants.py              8      0      0      0   100%
src/gatekeeper/content.py               49      0     10      0   100%
src/gatekeeper/discourse.py            157      0     34      0   100%
src/gatekeeper/docs_directory.py        32      0      8      0   100%
src/gatekeeper/download.py              21      0      2      0   100%
src/gatekeeper/exceptions.py            14      0      0      0   100%
src/gatekeeper/index.py                142      0     56      0   100%
src/gatekeeper/metadata.py              58      0     28      0   100%
src/gatekeeper/migration.py            101      0     33      0   100%
src/gatekeeper/navigation_table.py      64      0     20      0   100%
src/gatekeeper/reconcile.py            122      0     60      0   100%
src/gatekeeper/repository.py           292      0     88      0   100%
src/gatekeeper/sort.py                  42      0     26      0   100%
src/gatekeeper/types_.py               201      0     54      0   100%
--------------------------------------------------------------------------------
TOTAL                                 1671      0    546      0   100%

Static code analysis report

Working... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:02
Run started:2024-06-28 01:09:23.429197

Test results:
    No issues identified.

Code scanned:
    Total lines of code: 17923
    Total lines skipped (#nosec): 3
    Total potential issues skipped due to specifically being disabled (e.g., #nosec BXXX): 0

Run metrics:
    Total issues (by severity):
        Undefined: 0
        Low: 0
        Medium: 0
        High: 0
    Total issues (by confidence):
        Undefined: 0
        Low: 0
        Medium: 0
        High: 0
Files skipped (0):
jdkandersson commented 3 weeks ago

It also looks like there have been changed to the discourse change, the ad admin user is no longer there (required for testing), it is now create user ands then promote user. Would you like to fix that?