lmmx / incubator

Staging ground issue tracker for software ideas
0 stars 0 forks source link

🔍 Decide location of new path length validation tests in Pydantic `test_types.py` test module #2

Closed lmmx closed 2 months ago

lmmx commented 2 months ago

Context: https://github.com/pydantic/pydantic/pull/10207#issuecomment-2356957150

The test_types.py module has 288 test funcdefs.

I probably want to put mine in the right part, so I'll need to try to gauge what the general sections are.

Here's a dump of all their names:

Click to show all the test funcdef names ``` def test_constrained_bytes_good(ConBytesModel): def test_constrained_bytes_default(ConBytesModel): def test_strict_raw_type(): def test_constrained_bytes_too_long(ConBytesModel, data: bytes, valid: bool): def test_constrained_bytes_strict_true(): def test_constrained_bytes_strict_false(): def test_constrained_bytes_strict_default(): def test_constrained_list_good(): def test_constrained_list_default(): def test_constrained_list_too_long(): def test_constrained_list_too_short(): def test_constrained_list_optional(): def test_constrained_list_constraints(): def test_constrained_list_item_type_fails(): def test_conlist(): def test_conlist_wrong_type_default(): def test_constrained_set_good(): def test_constrained_set_default(): def test_constrained_set_default_invalid(): def test_constrained_set_too_long(): def test_constrained_set_too_short(): def test_constrained_set_optional(): def test_constrained_set_constraints(): def test_constrained_set_item_type_fails(): def test_conset(): def test_conset_not_required(): def test_confrozenset(): def test_confrozenset_not_required(): def test_constrained_frozenset_optional(): def test_constrained_str_good(ConStringModel): def test_constrained_str_default(ConStringModel): def test_constrained_str_too_long(ConStringModel, data, valid): def test_constrained_str_upper(to_upper, value, result): def test_constrained_str_lower(to_lower, value, result): def test_constrained_str_max_length_0(): def test_string_import_callable(annotation): def test_string_import_any(value: Any, expected: Any, mode: Literal['json', 'python']): def test_string_import_default_value(value: Any, validate_default: bool, expected: Any): def test_string_import_any_expected_failure(value: Any): def test_string_import_constraints(annotation): def test_string_import_examples(): def test_string_import_errors(import_string, errors): def test_import_string_sys_stdout() -> None: def test_decimal(): def test_decimal_allow_inf(): def test_decimal_dont_allow_inf(): def test_decimal_strict(): def test_decimal_precision() -> None: def test_strict_date(): def test_strict_datetime(): def test_strict_time(): def test_strict_timedelta(): def test_default_validators(field, value, result, CheckModel): def test_string_too_long(StrModel): def test_string_too_short(StrModel): def test_datetime_successful(DatetimeModel): def test_datetime_errors(DatetimeModel): def test_enum_successful(cooking_model): def test_enum_fails(cooking_model): def test_enum_fails_error_msg(): def test_int_enum_successful_for_str_int(cooking_model): def test_plain_enum_validate(): def test_plain_enum_validate_json(): def test_enum_type(): def test_enum_missing_default(): def test_enum_missing_custom(): def test_int_enum_type(): def test_enum_from_json(enum_base, strict): def test_strict_enum() -> None: def test_enum_with_no_cases() -> None: def test_invalid_schema_constraints(kwargs, type_, a): def test_invalid_decimal_constraint(): def test_string_success(): def test_string_fails(): def test_email_validator_not_installed_email_str(): def test_email_validator_not_installed_name_email(): def test_dict(): def test_list_success(value, result): def test_list_fails(value): def test_ordered_dict(): def test_tuple_success(value, result): def test_tuple_fails(value): def test_tuple_variable_len_success(value, cls, result): def test_tuple_variable_len_fails(value, cls, exc): def test_set_success(value, result): def test_set_fails(value): def test_list_type_fails(): def test_set_type_fails(): def test_sequence_success(cls, value, result): def test_infinite_iterable_int(): def test_iterable_any(type_annotation): def test_invalid_iterable(): def test_iterable_error_hide_input(config, input_str): def test_infinite_iterable_validate_first(): def test_sequence_generator_fails(): def test_sequence_fails(cls, value, errors): def test_sequence_strict(): def test_list_strict() -> None: def test_set_strict() -> None: def test_frozenset_strict() -> None: def test_tuple_strict() -> None: def test_int_validation(): def test_float_validation(): def test_infinite_float_validation(): def test_infinite_float_json_serialization(ser_json_inf_nan, input, output, python_roundtrip): def test_finite_float_validation_error(value): def test_finite_float_config(): def test_strict_bytes(): def test_strict_bytes_max_length(): def test_strict_str(): def test_strict_str_max_length(): def test_strict_bool(): def test_strict_int(): def test_big_int_json(input, expected_json): def test_strict_float(): def test_bool_unhashable_fails(): def test_uuid_error(): def test_uuid_json(): def test_uuid_validation(): def test_uuid_strict() -> None: def test_str_strip_whitespace(enabled, str_check, result_str_check): def test_str_to_upper(enabled, str_check, result_str_check): def test_str_to_lower(enabled, str_check, result_str_check): def test_decimal_validation(mode, type_args, value, result): def test_decimal_not_finite(value, result, AllowInfModel): def test_decimal_invalid(): def test_path_validation_success(value, result): def test_path_validation_constrained(): def test_path_like(): def test_path_like_extra_subtype(): def test_path_like_strict(): def test_path_strict_override(): def test_path_validation_fails(): def test_path_validation_strict(): def test_file_path_validation_success(value, result): def test_file_path_validation_fails(value): def test_directory_path_validation_success(value, result): def test_directory_path_validation_fails(value): def test_new_path_validation_path_already_exists(value): def test_new_path_validation_parent_does_not_exist(value): def test_new_path_validation_success(value, result): def test_number_gt(): def test_number_ge(): def test_number_lt(): def test_number_le(): def test_number_multiple_of_int_valid(value): def test_number_multiple_of_int_invalid(value): def test_number_multiple_of_float_valid(value): def test_number_multiple_of_float_invalid(value): def test_new_type_success(): def test_new_type_fails(): def test_valid_simple_json(): def test_valid_simple_json_any(): def test_invalid_simple_json(gen_type): def test_valid_simple_json_bytes(): def test_valid_detailed_json(): def test_valid_model_json(): def test_invalid_model_json(): def test_invalid_detailed_json_type_error(): def test_json_not_str(): def test_json_before_validator(): def test_json_optional_simple(): def test_json_optional_complex(): def test_json_required(): def test_pattern(pattern_type, pattern_value, matching_value, non_matching_value): def test_compiled_pattern_in_field(use_field): def test_pattern_with_invalid_param(): def test_pattern_error(pattern_type, pattern_value, error_type, error_msg): def test_secretstr(validate_json): def test_secretstr_subclass(): def test_secretstr_equality(): def test_secretstr_idempotent(): def test_secretdate(value, result): def test_secretdate_json_serializable(): def test_secretenum_json_serializable(): def test_strict_secretfield_by_config(SecretField, value, error_msg): def test_strict_secretfield_annotated(field, value, error_msg): def test_secretdate_parsing(value): def test_secretdate_equality(): def test_secretdate_idempotent(): def test_secret_union_serializable() -> None: def test_is_hashable(pydantic_type): def test_model_contain_hashable_type(): def test_secretstr_error(): def test_secret_str_hashable(): def test_secret_bytes_hashable(): def test_secret_str_min_max_length(): def test_secretbytes_json(): def test_secretbytes(): def test_secretbytes_equality(): def test_secretbytes_idempotent(): def test_secretbytes_error(): def test_secret_bytes_min_max_length(): def test_generic_without_params(): def test_generic_without_params_error(): def test_literal_single(): def test_literal_multiple(): def test_typing_mutable_set(): def test_frozenset_field(): def test_frozenset_field_conversion(value, result): def test_frozenset_field_not_convertible(): def test_bytesize_conversions(input_value, output, human_bin, human_dec, human_sep): def test_bytesize_to(): def test_bytesize_raises(): def test_deque_success(): def test_deque_generic_success(cls, value, result): def test_deque_generic_success_strict(cls, value: Any, result): def test_deque_fails(cls, value, expected_error): def test_deque_model(): def test_deque_json(): def test_deque_any_maxlen(): def test_deque_typed_maxlen(): def test_deque_set_maxlen(): def test_none(value_type): def test_none_literal(): def test_default_union_types(): def test_default_union_types_left_to_right(): def test_union_enum_int_left_to_right(): def test_union_uuid_str_left_to_right(): def test_default_union_class(): def test_union_subclass(max_length: Union[int, None]): def test_union_compound_types(): def test_smart_union_compounded_types_edge_case(): def test_union_typeddict(): def test_custom_generic_containers(): def test_base64(field_type, input_data, expected_value, serialized_data): def test_base64_invalid(field_type, input_data): def test_base64url(field_type, input_data, expected_value, serialized_data): def test_base64url_invalid(field_type, input_data): def test_sequence_subclass_without_core_schema() -> None: def test_typing_coercion_defaultdict(): def test_typing_coercion_counter(): def test_typing_counter_value_validation(): def test_mapping_subclass_without_core_schema() -> None: def test_defaultdict_unknown_default_factory() -> None: def test_defaultdict_infer_default_factory() -> None: def test_defaultdict_explicit_default_factory() -> None: def test_defaultdict_default_factory_preserved() -> None: def test_custom_default_dict() -> None: def test_ordered_dict_from_ordered_dict(field_type): def test_ordered_dict_from_ordered_dict_typed(): def test_ordered_dict_from_dict(field_type): def test_handle_3rd_party_custom_type_reusing_known_metadata() -> None: def test_skip_validation(optional): def test_skip_validation_model_reference(): def test_skip_validation_serialization(): def test_skip_validation_json_schema(): def test_transform_schema(): def test_transform_schema_for_first_party_class(): def test_constraint_dataclass() -> None: def test_transform_schema_for_third_party_class(): def test_iterable_arbitrary_type(): def test_typing_extension_literal_field(): def test_typing_literal_field(): def test_instance_of_annotation(): def test_instanceof_invalid_core_schema(): def test_instanceof_serialization(): def test_constraints_arbitrary_type() -> None: def test_annotated_default_value() -> None: def test_annotated_default_value_validate_default() -> None: def test_annotated_default_value_functional_validator() -> None: def test_types_repr(pydantic_type, expected): def test_enum_custom_schema() -> None: def test_get_pydantic_core_schema_marker_unrelated_type() -> None: def test_string_constraints() -> None: def test_string_constraints_strict() -> None: def test_decimal_float_precision() -> None: def test_coerce_numbers_to_str_disabled_in_strict_mode() -> None: def test_coerce_numbers_to_str_raises_for_bool(value_param: bool) -> None: def test_coerce_numbers_to_str(number: Number, expected_str: str) -> None: def test_coerce_numbers_to_str_from_json(number: str, expected_str: str) -> None: def test_union_tags_in_errors(): def test_json_value(): def test_json_value_with_subclassed_types(): def test_json_value_roundtrip() -> None: def test_on_error_omit() -> None: def test_on_error_omit_top_level() -> None: def test_diff_enums_diff_configs() -> None: def test_can_serialize_deque_passed_to_sequence() -> None: def test_strict_enum_with_use_enum_values() -> None: def test_complex_field(): def test_strict_complex_field(): def test_python_re_respects_flags() -> None: def test_constraints_on_str_like() -> None: def test_fail_fast(tp, fail_fast, decl) -> None: def test_mutable_mapping() -> None: def test_ser_ip_with_union() -> None: def test_ser_ip_with_unexpected_value() -> None: ```
lmmx commented 2 months ago

ChatGPT notes the following tests:

Since you are adding file length validation tests for FilePath and NewPath, it makes sense to group them with other tests related to file path and new path validations. In the list you provided, these existing tests might be a good reference point for where to add your new tests:

  • test_file_path_validation_success(value, result)
  • test_file_path_validation_fails(value)
  • test_new_path_validation_path_already_exists(value)
  • test_new_path_validation_parent_does_not_exist(value)
  • test_new_path_validation_success(value, result)

You could either extend these tests with additional checks for file length or create new tests right after them to maintain the grouping by the relevant model features. This will help keep related tests together and maintain readability within the test suite.

lmmx commented 2 months ago

The 5 tests mentioned by ChatGPT come in the middle:

... def test_file_path_validation_success(value, result): def test_file_path_validation_fails(value): def test_directory_path_validation_success(value, result): def test_directory_path_validation_fails(value): def test_new_path_validation_path_already_exists(value): def test_new_path_validation_parent_does_not_exist(value): def test_new_path_validation_success(value, result): ...

These seem like a pretty coherent group though, my tests should probably not interrupt them, so I'll put mine directly after

So the insertion point is between these 2 which seem unrelated:

def test_new_path_validation_success(value, result):
def test_number_gt():