From 0c962a8adca4bb50275b38937253c5987a744f65 Mon Sep 17 00:00:00 2001 From: MrMaydo <89995856+MrMaydo@users.noreply.github.com> Date: Fri, 9 Jan 2026 21:23:54 +0100 Subject: [PATCH 1/9] refactor enum_generator.py --- src/enum_generator.py | 74 +++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 41 deletions(-) diff --git a/src/enum_generator.py b/src/enum_generator.py index 5dc43b2..f9671da 100644 --- a/src/enum_generator.py +++ b/src/enum_generator.py @@ -21,40 +21,27 @@ def generate_enum_class(enum_class: EnumClass, package: str) -> str: "", f"import java.util.HashMap;", f"import java.util.Map;", + f"", + _get_javadoc(enum_class.description), + f"public enum {enum_class.name} {{", + _get_constants(enum_class.values), + f"", + f"{indent_lvl1}private final static Map CONSTANTS = new HashMap();", + _get_static_method(enum_class.name), + f"", + f"{indent_lvl1}private final String value;", + _get_constructor(enum_class.name), + _get_from_value_method(enum_class.name), + _get_to_string_method(), + _get_value_method(), + "}", f"" ] - enum_body.extend(_get_javadoc(enum_class.description)) - - enum_body.append(f"public enum {enum_class.name} {{") - enum_body.extend(_get_constants(enum_class.values)) - - enum_body.append(f"") - enum_body.append( - f"{indent_lvl1}private final static Map CONSTANTS = new HashMap();") - enum_body.append(f"") - enum_body.extend(_get_static_method(enum_class.name)) - - enum_body.append(f"") - enum_body.append(f"{indent_lvl1}private final String value;") - enum_body.append(f"") - enum_body.extend(_get_constructor(enum_class.name)) - - enum_body.append(f"") - enum_body.extend(_get_from_value_method(enum_class.name)) - - enum_body.append(f"") - enum_body.extend(_get_to_string_method()) - - enum_body.append(f"") - enum_body.extend(_get_value_method()) - enum_body.append("}") - enum_body.append(f"") - return "\n".join(enum_body) -def _get_javadoc(description: str) -> List[str]: +def _get_javadoc(description: str) -> str: javadoc = [""] if description is not None: javadoc = [ @@ -63,41 +50,44 @@ def _get_javadoc(description: str) -> List[str]: f" * {description}", " */" ] - return javadoc + return "\n".join(javadoc) -def _get_constants(constants: List[str]) -> List[str]: +def _get_constants(constants: List[str]) -> str: values = [] for i, value in enumerate(constants): line_end = ";" if i == (len(constants) - 1) else "," values.append( f'{indent_lvl1}{to_java_constant(value)}("{value}"){line_end}' ) - return values + return "\n".join(values) -def _get_static_method(class_name: str) -> List[str]: +def _get_static_method(class_name: str) -> str: body = [ + "", f"{indent_lvl1}static {{", f"{indent_lvl2}for ({class_name} c : values()) {{", f"{indent_lvl3}CONSTANTS.put(c.value, c);", f"{indent_lvl2}}}", f"{indent_lvl1}}}" ] - return body + return "\n".join(body) -def _get_constructor(class_name: str) -> List[str]: +def _get_constructor(class_name: str) -> str: body = [ + "", f"{indent_lvl1}{class_name}(String value) {{", f"{indent_lvl2}this.value = value;", f"{indent_lvl1}}}" ] - return body + return "\n".join(body) -def _get_from_value_method(class_name: str) -> List[str]: +def _get_from_value_method(class_name: str) -> str: body = [ + "", f"{indent_lvl1}public static {class_name} fromValue(String value) {{", f"{indent_lvl2}{class_name} constant = CONSTANTS.get(value);", f"{indent_lvl2}if (constant == null) {{", @@ -107,23 +97,25 @@ def _get_from_value_method(class_name: str) -> List[str]: f"{indent_lvl2}}}", f"{indent_lvl1}}}" ] - return body + return "\n".join(body) -def _get_to_string_method() -> List[str]: +def _get_to_string_method() -> str: body = [ + "", f"{indent_lvl1}@Override", f"{indent_lvl1}public String toString() {{", f"{indent_lvl2}return this.value;", f"{indent_lvl1}}}" ] - return body + return "\n".join(body) -def _get_value_method() -> List[str]: +def _get_value_method() -> str: body = [ + "", f"{indent_lvl1}public String value() {{", f"{indent_lvl2}return this.value;", f"{indent_lvl1}}}" ] - return body + return "\n".join(body) From 38e4fed56c707f53a11a16bf934b17d202a7a6a5 Mon Sep 17 00:00:00 2001 From: MrMaydo <89995856+MrMaydo@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:42:54 +0100 Subject: [PATCH 2/9] add set imports to header generation --- src/header_generator.py | 19 +++++++++++++++++++ tests/test_header_generator.py | 32 +++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/header_generator.py b/src/header_generator.py index ba1487f..5b16f4f 100644 --- a/src/header_generator.py +++ b/src/header_generator.py @@ -1,4 +1,7 @@ import re +from typing import List + +from java_model import Field def set_package(package: str) -> str: @@ -6,3 +9,19 @@ def set_package(package: str) -> str: if not re.match(PACKAGE_REGEX, package): raise ValueError(f"Invalid package: '{package}'") return f"package {package};" + + +def set_imports(fields: List[Field]) -> str: + imports = [_imports["Objects"]] + for field in fields: + if field.type in _imports.keys(): + imports.append(_imports[field.type]) + imports.sort() + return "\n".join(imports) + + +_imports = { + "Date": "import java.util.Date;", + "List": "import java.util.List;", + "Objects": "import java.util.Objects;", +} diff --git a/tests/test_header_generator.py b/tests/test_header_generator.py index 4bba937..e4069b5 100644 --- a/tests/test_header_generator.py +++ b/tests/test_header_generator.py @@ -1,6 +1,7 @@ import pytest -from src.header_generator import set_package +from java_model import Field +from src.header_generator import set_package, set_imports def test_set_package(): @@ -25,3 +26,32 @@ def test_set_package_illegal_name(): example_2 = "com.example.123name" with pytest.raises(ValueError): set_package(example_2) + + +def test_set_imports_all(): + field_date = Field(name="birthDate", type="Date") + field_string = Field(name="birthDate", type="String") + field_list = Field(name="setOfSth", type="List") + fields = [field_list, field_string, field_date] + expected = """\ +import java.util.Date; +import java.util.List; +import java.util.Objects;""" + assert set_imports(fields) == expected + + +def test_set_imports_individual_import(): + field_date = Field(name="birthDate", type="Date") + fields = [field_date] + expected = """\ +import java.util.Date; +import java.util.Objects;""" + assert set_imports(fields) == expected + + +def test_set_imports_no_additional_imports(): + field_int = Field(name="age", type="int") + fields = [field_int] + expected = """\ +import java.util.Objects;""" + assert set_imports(fields) == expected From 6b1fc035fef79b852fe7b5dc6feb1367e1ded026 Mon Sep 17 00:00:00 2001 From: MrMaydo <89995856+MrMaydo@users.noreply.github.com> Date: Tue, 10 Feb 2026 17:38:57 +0100 Subject: [PATCH 3/9] add indent function --- src/java_model.py | 18 ++++++++++++++++++ tests/test_java_model.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 tests/test_java_model.py diff --git a/src/java_model.py b/src/java_model.py index 7991cd4..a89ab90 100644 --- a/src/java_model.py +++ b/src/java_model.py @@ -36,3 +36,21 @@ class Field: name: str type: str description: Optional[str] = None + + +@dataclass +class JavaClass: + name: str + fields: List[Field] + description: Optional[str] = None + + +def indent(level: int, size: int = 4) -> str: + if level < 0 or size < 0: + raise ValueError("Indent size cannot be lower than 0") + + return " " * size * level + + + + diff --git a/tests/test_java_model.py b/tests/test_java_model.py new file mode 100644 index 0000000..a64faeb --- /dev/null +++ b/tests/test_java_model.py @@ -0,0 +1,33 @@ +import pytest + +from src.java_model import indent + + +def test_indent_zero(): + assert indent(0) == "" + + +def test_indent_default_size(): + assert indent(1) == " " * 4 + + +def test_indent_multiple_levels(): + assert indent(3) == " " * 12 + + +def test_indent_custom_size(): + assert indent(2, size=2) == " " * 4 + + +def test_indent_size_zero(): + assert indent(5, size=0) == "" + + +def test_indent_negative_lvl(): + with pytest.raises(ValueError): + indent(level=-1, size=4) + + +def test_indent_negative_size(): + with pytest.raises(ValueError): + indent(level=1, size=-1) From aab16bfddf7dc02a99a019572e6ce4377a1df5e9 Mon Sep 17 00:00:00 2001 From: MrMaydo <89995856+MrMaydo@users.noreply.github.com> Date: Tue, 10 Feb 2026 18:06:57 +0100 Subject: [PATCH 4/9] add general render_javadoc function --- src/header_generator.py | 16 ++++++++++++++-- tests/test_header_generator.py | 28 ++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/header_generator.py b/src/header_generator.py index 5b16f4f..a7ef81e 100644 --- a/src/header_generator.py +++ b/src/header_generator.py @@ -1,7 +1,7 @@ import re -from typing import List +from typing import List, Union -from java_model import Field +from src.java_model import Field, indent def set_package(package: str) -> str: @@ -20,6 +20,18 @@ def set_imports(fields: List[Field]) -> str: return "\n".join(imports) +def render_javadoc(description: Union[str, None], indent_lvl: int) -> str: + if description is None or description == "": + return "" + + return "\n".join([ + "", + f"{indent(indent_lvl)}/**", + f"{indent(indent_lvl)} * {description}", + f"{indent(indent_lvl)} */" + ]) + + _imports = { "Date": "import java.util.Date;", "List": "import java.util.List;", diff --git a/tests/test_header_generator.py b/tests/test_header_generator.py index e4069b5..5e376c0 100644 --- a/tests/test_header_generator.py +++ b/tests/test_header_generator.py @@ -1,7 +1,7 @@ import pytest -from java_model import Field -from src.header_generator import set_package, set_imports +from src.java_model import Field +from src.header_generator import set_package, set_imports, render_javadoc def test_set_package(): @@ -55,3 +55,27 @@ def test_set_imports_no_additional_imports(): expected = """\ import java.util.Objects;""" assert set_imports(fields) == expected + + +def test_render_javadoc_class_indent(): + description = "Example class description" + expected = """ +/** + * Example class description + */""" + assert render_javadoc(description, 0) == expected + + +def test_render_javadoc_field_indent(): + description = "Example field description" + expected = """ + /** + * Example field description + */""" + assert render_javadoc(description, 1) == expected + + +def test_render_javadoc_no_description(): + assert render_javadoc("", 0) == "" + assert render_javadoc(None, 0) == "" + assert render_javadoc(None, 1) == "" From 199a6d19f15f585d6076ec7aff8ed688ac94ad72 Mon Sep 17 00:00:00 2001 From: MrMaydo <89995856+MrMaydo@users.noreply.github.com> Date: Tue, 10 Feb 2026 20:44:23 +0100 Subject: [PATCH 5/9] apply new indent() and render_javadoc() functions --- src/enum_generator.py | 70 +++++++++++++++--------------------- src/header_generator.py | 2 +- src/java_method_generator.py | 66 ++++++++++++++-------------------- src/java_model.py | 4 --- 4 files changed, 57 insertions(+), 85 deletions(-) diff --git a/src/enum_generator.py b/src/enum_generator.py index f9671da..5f7b28f 100644 --- a/src/enum_generator.py +++ b/src/enum_generator.py @@ -1,8 +1,8 @@ import re from typing import List -from src.java_model import EnumClass, indent_lvl1, indent_lvl2, indent_lvl3 -from src.header_generator import set_package +from src.java_model import EnumClass, indent +from src.header_generator import set_package, render_javadoc def to_java_constant(value: str) -> str: @@ -22,14 +22,14 @@ def generate_enum_class(enum_class: EnumClass, package: str) -> str: f"import java.util.HashMap;", f"import java.util.Map;", f"", - _get_javadoc(enum_class.description), + render_javadoc(enum_class.description, indent_lvl=0), f"public enum {enum_class.name} {{", _get_constants(enum_class.values), f"", - f"{indent_lvl1}private final static Map CONSTANTS = new HashMap();", + f"{indent(1)}private final static Map CONSTANTS = new HashMap();", _get_static_method(enum_class.name), f"", - f"{indent_lvl1}private final String value;", + f"{indent(1)}private final String value;", _get_constructor(enum_class.name), _get_from_value_method(enum_class.name), _get_to_string_method(), @@ -41,24 +41,12 @@ def generate_enum_class(enum_class: EnumClass, package: str) -> str: return "\n".join(enum_body) -def _get_javadoc(description: str) -> str: - javadoc = [""] - if description is not None: - javadoc = [ - "", - "/**", - f" * {description}", - " */" - ] - return "\n".join(javadoc) - - def _get_constants(constants: List[str]) -> str: values = [] for i, value in enumerate(constants): line_end = ";" if i == (len(constants) - 1) else "," values.append( - f'{indent_lvl1}{to_java_constant(value)}("{value}"){line_end}' + f'{indent(1)}{to_java_constant(value)}("{value}"){line_end}' ) return "\n".join(values) @@ -66,11 +54,11 @@ def _get_constants(constants: List[str]) -> str: def _get_static_method(class_name: str) -> str: body = [ "", - f"{indent_lvl1}static {{", - f"{indent_lvl2}for ({class_name} c : values()) {{", - f"{indent_lvl3}CONSTANTS.put(c.value, c);", - f"{indent_lvl2}}}", - f"{indent_lvl1}}}" + f"{indent(1)}static {{", + f"{indent(2)}for ({class_name} c : values()) {{", + f"{indent(3)}CONSTANTS.put(c.value, c);", + f"{indent(2)}}}", + f"{indent(1)}}}" ] return "\n".join(body) @@ -78,9 +66,9 @@ def _get_static_method(class_name: str) -> str: def _get_constructor(class_name: str) -> str: body = [ "", - f"{indent_lvl1}{class_name}(String value) {{", - f"{indent_lvl2}this.value = value;", - f"{indent_lvl1}}}" + f"{indent(1)}{class_name}(String value) {{", + f"{indent(2)}this.value = value;", + f"{indent(1)}}}" ] return "\n".join(body) @@ -88,14 +76,14 @@ def _get_constructor(class_name: str) -> str: def _get_from_value_method(class_name: str) -> str: body = [ "", - f"{indent_lvl1}public static {class_name} fromValue(String value) {{", - f"{indent_lvl2}{class_name} constant = CONSTANTS.get(value);", - f"{indent_lvl2}if (constant == null) {{", - f"{indent_lvl3}throw new IllegalArgumentException(value);", - f"{indent_lvl2}}} else {{", - f"{indent_lvl3}return constant;", - f"{indent_lvl2}}}", - f"{indent_lvl1}}}" + f"{indent(1)}public static {class_name} fromValue(String value) {{", + f"{indent(2)}{class_name} constant = CONSTANTS.get(value);", + f"{indent(2)}if (constant == null) {{", + f"{indent(3)}throw new IllegalArgumentException(value);", + f"{indent(2)}}} else {{", + f"{indent(3)}return constant;", + f"{indent(2)}}}", + f"{indent(1)}}}" ] return "\n".join(body) @@ -103,10 +91,10 @@ def _get_from_value_method(class_name: str) -> str: def _get_to_string_method() -> str: body = [ "", - f"{indent_lvl1}@Override", - f"{indent_lvl1}public String toString() {{", - f"{indent_lvl2}return this.value;", - f"{indent_lvl1}}}" + f"{indent(1)}@Override", + f"{indent(1)}public String toString() {{", + f"{indent(2)}return this.value;", + f"{indent(1)}}}" ] return "\n".join(body) @@ -114,8 +102,8 @@ def _get_to_string_method() -> str: def _get_value_method() -> str: body = [ "", - f"{indent_lvl1}public String value() {{", - f"{indent_lvl2}return this.value;", - f"{indent_lvl1}}}" + f"{indent(1)}public String value() {{", + f"{indent(2)}return this.value;", + f"{indent(1)}}}" ] return "\n".join(body) diff --git a/src/header_generator.py b/src/header_generator.py index a7ef81e..f19a6f3 100644 --- a/src/header_generator.py +++ b/src/header_generator.py @@ -21,7 +21,7 @@ def set_imports(fields: List[Field]) -> str: def render_javadoc(description: Union[str, None], indent_lvl: int) -> str: - if description is None or description == "": + if not description: return "" return "\n".join([ diff --git a/src/java_method_generator.py b/src/java_method_generator.py index 5350fe3..18e6e2a 100644 --- a/src/java_method_generator.py +++ b/src/java_method_generator.py @@ -1,8 +1,8 @@ import re from typing import List -from src.java_model import JAVA_KEYWORDS, JAVA_BUILTIN_TYPES, JAVA_LITERALS, indent_lvl1, indent_lvl2, indent_lvl3, \ - return_indent, Field +from src.header_generator import render_javadoc +from src.java_model import JAVA_KEYWORDS, JAVA_BUILTIN_TYPES, JAVA_LITERALS, Field, indent def generate_fields_block(fields: List[Field]) -> str: @@ -17,24 +17,12 @@ def generate_field_declaration(field: Field) -> str: _validate_java_field_name(field.name) declaration = [ - _render_javadoc(field), - f"{indent_lvl1}private {field.type} {field.name};" + render_javadoc(field.description, indent_lvl=1), + f"{indent(1)}private {field.type} {field.name};" ] return "\n".join(declaration) -def _render_javadoc(field: Field) -> str: - if field.description is None: - return "" - - return "\n".join([ - "", - f"{indent_lvl1}/**", - f"{indent_lvl1} * {field.description}", - f"{indent_lvl1} */" - ]) - - def generate_getters_and_setters(fields: List[Field]) -> str: methods = [] for field in fields: @@ -49,9 +37,9 @@ def generate_getter(field: Field) -> str: getter = [ "", - f"{indent_lvl1}public {field.type} {getter_name}() {{", - f"{indent_lvl2}return {field.name};", - f"{indent_lvl1}}}" + f"{indent(1)}public {field.type} {getter_name}() {{", + f"{indent(2)}return {field.name};", + f"{indent(1)}}}" ] return "\n".join(getter) @@ -61,9 +49,9 @@ def generate_setter(field: Field) -> str: setter = [ "", - f"{indent_lvl1}public void {setter_name}({field.type} {field.name}) {{", - f"{indent_lvl2}this.{field.name} = {field.name};", - f"{indent_lvl1}}}" + f"{indent(1)}public void {setter_name}({field.type} {field.name}) {{", + f"{indent(2)}this.{field.name} = {field.name};", + f"{indent(1)}}}" ] return "\n".join(setter) @@ -71,19 +59,19 @@ def generate_setter(field: Field) -> str: def generate_equals(class_name: str, fields: List[Field]) -> str: equals = [ "", - f"{indent_lvl1}@Override", - f"{indent_lvl1}public boolean equals(Object obj) {{", + f"{indent(1)}@Override", + f"{indent(1)}public boolean equals(Object obj) {{", - f"{indent_lvl2}if (this == obj)", - f"{indent_lvl3}return true;", + f"{indent(2)}if (this == obj)", + f"{indent(3)}return true;", - f"{indent_lvl2}if (!(obj instanceof {class_name}))", - f"{indent_lvl3}return false;", + f"{indent(2)}if (!(obj instanceof {class_name}))", + f"{indent(3)}return false;", - f"{indent_lvl2}{class_name} that = ({class_name}) obj;", + f"{indent(2)}{class_name} that = ({class_name}) obj;", _render_equals_return_statement(fields), - f"{indent_lvl1}}}" + f"{indent(1)}}}" ] return "\n".join(equals) @@ -95,20 +83,20 @@ def _render_equals_return_statement(fields: List[Field]) -> str: getter_name = _build_getter_name(field.name) end_line = ";" if i == (len(fields) - 1) else "" if i == 0: - return_statement.append(f"{indent_lvl2}return Objects.equals({getter_name}(), that.{getter_name}()){end_line}") + return_statement.append(f"{indent(2)}return Objects.equals({getter_name}(), that.{getter_name}()){end_line}") else: return_statement.append( - f"{indent_lvl2}{return_indent}&& Objects.equals({getter_name}(), that.{getter_name}()){end_line}") + f"{indent(4)}&& Objects.equals({getter_name}(), that.{getter_name}()){end_line}") return "\n".join(return_statement) def generate_hash_code(fields: List[Field]) -> str: hash_code = [ "", - f"{indent_lvl1}@Override", - f"{indent_lvl1}public int hashCode() {{", + f"{indent(1)}@Override", + f"{indent(1)}public int hashCode() {{", _render_hashcode_return_statement(fields), - f"{indent_lvl1}}}" + f"{indent(1)}}}" ] return "\n".join(hash_code) @@ -124,17 +112,17 @@ def _render_hashcode_return_statement(fields: List[Field]) -> str: def _render_hashcode_return_statement_single_field(fields: List[Field]) -> str: field_name = fields[0].name getter_name = _build_getter_name(field_name) - return f"{indent_lvl2}return Objects.hash({getter_name}());" + return f"{indent(2)}return Objects.hash({getter_name}());" def _render_hashcode_return_statement_multiple_field(fields: List[Field]) -> str: - return_statement = [f"{indent_lvl2}return Objects.hash("] + return_statement = [f"{indent(2)}return Objects.hash("] for index, field in enumerate(fields): getter_name = _build_getter_name(field.name) comma = "," if index < (len(fields) - 1) else "" - return_statement.append(f"{indent_lvl2}{return_indent}{getter_name}(){comma}") + return_statement.append(f"{indent(4)}{getter_name}(){comma}") - return_statement.append(f"{indent_lvl2});") + return_statement.append(f"{indent(2)});") return "\n".join(return_statement) diff --git a/src/java_model.py b/src/java_model.py index a89ab90..ff4243c 100644 --- a/src/java_model.py +++ b/src/java_model.py @@ -18,10 +18,6 @@ JAVA_LITERALS = { "null", "true", "false" } -indent_lvl1 = " " * 4 -indent_lvl2 = indent_lvl1 * 2 -indent_lvl3 = indent_lvl1 * 3 -return_indent = " " @dataclass From 22378781fe6f8c0ff24ac260ee876cb271b75abc Mon Sep 17 00:00:00 2001 From: MrMaydo <89995856+MrMaydo@users.noreply.github.com> Date: Tue, 10 Feb 2026 20:45:38 +0100 Subject: [PATCH 6/9] rename reference_data.py --- tests/{reference_data.py => reference_data_methods.py} | 0 tests/test_java_method_generator.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{reference_data.py => reference_data_methods.py} (100%) diff --git a/tests/reference_data.py b/tests/reference_data_methods.py similarity index 100% rename from tests/reference_data.py rename to tests/reference_data_methods.py diff --git a/tests/test_java_method_generator.py b/tests/test_java_method_generator.py index d511bde..8d68ae1 100644 --- a/tests/test_java_method_generator.py +++ b/tests/test_java_method_generator.py @@ -1,6 +1,6 @@ import pytest -from tests.reference_data import * +from tests.reference_data_methods import * from src.java_method_generator import * JAVA_KEYWORDS = { From d2f03e13c1a77816573d428443532e5a91687373 Mon Sep 17 00:00:00 2001 From: MrMaydo <89995856+MrMaydo@users.noreply.github.com> Date: Tue, 10 Feb 2026 20:46:04 +0100 Subject: [PATCH 7/9] rename reference_data_enum_class.py --- tests/{enum_reference_data.py => reference_data_enum_class.py} | 0 tests/test_enum_generator.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{enum_reference_data.py => reference_data_enum_class.py} (100%) diff --git a/tests/enum_reference_data.py b/tests/reference_data_enum_class.py similarity index 100% rename from tests/enum_reference_data.py rename to tests/reference_data_enum_class.py diff --git a/tests/test_enum_generator.py b/tests/test_enum_generator.py index a6e6de4..7240ac9 100644 --- a/tests/test_enum_generator.py +++ b/tests/test_enum_generator.py @@ -1,5 +1,5 @@ from src.enum_generator import to_java_constant, generate_enum_class -from tests.enum_reference_data import * +from tests.reference_data_enum_class import * def test_to_java_constant(): From 5f29313551fd21cdab88e407dcda8b76d193386a Mon Sep 17 00:00:00 2001 From: MrMaydo <89995856+MrMaydo@users.noreply.github.com> Date: Tue, 10 Feb 2026 22:23:45 +0100 Subject: [PATCH 8/9] add new unit test --- tests/reference_data_methods.py | 14 ++++++++++++++ tests/test_java_method_generator.py | 24 ++++++++++++++---------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/tests/reference_data_methods.py b/tests/reference_data_methods.py index c68668a..3ada138 100644 --- a/tests/reference_data_methods.py +++ b/tests/reference_data_methods.py @@ -3,6 +3,7 @@ field_exampleAttribute_int = Field(name="exampleAttribute", type="int", description="javadoc description") field_someName_String = Field(name="someName", type="String") field_customData_CustomObject = Field(name="customData", type="CustomObject", description="another javadoc description") +field_listOfThings_List_String = Field(name="listOfThings", type="List") expected_getExampleAttribute_int = """ public int getExampleAttribute() { @@ -33,3 +34,16 @@ public void setCustomData(CustomObject customData) { this.customData = customData; }""" + + +expected_getListOfThings_list_string = """ + public List getListOfThings() { + return listOfThings; + }""" + +expected_setListOfThings_list_string = """ + public void setListOfThings(List listOfThings) { + this.listOfThings = listOfThings; + }""" + + diff --git a/tests/test_java_method_generator.py b/tests/test_java_method_generator.py index 8d68ae1..b24bb41 100644 --- a/tests/test_java_method_generator.py +++ b/tests/test_java_method_generator.py @@ -32,20 +32,22 @@ def test_generate_getter_integer(): attr = field_exampleAttribute_int - - assert (generate_getter(attr) == expected_getExampleAttribute_int) + assert generate_getter(attr) == expected_getExampleAttribute_int def test_generate_getter_string(): attr = field_someName_String - - assert (generate_getter(attr) == expected_getSomeName_String) + assert generate_getter(attr) == expected_getSomeName_String def test_generate_getter_custom_object(): attr = field_customData_CustomObject + assert generate_getter(attr) == expected_getCustomData_CustomObject + - assert (generate_getter(attr) == expected_getCustomData_CustomObject) +def test_generate_getter_list(): + attr = field_listOfThings_List_String + assert generate_getter(attr) == expected_getListOfThings_list_string def test_generate_getter_invalid_name(): @@ -57,20 +59,22 @@ def test_generate_getter_invalid_name(): def test_generate_setter_integer(): attr = field_exampleAttribute_int - - assert (generate_setter(attr) == expected_setExampleAttribute_int) + assert generate_setter(attr) == expected_setExampleAttribute_int def test_generate_setter_string(): attr = field_someName_String - - assert (generate_setter(attr) == expected_setSomeName_String) + assert generate_setter(attr) == expected_setSomeName_String def test_generate_setter_custom_object(): attr = field_customData_CustomObject + assert generate_setter(attr) == expected_setCustomData_CustomObject + - assert (generate_setter(attr) == expected_setCustomData_CustomObject) +def test_generate_setter_list(): + attr = field_listOfThings_List_String + assert generate_setter(attr) == expected_setListOfThings_list_string def test_generate_setter_invalid_name(): From 14bbe096230b65ed757dc9baa3760f3204103d8f Mon Sep 17 00:00:00 2001 From: MrMaydo <89995856+MrMaydo@users.noreply.github.com> Date: Tue, 10 Feb 2026 23:20:08 +0100 Subject: [PATCH 9/9] add class generator --- src/class_generator.py | 41 +++++++++++ src/enum_generator.py | 2 +- src/java_method_generator.py | 3 +- src/java_model.py | 4 - tests/reference_data_java_class.py | 114 +++++++++++++++++++++++++++++ tests/test_class_generator.py | 10 +++ 6 files changed, 168 insertions(+), 6 deletions(-) create mode 100644 src/class_generator.py create mode 100644 tests/reference_data_java_class.py create mode 100644 tests/test_class_generator.py diff --git a/src/class_generator.py b/src/class_generator.py new file mode 100644 index 0000000..56977b3 --- /dev/null +++ b/src/class_generator.py @@ -0,0 +1,41 @@ +from src.header_generator import set_package, set_imports, render_javadoc +from src.java_method_generator import generate_fields_block, generate_getters_and_setters, generate_equals, \ + generate_hash_code +from src.java_model import JavaClass + + +def generate_java_class(java_class: JavaClass, package: str) -> str: + if len(java_class.fields) == 0: + return _empty_java_class(java_class, package) + + body = [ + set_package(package), + "", + "", + set_imports(java_class.fields), + "", + render_javadoc(java_class.description, indent_lvl=0), + f"public class {java_class.name} {{", + generate_fields_block(java_class.fields), + "", + generate_getters_and_setters(java_class.fields), + "", + generate_equals(java_class.name, java_class.fields), + "", + generate_hash_code(java_class.fields), + "}", + "" + ] + return "\n".join(body) + + +def _empty_java_class(java_class: JavaClass, package: str) -> str: + body = [ + set_package(package), + "", + render_javadoc(java_class.description, indent_lvl=0), + f"public class {java_class.name} {{", + "}", + "" + ] + return "\n".join(body) diff --git a/src/enum_generator.py b/src/enum_generator.py index 5f7b28f..0b821f9 100644 --- a/src/enum_generator.py +++ b/src/enum_generator.py @@ -1,8 +1,8 @@ import re from typing import List -from src.java_model import EnumClass, indent from src.header_generator import set_package, render_javadoc +from src.java_model import EnumClass, indent def to_java_constant(value: str) -> str: diff --git a/src/java_method_generator.py b/src/java_method_generator.py index 18e6e2a..9da2db1 100644 --- a/src/java_method_generator.py +++ b/src/java_method_generator.py @@ -83,7 +83,8 @@ def _render_equals_return_statement(fields: List[Field]) -> str: getter_name = _build_getter_name(field.name) end_line = ";" if i == (len(fields) - 1) else "" if i == 0: - return_statement.append(f"{indent(2)}return Objects.equals({getter_name}(), that.{getter_name}()){end_line}") + return_statement.append( + f"{indent(2)}return Objects.equals({getter_name}(), that.{getter_name}()){end_line}") else: return_statement.append( f"{indent(4)}&& Objects.equals({getter_name}(), that.{getter_name}()){end_line}") diff --git a/src/java_model.py b/src/java_model.py index ff4243c..5c2ab3e 100644 --- a/src/java_model.py +++ b/src/java_model.py @@ -46,7 +46,3 @@ def indent(level: int, size: int = 4) -> str: raise ValueError("Indent size cannot be lower than 0") return " " * size * level - - - - diff --git a/tests/reference_data_java_class.py b/tests/reference_data_java_class.py new file mode 100644 index 0000000..fcc8eef --- /dev/null +++ b/tests/reference_data_java_class.py @@ -0,0 +1,114 @@ +from src.java_model import Field, JavaClass + +package_example = "expected.DataTypes" +field_name_string = Field(name="name", type="String", description="This contains name.") +field_age_int = Field(name="age", type="int", description="This contains age.") +field_birthdate_date = Field(name="birthDate", type="Date") +field_additionalInfo_CustomObject = Field(name="additionalInfo", type="CustomData") + +person_class_fields = [field_name_string, field_age_int, field_birthdate_date, field_additionalInfo_CustomObject] + +class_person = JavaClass(name="Person", fields=person_class_fields, description="Contains information about a person.") +class_heartbeat = JavaClass(name="Heartbeat", fields=[]) + +expected_java_class_person = """\ +package expected.DataTypes; + + +import java.util.Date; +import java.util.Objects; + + +/** + * Contains information about a person. + */ +public class Person { + + /** + * This contains name. + */ + private String name; + + /** + * This contains age. + */ + private int age; + + private Date birthDate; + + private CustomData additionalInfo; + + + public String getName() { + return name; + } + + + public void setName(String name) { + this.name = name; + } + + + public int getAge() { + return age; + } + + + public void setAge(int age) { + this.age = age; + } + + + public Date getBirthDate() { + return birthDate; + } + + + public void setBirthDate(Date birthDate) { + this.birthDate = birthDate; + } + + + public CustomData getAdditionalInfo() { + return additionalInfo; + } + + + public void setAdditionalInfo(CustomData additionalInfo) { + this.additionalInfo = additionalInfo; + } + + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!(obj instanceof Person)) + return false; + Person that = (Person) obj; + return Objects.equals(getName(), that.getName()) + && Objects.equals(getAge(), that.getAge()) + && Objects.equals(getBirthDate(), that.getBirthDate()) + && Objects.equals(getAdditionalInfo(), that.getAdditionalInfo()); + } + + + @Override + public int hashCode() { + return Objects.hash( + getName(), + getAge(), + getBirthDate(), + getAdditionalInfo() + ); + } +} +""" + +expected_java_class_heartbeat = """\ +package expected.DataTypes; + + +public class Heartbeat { +} +""" diff --git a/tests/test_class_generator.py b/tests/test_class_generator.py new file mode 100644 index 0000000..56a5f20 --- /dev/null +++ b/tests/test_class_generator.py @@ -0,0 +1,10 @@ +from src.class_generator import generate_java_class +from tests.reference_data_java_class import * + + +def test_generate_java_class(): + assert generate_java_class(class_person, package_example) == expected_java_class_person + + +def test_generate_java_class_no_fields(): + assert generate_java_class(class_heartbeat, package_example) == expected_java_class_heartbeat