import pytest from myfasthtml.core.utils import flatten, make_html_id, pascal_to_snake, snake_to_pascal @pytest.mark.parametrize("input_args,expected,test_description", [ # Simple list without nesting (([1, 2, 3],), [1, 2, 3], "simple list"), # Nested list (one level) (([1, [2, 3], 4],), [1, 2, 3, 4], "nested list one level"), # Nested tuple (((1, (2, 3), 4),), [1, 2, 3, 4], "nested tuple"), # Mixed list and tuple (([1, (2, 3), [4, 5]],), [1, 2, 3, 4, 5], "mixed list and tuple"), # Deeply nested structure (([1, [2, [3, [4, 5]]]],), [1, 2, 3, 4, 5], "deeply nested structure"), # Empty list (([],), [], "empty list"), # Empty nested lists (([1, [], [2, []], 3],), [1, 2, 3], "empty nested lists"), # Preserves order (([[3, 1], [4, 2]],), [3, 1, 4, 2], "preserves order"), # Strings (should not be iterated) ((["hello", ["world"]],), ["hello", "world"], "strings not iterated"), # Mixed types (([1, "text", [2.5, True], None],), [1, "text", 2.5, True, None], "mixed types"), # Multiple arguments with lists (([1, 2], [3, 4], 5), [1, 2, 3, 4, 5], "multiple arguments with lists"), # Scalar values only ((1, 2, 3), [1, 2, 3], "scalar values only"), # Mixed scalars and lists ((1, [2, 3], 4, [5, 6]), [1, 2, 3, 4, 5, 6], "mixed scalars and lists"), # Multiple nested arguments (([1, [2]], [3, [4]], 5), [1, 2, 3, 4, 5], "multiple nested arguments"), # No arguments ((), [], "no arguments"), # Complex real-world example (([1, [2, 3], [[4, 5], [6, 7]], [[[8, 9]]], 10],), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "complex nesting"), ]) def test_i_can_flatten(input_args, expected, test_description): """Test that flatten correctly handles various nested structures and arguments.""" result = flatten(*input_args) assert result == expected, f"Failed for test case: {test_description}" @pytest.mark.parametrize("string, expected", [ ("My Example String!", "My-Example-String_"), ("123 Bad ID", "id_123-Bad-ID"), (None, None) ]) def test_i_can_have_valid_html_id(string, expected): assert make_html_id(string) == expected @pytest.mark.parametrize("input_str, expected, test_description", [ ("MyClass", "my_class", "simple PascalCase"), ("myVariable", "my_variable", "camelCase"), ("HTTPServer", "http_server", "short uppercase sequence"), ("XMLHttpRequest", "xml_http_request", "long uppercase sequence"), ("A", "a", "single letter"), ("already_snake", "already_snake", "already snake_case"), ("MyClass123", "my_class123", "with numbers"), ("MyLongClassName", "my_long_class_name", "long class name"), (" MyClass ", "my_class", "with spaces to trim"), ("iPhone", "i_phone", "starts lowercase then uppercase"), (None, None, "None input"), ("", "", "empty string"), (" ", "", "only spaces"), ]) def test_i_can_convert_pascal_to_snake(input_str, expected, test_description): """Test that pascal_to_snake correctly converts PascalCase/camelCase to snake_case.""" result = pascal_to_snake(input_str) assert result == expected, f"Failed for test case: {test_description}" @pytest.mark.parametrize("input_str, expected, test_description", [ ("my_class", "MyClass", "simple snake_case"), ("my_long_class_name", "MyLongClassName", "long class name"), ("a", "A", "single letter"), ("myclass", "Myclass", "no underscore"), (" my_class ", "MyClass", "with spaces to trim"), ("my__class", "MyClass", "multiple consecutive underscores"), ("_my_class", "MyClass", "starts with underscore"), ("my_class_", "MyClass", "ends with underscore"), ("_my_class_", "MyClass", "starts and ends with underscore"), ("my_class_123", "MyClass123", "with numbers"), (None, None, "None input"), ("", "", "empty string"), (" ", "", "only spaces"), ("___", "", "only underscores"), ]) def test_i_can_convert_snake_to_pascal(input_str, expected, test_description): """Test that snake_to_pascal correctly converts snake_case to PascalCase.""" result = snake_to_pascal(input_str) assert result == expected, f"Failed for test case: {test_description}"