← Về thư mục
tests/scientific-slides/test_scripts.py
- child_environment · function · L81-L85 — def child_environment() -> dict[str, str]
- TemporaryDirectoryTestCase · class · L88-L110 — class TemporaryDirectoryTestCase(unittest.TestCase)
- setUp · method · L89-L92 — def setUp(self) -> None
- deck · method · L94-L101 — def deck(self, pages: int = 2, size: tuple[int, int] = (1280, 720)) -> Path
- image · method · L106-L110 — def image(self, name: str, size: tuple[int, int] = (320, 180), mode="RGB") -> Path
- validated · function · L113-L116 — def validated(path, duration=None) -> dict
- SlideBudgetTests · class · L119-L195 — class SlideBudgetTests(unittest.TestCase)
- counted · method · L122-L125 — def counted(self, slides: int, duration: int) -> dict
- test_every_duration_brackets_its_recommendation · method · L127-L131 — def test_every_duration_brackets_its_recommendation(self) -> None
- test_the_budget_grows_with_the_talk_length · method · L133-L135 — def test_the_budget_grows_with_the_talk_length(self) -> None
- test_the_recommendations_track_one_slide_per_minute · method · L137-L143 — def test_the_recommendations_track_one_slide_per_minute(self) -> None: # The rule the skill's own timing_guidelines.md is built on; a table that # drifted far from it would contradict the guidance it ships with.
- test_the_ranges_overlap_the_shipped_timing_asset · method · L145-L162 — def test_the_ranges_overlap_the_shipped_timing_asset(self) -> None: # assets/timing_guidelines.md tabulates "Duration | Total Slides"; the # validator must not call a deck too long when that table calls it right.
- test_a_deck_inside_the_range_is_reported_as_fine · method · L164-L170 — def test_a_deck_inside_the_range_is_reported_as_fine(self) -> None: # 16 slides for a 15-minute talk: squarely inside 13-20.
- test_too_few_slides_warns_about_the_empty_time · method · L172-L175 — def test_too_few_slides_warns_about_the_empty_time(self) -> None
- test_too_many_slides_warns_about_running_over · method · L177-L180 — def test_too_many_slides_warns_about_running_over(self) -> None
- test_the_boundaries_themselves_are_acceptable · method · L182-L186 — def test_the_boundaries_themselves_are_acceptable(self) -> None
- test_an_untabulated_duration_borrows_the_nearest_one · method · L188-L195 — def test_an_untabulated_duration_borrows_the_nearest_one(self) -> None: # 12 minutes is closest to the 10-minute row, and the substitution has # to be stated or the numbers look wrong to the user.
- ValidatorFileTests · class · L198-L238 — class ValidatorFileTests(TemporaryDirectoryTestCase)
- test_a_missing_file_is_the_only_thing_reported · method · L199-L202 — def test_a_missing_file_is_the_only_thing_reported(self) -> None
- test_an_unsupported_extension_warns_but_does_not_fail · method · L204-L209 — def test_an_unsupported_extension_warns_but_does_not_fail(self) -> None
- test_the_file_type_is_recognised_case_insensitively · method · L211-L213 — def test_the_file_type_is_recognised_case_insensitively(self) -> None
- sized · method · L215-L222 — def sized(self, megabytes: float) -> dict
- test_an_ordinary_deck_size_is_only_reported · method · L224-L228 — def test_an_ordinary_deck_size_is_only_reported(self) -> None
- test_a_large_deck_warns_about_sharing_it · method · L230-L233 — def test_a_large_deck_warns_about_sharing_it(self) -> None
- test_an_enormous_deck_is_an_issue_not_a_warning · method · L235-L238 — def test_an_enormous_deck_is_an_issue_not_a_warning(self) -> None
- ValidatorPdfTests · class · L241-L280 — class ValidatorPdfTests(TemporaryDirectoryTestCase)
- setUp · method · L242-L245 — def setUp(self) -> None
- test_a_widescreen_deck_reports_its_page_count_and_ratio · method · L247-L254 — def test_a_widescreen_deck_reports_its_page_count_and_ratio(self) -> None: # Regression: with only pypdf installed this whole branch used to be # skipped, and the validator reported nothing about the deck at all.
- test_a_four_by_three_deck_is_recognised · method · L256-L258 — def test_a_four_by_three_deck_is_recognised(self) -> None
- test_an_unusual_aspect_ratio_is_flagged_for_the_venue · method · L260-L264 — def test_an_unusual_aspect_ratio_is_flagged_for_the_venue(self) -> None
- test_the_slide_dimensions_are_reported_in_inches · method · L266-L269 — def test_the_slide_dimensions_are_reported_in_inches(self) -> None: # 1280 x 720 points at 72 points per inch is 17.8" x 10.0".
- test_the_page_count_is_measured_against_the_duration · method · L271-L273 — def test_the_page_count_is_measured_against_the_duration(self) -> None
- test_a_corrupt_pdf_is_an_issue_rather_than_a_traceback · method · L275-L280 — def test_a_corrupt_pdf_is_an_issue_rather_than_a_traceback(self) -> None
- ValidatorLatexTests · class · L283-L318 — class ValidatorLatexTests(TemporaryDirectoryTestCase)
- source · method · L286-L289 — def source(self) -> Path
- test_a_failed_compile_is_an_issue_pointing_at_the_log · method · L291-L296 — def test_a_failed_compile_is_an_issue_pointing_at_the_log(self) -> None
- test_a_successful_compile_folds_in_the_pdf_report · method · L298-L310 — def test_a_successful_compile_folds_in_the_pdf_report(self) -> None
- test_the_compile_never_enables_shell_escape · method · L312-L318 — def test_the_compile_never_enables_shell_escape(self) -> None: # Shell escape in a LaTeX source would run arbitrary commands.
- ValidatorPptxTests · class · L321-L383 — class ValidatorPptxTests(TemporaryDirectoryTestCase)
- setUp · method · L322-L325 — def setUp(self) -> None
- build · method · L327-L342 — def build(self, *, font_pt: int, bullets: int) -> Path
- test_a_readable_uncluttered_slide_raises_nothing · method · L344-L350 — def test_a_readable_uncluttered_slide_raises_nothing(self) -> None
- test_text_below_eighteen_point_is_flagged_with_the_slide_number · method · L352-L359 — def test_text_below_eighteen_point_is_flagged_with_the_slide_number(self) -> None: # 18 pt is the projection floor the skill documents.
- test_eighteen_point_itself_is_acceptable · method · L361-L365 — def test_eighteen_point_itself_is_acceptable(self) -> None
- test_more_than_six_bullets_is_flagged · method · L367-L372 — def test_more_than_six_bullets_is_flagged(self) -> None
- test_six_bullets_is_still_acceptable · method · L374-L378 — def test_six_bullets_is_still_acceptable(self) -> None
- test_the_slide_geometry_is_reported · method · L380-L383 — def test_the_slide_geometry_is_reported(self) -> None
- PdfToImagesTests · class · L386-L448 — class PdfToImagesTests(TemporaryDirectoryTestCase)
- test_only_jpeg_and_png_are_accepted · method · L387-L399 — def test_only_jpeg_and_png_are_accepted(self) -> None
- test_a_missing_pdf_is_refused_before_any_conversion · method · L401-L407 — def test_a_missing_pdf_is_refused_before_any_conversion(self) -> None
- convert · method · L409-L417 — def convert(self, **kwargs)
- test_every_page_becomes_one_zero_padded_image · method · L419-L426 — def test_every_page_becomes_one_zero_padded_image(self) -> None
- test_the_output_directory_is_created_on_demand · method · L428-L430 — def test_the_output_directory_is_created_on_demand(self) -> None
- test_the_requested_dpi_sets_the_pixel_size · method · L432-L436 — def test_the_requested_dpi_sets_the_pixel_size(self) -> None: # A 720-point-tall slide at 144 dpi is 1440 pixels: zoom = dpi / 72.
- test_a_page_range_converts_only_those_slides · method · L438-L443 — def test_a_page_range_converts_only_those_slides(self) -> None
- test_the_format_decides_the_encoding_not_just_the_suffix · method · L445-L448 — def test_the_format_decides_the_encoding_not_just_the_suffix(self) -> None
- ImageCollectionTests · class · L451-L491 — class ImageCollectionTests(TemporaryDirectoryTestCase)
- test_files_are_ordered_by_name_so_numbering_decides_the_deck · method · L452-L460 — def test_files_are_ordered_by_name_so_numbering_decides_the_deck(self) -> None: # Zero-padded names sort correctly; "10" must not precede "2".
- test_a_directory_yields_every_supported_image · method · L462-L466 — def test_a_directory_yields_every_supported_image(self) -> None
- test_a_non_image_file_is_skipped_with_a_warning · method · L468-L476 — def test_a_non_image_file_is_skipped_with_a_warning(self) -> None
- test_the_same_file_named_twice_appears_once · method · L478-L481 — def test_the_same_file_named_twice_appears_once(self) -> None
- test_a_glob_pattern_is_expanded · method · L483-L488 — def test_a_glob_pattern_is_expanded(self) -> None
- test_a_path_that_matches_nothing_yields_nothing · method · L490-L491 — def test_a_path_that_matches_nothing_yields_nothing(self) -> None
- SlidesToPdfTests · class · L494-L541 — class SlidesToPdfTests(TemporaryDirectoryTestCase)
- combine · method · L495-L499 — def combine(self, images, name="talk.pdf", **kwargs)
- page_count · method · L501-L506 — def page_count(self, path: Path) -> int
- test_the_slides_become_pages_in_the_order_given · method · L508-L512 — def test_the_slides_become_pages_in_the_order_given(self) -> None
- test_the_output_directory_is_created · method · L514-L517 — def test_the_output_directory_is_created(self) -> None
- test_no_images_is_refused_rather_than_writing_an_empty_pdf · method · L519-L523 — def test_no_images_is_refused_rather_than_writing_an_empty_pdf(self) -> None
- test_a_transparent_slide_is_flattened_onto_white · method · L525-L529 — def test_a_transparent_slide_is_flattened_onto_white(self) -> None: # PDF has no alpha channel; without the flattening step Pillow raises.
- test_a_greyscale_slide_is_converted_rather_than_rejected · method · L531-L533 — def test_a_greyscale_slide_is_converted_rather_than_rejected(self) -> None
- test_an_unreadable_slide_aborts_instead_of_producing_a_short_deck · method · L535-L541 — def test_an_unreadable_slide_aborts_instead_of_producing_a_short_deck(self) -> None
- SlideImageEnvironmentTests · class · L544-L587 — class SlideImageEnvironmentTests(unittest.TestCase)
- test_only_allowlisted_variables_reach_the_subprocess · method · L547-L556 — def test_only_allowlisted_variables_reach_the_subprocess(self) -> None
- test_the_api_key_is_injected_under_the_expected_name · method · L558-L561 — def test_the_api_key_is_injected_under_the_expected_name(self) -> None
- test_no_key_means_no_key_variable_rather_than_an_empty_one · method · L563-L571 — def test_no_key_means_no_key_variable_rather_than_an_empty_one(self) -> None: # An empty value would look configured and fail deep inside the request.
- test_the_allowlist_carries_no_credential_variables · method · L573-L577 — def test_the_allowlist_carries_no_credential_variables(self) -> None
- test_the_allowlist_matches_the_schematic_wrapper_in_this_skill · method · L579-L587 — def test_the_allowlist_matches_the_schematic_wrapper_in_this_skill(self) -> None: # Both wrappers in this skill spawn an AI child the same way; a variable # added to one and not the other breaks proxies or TLS in half the tools.
- SlideImageInvocationTests · class · L590-L657 — class SlideImageInvocationTests(TemporaryDirectoryTestCase)
- invoke · method · L593-L603 — def invoke(self, *arguments)
- test_the_generator_script_beside_it_is_what_runs · method · L605-L610 — def test_the_generator_script_beside_it_is_what_runs(self) -> None
- test_the_credential_never_appears_on_the_command_line · method · L612-L615 — def test_the_credential_never_appears_on_the_command_line(self) -> None
- test_the_visual_only_mode_is_forwarded · method · L617-L619 — def test_the_visual_only_mode_is_forwarded(self) -> None
- test_each_attachment_is_forwarded_in_order · method · L621-L628 — def test_each_attachment_is_forwarded_in_order(self) -> None
- test_the_iteration_ceiling_is_enforced_by_the_wrapper · method · L630-L638 — def test_the_iteration_ceiling_is_enforced_by_the_wrapper(self) -> None: # Two is the documented maximum; a larger request is clamped, and the # default is left implicit rather than passed through.
- test_without_a_key_nothing_is_spawned · method · L640-L657 — def test_without_a_key_nothing_is_spawned(self) -> None: # The wrapper also resolves a credential from any .env file at or above the # working directory, so the temporary root stands in for a machine that has # none -- otherwise a developer's own .env would satisfy the lookup.
- SlideGeneratorTestCase · class · L660-L675 — class SlideGeneratorTestCase(TemporaryDirectoryTestCase)
- setUp · method · L663-L671 — def setUp(self) -> None
- data_url · method · L674-L675 — def data_url(payload: bytes) -> str
- ApiKeyTests · class · L678-L698 — class ApiKeyTests(TemporaryDirectoryTestCase)
- test_a_generator_without_a_credential_refuses_to_start · method · L679-L690 — def test_a_generator_without_a_credential_refuses_to_start(self) -> None
- test_the_environment_variable_is_accepted_in_place_of_an_argument · method · L692-L698 — def test_the_environment_variable_is_accepted_in_place_of_an_argument(self) -> None
- GuidelineTests · class · L701-L730 — class GuidelineTests(SlideGeneratorTestCase)
- test_the_presentation_threshold_is_lower_than_a_paper_figure · method · L702-L704 — def test_the_presentation_threshold_is_lower_than_a_paper_figure(self) -> None: # Documented as deliberately below the journal/conference bar.
- test_a_full_slide_prompt_asks_for_slide_structure · method · L706-L710 — def test_a_full_slide_prompt_asks_for_slide_structure(self) -> None
- test_a_visual_only_prompt_does_not_ask_for_slide_furniture · method · L712-L717 — def test_a_visual_only_prompt_does_not_ask_for_slide_furniture(self) -> None: # In the PPT workflow the text is added in PowerPoint, so a generated # title baked into the image would be duplicated.
- test_the_improved_prompt_carries_the_critique_and_the_right_guidelines · method · L719-L730 — def test_the_improved_prompt_carries_the_critique_and_the_right_guidelines(self) -> None
- ImageExtractionTests · class · L733-L793 — class ImageExtractionTests(SlideGeneratorTestCase)
- response · method · L736-L737 — def response(self, message: dict) -> dict
- test_an_image_in_the_images_field_is_decoded · method · L739-L746 — def test_an_image_in_the_images_field_is_decoded(self) -> None
- test_wrapped_base64_is_reassembled · method · L748-L758 — def test_wrapped_base64_is_reassembled(self) -> None: # Some responses arrive hard-wrapped; the newlines are not data.
- test_an_image_embedded_in_the_content_string_is_found · method · L760-L766 — def test_an_image_embedded_in_the_content_string_is_found(self) -> None
- test_an_image_in_a_content_block_is_found · method · L768-L777 — def test_an_image_in_a_content_block_is_found(self) -> None
- test_a_response_with_no_image_yields_none · method · L779-L784 — def test_a_response_with_no_image_yields_none(self) -> None
- test_a_refusal_with_no_choices_yields_none · method · L786-L787 — def test_a_refusal_with_no_choices_yields_none(self) -> None
- test_a_truncated_data_url_yields_none_rather_than_raising · method · L789-L793 — def test_a_truncated_data_url_yields_none_rather_than_raising(self) -> None
- AttachmentEncodingTests · class · L796-L826 — class AttachmentEncodingTests(SlideGeneratorTestCase)
- test_the_mime_type_follows_the_file_extension · method · L797-L813 — def test_the_mime_type_follows_the_file_extension(self) -> None
- test_an_unknown_extension_falls_back_to_png · method · L815-L820 — def test_an_unknown_extension_falls_back_to_png(self) -> None
- test_the_encoded_payload_round_trips · method · L822-L826 — def test_the_encoded_payload_round_trips(self) -> None
- ReviewDecisionTests · class · L829-L894 — class ReviewDecisionTests(SlideGeneratorTestCase)
- setUp · method · L830-L833 — def setUp(self) -> None
- review · method · L835-L839 — def review(self, message: dict)
- test_a_score_at_the_threshold_is_accepted · method · L841-L845 — def test_a_score_at_the_threshold_is_accepted(self) -> None: # 6.5 is the threshold itself, so it must not trigger another round.
- test_a_score_below_the_threshold_asks_for_another_round · method · L847-L850 — def test_a_score_below_the_threshold_asks_for_another_round(self) -> None
- test_an_explicit_verdict_overrides_a_high_score · method · L852-L856 — def test_an_explicit_verdict_overrides_a_high_score(self) -> None: # The reviewer's words win: a 9 with NEEDS_IMPROVEMENT is not accepted.
- test_a_loosely_worded_score_is_still_read · method · L858-L860 — def test_a_loosely_worded_score_is_still_read(self) -> None
- test_an_unscored_review_does_not_block_the_pipeline · method · L862-L870 — def test_an_unscored_review_does_not_block_the_pipeline(self) -> None: # No parseable score and no verdict: still no extra round, because a # reviewer that said nothing measurable says nothing about the image. # The score stays None -- a stand-in number here would reach the review # log indistinguishable from one the reviewer actually gave.
- test_a_review_returned_as_content_blocks_is_flattened · method · L872-L878 — def test_a_review_returned_as_content_blocks_is_flattened(self) -> None
- test_a_reasoning_only_reply_is_used_as_the_critique · method · L880-L883 — def test_a_reasoning_only_reply_is_used_as_the_critique(self) -> None
- test_a_failed_review_is_not_treated_as_a_bad_image · method · L885-L894 — def test_a_failed_review_is_not_treated_as_a_bad_image(self) -> None
- RefinementLoopTests · class · L897-L966 — class RefinementLoopTests(SlideGeneratorTestCase)
- reviewed · method · L901-L905 — def reviewed(self, critique, score, needs_improvement)
- generate · method · L907-L915 — def generate(self, images, reviews, **kwargs)
- test_a_good_first_image_stops_early_and_is_written · method · L917-L927 — def test_a_good_first_image_stops_early_and_is_written(self) -> None
- test_a_weak_image_is_regenerated_from_an_improved_prompt · method · L929-L939 — def test_a_weak_image_is_regenerated_from_an_improved_prompt(self) -> None
- test_the_iteration_ceiling_still_keeps_the_last_image · method · L941-L951 — def test_the_iteration_ceiling_still_keeps_the_last_image(self) -> None
- test_a_failed_generation_writes_no_file_and_reports_failure · method · L953-L958 — def test_a_failed_generation_writes_no_file_and_reports_failure(self) -> None
- test_the_mode_and_threshold_are_recorded_in_the_results · method · L960-L966 — def test_the_mode_and_threshold_are_recorded_in_the_results(self) -> None
- AiCliValidationTests · class · L969-L1015 — class AiCliValidationTests(TemporaryDirectoryTestCase)
- invoke · method · L972-L986 — def invoke(self, *arguments, key="sk-or-test")
- test_more_iterations_than_allowed_is_refused · method · L988-L994 — def test_more_iterations_than_allowed_is_refused(self) -> None
- test_zero_iterations_is_refused · method · L996-L1001 — def test_zero_iterations_is_refused(self) -> None
- test_a_missing_attachment_is_named_before_any_request · method · L1003-L1009 — def test_a_missing_attachment_is_named_before_any_request(self) -> None
- test_a_missing_credential_is_reported_without_a_traceback · method · L1011-L1015 — def test_a_missing_credential_is_reported_without_a_traceback(self) -> None