Skip to content

Commit 1b10caf

Browse files
authored
Test branch protection
Test branch protection
2 parents ee5dbd7 + 5fb8c5e commit 1b10caf

5 files changed

Lines changed: 145 additions & 9 deletions

File tree

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2025 MrMaydo
3+
Copyright (c) 2025 Zbigniew Brzezicki
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

src/header_generator.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import re
2+
3+
4+
def set_package(package: str) -> str:
5+
PACKAGE_REGEX = r"^(?:[a-z_][a-z0-9_]*)(?:\.(?:[a-z_][a-z0-9_]*))*$"
6+
if not re.match(PACKAGE_REGEX, package):
7+
raise ValueError(f"Invalid package: '{package}'")
8+
return f"package {package}"

src/method_generator.py

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
indent_lvl1 = " "
2626
indent_lvl2 = indent_lvl1 * 2
2727
indent_lvl3 = indent_lvl1 * 3
28+
return_indent = " "
2829

2930

3031
@dataclass
@@ -75,7 +76,7 @@ def generate_getter(field: Field) -> str:
7576

7677
_validate_java_identifier(field_name)
7778

78-
getter_name = "get" + field_name[0].upper() + field_name[1:]
79+
getter_name = _get_getter_name(field)
7980

8081
getter = [
8182
"",
@@ -94,7 +95,7 @@ def generate_setter(field: Field) -> str:
9495

9596
_validate_java_identifier(field_name)
9697

97-
setter_name = "set" + field_name[0].upper() + field_name[1:]
98+
setter_name = _get_setter_name(field_name)
9899

99100
setter = [
100101
"",
@@ -106,26 +107,76 @@ def generate_setter(field: Field) -> str:
106107
return setter
107108

108109

110+
def generate_equals(class_name: str, fields: List[Field]) -> str:
111+
equals = [
112+
"",
113+
f"{indent_lvl1}@Override",
114+
f"{indent_lvl1}public boolean equals(Object obj) {{",
115+
116+
f"{indent_lvl2}if (this == obj)",
117+
f"{indent_lvl3}return true;",
118+
119+
f"{indent_lvl2}if (!(obj instanceof {class_name}))",
120+
f"{indent_lvl3}return false;",
121+
122+
f"{indent_lvl2}{class_name} that = ({class_name}) obj;"
123+
]
124+
125+
for i, field in enumerate(fields):
126+
_validate_java_identifier(field.name)
127+
getter_name = _get_getter_name(field)
128+
semicolon = ";" if i == (len(fields) - 1) else ""
129+
if i == 0:
130+
equals.append(f"{indent_lvl2}return Objects.equals({getter_name}(), that.{getter_name}()){semicolon}")
131+
else:
132+
equals.append(f"{indent_lvl2}{return_indent}&& Objects.equals({getter_name}(), that.{getter_name}()){semicolon}")
133+
equals.append(f"{indent_lvl1}}}")
134+
135+
return "\n".join(equals)
136+
137+
109138
def generate_hash_code(fields: List[Field]) -> str:
110139
hash_code = [
111140
"",
112141
f"{indent_lvl1}@Override",
113-
f"{indent_lvl1}public int hashCode() {{",
114-
f"{indent_lvl2}return Objects.hash("
142+
f"{indent_lvl1}public int hashCode() {{"
115143
]
116144

117145
for i, field in enumerate(fields):
118146
_validate_java_identifier(field.name)
119-
getter_name = "get" + field.name[0].upper() + field.name[1:]
120-
comma = "," if i < (len(fields) - 1) else ""
121-
hash_code.append(f"{indent_lvl2} {getter_name}(){comma}")
147+
hash_code.extend(_get_return_hash_lines(fields, index=i))
122148

123-
hash_code.append(f"{indent_lvl2});")
124149
hash_code.append(f"{indent_lvl1}}}")
125150

126151
return "\n".join(hash_code)
127152

128153

154+
def _get_return_hash_lines(fields, index) -> List[str]:
155+
field = fields[index]
156+
getter_name = _get_getter_name(field)
157+
comma = "," if index < (len(fields) - 1) else ""
158+
another_hash_line = f"{indent_lvl2}{return_indent}{getter_name}(){comma}"
159+
if len(fields) == 1:
160+
return [f"{indent_lvl2}return Objects.hash({getter_name}());"]
161+
if len(fields) > 1 and index == 0:
162+
return [f"{indent_lvl2}return Objects.hash(",
163+
f"{another_hash_line}"]
164+
if len(fields) > 1 and index == (len(fields) - 1):
165+
return [f"{another_hash_line}",
166+
f"{indent_lvl2});"]
167+
return [another_hash_line]
168+
169+
170+
def _get_getter_name(field):
171+
getter_name = "get" + field.name[0].upper() + field.name[1:]
172+
return getter_name
173+
174+
175+
def _get_setter_name(field_name):
176+
setter_name = "set" + field_name[0].upper() + field_name[1:]
177+
return setter_name
178+
179+
129180
def _validate_java_identifier(name: str) -> None:
130181
if not name:
131182
raise ValueError("Field name cannot be empty")

tests/test_header_generator.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import pytest
2+
3+
from src.header_generator import set_package
4+
5+
6+
def test_set_package():
7+
example = "org.example.hyphenated_name"
8+
expected = f"package {example}"
9+
assert set_package(example) == expected
10+
11+
example_2 = "com.example._123name"
12+
expected_2 = f"package {example_2}"
13+
assert set_package(example_2) == expected_2
14+
15+
16+
def test_set_package_illegal_name():
17+
example = "org.example.hyphenated-name"
18+
with pytest.raises(ValueError):
19+
set_package(example)
20+
21+
example_2 = "com.example.123name"
22+
with pytest.raises(ValueError):
23+
set_package(example_2)

tests/test_method_generator.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,62 @@ def test_generate_hash_code():
155155
assert generate_hash_code(attributes) == expected
156156

157157

158+
def test_generate_hash_code_one_field():
159+
attr = field_exampleAttribute_int
160+
expected = """
161+
@Override
162+
public int hashCode() {
163+
return Objects.hash(getExampleAttribute());
164+
}"""
165+
assert generate_hash_code([attr]) == expected
166+
167+
158168
def test_generate_hash_code_invalid_name():
159169
for name in illegal_names:
160170
attr = Field(name=name, type="String")
161171
with pytest.raises(ValueError):
162172
generate_hash_code([attr])
173+
174+
175+
def test_generate_equals():
176+
class_name = "MyClass"
177+
attr1 = field_exampleAttribute_int
178+
attr2 = field_someName_String
179+
attr3 = field_customData_CustomObject
180+
attributes = [attr1, attr2, attr3]
181+
expected = """
182+
@Override
183+
public boolean equals(Object obj) {
184+
if (this == obj)
185+
return true;
186+
if (!(obj instanceof MyClass))
187+
return false;
188+
MyClass that = (MyClass) obj;
189+
return Objects.equals(getExampleAttribute(), that.getExampleAttribute())
190+
&& Objects.equals(getSomeName(), that.getSomeName())
191+
&& Objects.equals(getCustomData(), that.getCustomData());
192+
}"""
193+
assert generate_equals(class_name, attributes) == expected
194+
195+
196+
def test_generate_equals_one_field():
197+
class_name = "AnotherClass"
198+
attr = field_someName_String
199+
expected = """
200+
@Override
201+
public boolean equals(Object obj) {
202+
if (this == obj)
203+
return true;
204+
if (!(obj instanceof AnotherClass))
205+
return false;
206+
AnotherClass that = (AnotherClass) obj;
207+
return Objects.equals(getSomeName(), that.getSomeName());
208+
}"""
209+
assert generate_equals(class_name, [attr]) == expected
210+
211+
212+
def test_generate_equals_invalid_name():
213+
for name in illegal_names:
214+
attr = Field(name=name, type="String")
215+
with pytest.raises(ValueError):
216+
generate_equals("MyClass", [attr])

0 commit comments

Comments
 (0)