Skip to content

Commit e8ba9df

Browse files
authored
Merge pull request #1 from MrMaydo/dev
Dev
2 parents 497711e + 5eb8f2e commit e8ba9df

5 files changed

Lines changed: 241 additions & 61 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ coverage.xml
5050
.hypothesis/
5151
.pytest_cache/
5252
cover/
53+
reports/
5354

5455
# Translations
5556
*.mo
@@ -150,3 +151,4 @@ cython_debug/
150151
# and can be added to the global gitignore or merged into this file. For a more nuclear
151152
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
152153
.idea/
154+
poetry.lock

pyproject.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[tool.poetry]
2+
name = "jsonschema-2-javaclass"
3+
version = "0.1.0"
4+
description = "Java Class generator"
5+
authors = ["Your Name <you@example.com>"]
6+
license = "MIT"
7+
readme = "README.md"
8+
9+
[tool.poetry.dependencies]
10+
python = "^3.8"
11+
pytest = "^8.3.5"
12+
13+
[tool.poetry.group.dev.dependencies]
14+
ruff = "^0.14.10"
15+
pytest-html = "^4.1.1"
16+
17+
[build-system]
18+
requires = ["poetry-core"]
19+
build-backend = "poetry.core.masonry.api"
20+
21+
[tool.pytest.ini_options]
22+
addopts = """-v --cov=src --cov-report=term-missing --cov-report=html:reports/coverage --html=reports/report.html --self-contained-html"""
23+
testpaths = ["tests"]
24+

src/method_generator.py

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import re
22
from dataclasses import dataclass
3-
3+
from typing import List, Optional
44

55
JAVA_KEYWORDS = {
66
"abstract", "assert", "boolean", "break", "byte", "case", "catch",
@@ -31,45 +31,101 @@
3131
class Field:
3232
name: str
3333
type: str
34+
description: Optional[str] = None
35+
36+
37+
def generate_fields_block(fields: List[Field]) -> str:
38+
declaration = []
39+
for field in fields:
40+
declaration.append(generate_field_declaration(field))
41+
42+
return "\n".join(declaration)
43+
44+
45+
def generate_field_declaration(field: Field) -> str:
46+
_validate_java_identifier(field.name)
47+
if field.description:
48+
javadoc = "\n".join([
49+
"",
50+
f"{indent_lvl1}/**",
51+
f"{indent_lvl1} * {field.description}",
52+
f"{indent_lvl1} */"
53+
])
54+
else:
55+
javadoc = ""
56+
declaration = [
57+
javadoc,
58+
f"{indent_lvl1}private {field.type} {field.name};"
59+
]
60+
return "\n".join(declaration)
61+
3462

63+
def generate_getters_and_setters(fields: List[Field]) -> str:
64+
methods = []
65+
for field in fields:
66+
methods.append(generate_getter(field))
67+
methods.append(generate_setter(field))
3568

36-
def generate_getter(attr: Field) -> str:
37-
attr_name = attr.name
38-
attr_type = attr.type
69+
return "\n\n".join(methods)
3970

40-
_validate_java_identifier(attr_name)
4171

42-
getter_name = "get" + attr_name[0].upper() + attr_name[1:]
72+
def generate_getter(field: Field) -> str:
73+
field_name = field.name
74+
field_type = field.type
75+
76+
_validate_java_identifier(field_name)
77+
78+
getter_name = "get" + field_name[0].upper() + field_name[1:]
4379

4480
getter = [
4581
"",
46-
f"{indent_lvl1}public {attr_type} {getter_name}() {{",
47-
f"{indent_lvl2}return {attr_name};",
82+
f"{indent_lvl1}public {field_type} {getter_name}() {{",
83+
f"{indent_lvl2}return {field_name};",
4884
f"{indent_lvl1}}}"
4985
]
5086
getter = "\n".join(getter)
5187

5288
return getter
5389

5490

55-
def generate_setter(attr: Field) -> str:
56-
attr_name = attr.name
57-
attr_type = attr.type
91+
def generate_setter(field: Field) -> str:
92+
field_name = field.name
93+
field_type = field.type
5894

59-
_validate_java_identifier(attr_name)
95+
_validate_java_identifier(field_name)
6096

61-
setter_name = "set" + attr_name[0].upper() + attr_name[1:]
97+
setter_name = "set" + field_name[0].upper() + field_name[1:]
6298

6399
setter = [
64100
"",
65-
f"{indent_lvl1}public void {setter_name}({attr_type} {attr_name}) {{",
66-
f"{indent_lvl2}this.{attr_name} = {attr_name};",
101+
f"{indent_lvl1}public void {setter_name}({field_type} {field_name}) {{",
102+
f"{indent_lvl2}this.{field_name} = {field_name};",
67103
f"{indent_lvl1}}}"
68104
]
69105
setter = "\n".join(setter)
70106
return setter
71107

72108

109+
def generate_hash_code(fields: List[Field]) -> str:
110+
hash_code = [
111+
"",
112+
f"{indent_lvl1}@Override",
113+
f"{indent_lvl1}public int hashCode() {{",
114+
f"{indent_lvl2}return Objects.hash("
115+
]
116+
117+
for i, field in enumerate(fields):
118+
_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}")
122+
123+
hash_code.append(f"{indent_lvl2});")
124+
hash_code.append(f"{indent_lvl1}}}")
125+
126+
return "\n".join(hash_code)
127+
128+
73129
def _validate_java_identifier(name: str) -> None:
74130
if not name:
75131
raise ValueError("Field name cannot be empty")

tests/reference_data.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from src.method_generator import Field
2+
3+
field_exampleAttribute_int = Field(name="exampleAttribute", type="int", description="javadoc description")
4+
field_someName_String = Field(name="someName", type="String")
5+
field_customData_CustomObject = Field(name="customData", type="CustomObject", description="another javadoc description")
6+
7+
expected_getExampleAttribute_int = """
8+
public int getExampleAttribute() {
9+
return exampleAttribute;
10+
}"""
11+
12+
expected_setExampleAttribute_int = """
13+
public void setExampleAttribute(int exampleAttribute) {
14+
this.exampleAttribute = exampleAttribute;
15+
}"""
16+
17+
expected_getSomeName_String = """
18+
public String getSomeName() {
19+
return someName;
20+
}"""
21+
22+
expected_setSomeName_String = """
23+
public void setSomeName(String someName) {
24+
this.someName = someName;
25+
}"""
26+
27+
expected_getCustomData_CustomObject = """
28+
public CustomObject getCustomData() {
29+
return customData;
30+
}"""
31+
32+
expected_setCustomData_CustomObject = """
33+
public void setCustomData(CustomObject customData) {
34+
this.customData = customData;
35+
}"""

tests/test_method_generator.py

Lines changed: 109 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import pytest
22

3-
from src.method_generator import generate_getter, Field, generate_setter
3+
from tests.reference_data import *
4+
from src.method_generator import *
45

56
JAVA_KEYWORDS = {
67
"abstract", "assert", "boolean", "break", "byte", "case", "catch",
@@ -22,78 +23,140 @@
2223
"null", "true", "false"
2324
}
2425

26+
EMPTY_NAMES = {None, ""}
27+
28+
MALFORMED_IDENTIFIERS = {"3", "abc-d", "gf*d"}
29+
30+
illegal_names = JAVA_KEYWORDS | JAVA_BUILTIN_TYPES | JAVA_LITERALS | EMPTY_NAMES | MALFORMED_IDENTIFIERS
31+
2532

2633
def test_generate_getter_integer():
27-
attr = Field(
28-
name="exampleAttribute",
29-
type="int"
30-
)
31-
expected = """
32-
public int getExampleAttribute() {
33-
return exampleAttribute;
34-
}"""
35-
assert (generate_getter(attr) == expected)
34+
attr = field_exampleAttribute_int
35+
36+
assert (generate_getter(attr) == expected_getExampleAttribute_int)
3637

3738

3839
def test_generate_getter_string():
39-
attr = Field(name="someName", type="String")
40-
expected = """
41-
public String getSomeName() {
42-
return someName;
43-
}"""
44-
assert (generate_getter(attr) == expected)
40+
attr = field_someName_String
41+
42+
assert (generate_getter(attr) == expected_getSomeName_String)
4543

4644

4745
def test_generate_getter_custom_object():
48-
attr = Field(name="customData", type="CustomObject")
49-
expected = """
50-
public CustomObject getCustomData() {
51-
return customData;
52-
}"""
53-
assert (generate_getter(attr) == expected)
46+
attr = field_customData_CustomObject
47+
48+
assert (generate_getter(attr) == expected_getCustomData_CustomObject)
5449

5550

5651
def test_generate_getter_invalid_name():
57-
EMPTY_NAMES = {None, ""}
58-
invalid_names = JAVA_KEYWORDS | JAVA_BUILTIN_TYPES | JAVA_LITERALS | EMPTY_NAMES
59-
for name in invalid_names:
52+
for name in illegal_names:
6053
attr = Field(name=name, type="String")
6154
with pytest.raises(ValueError):
6255
generate_getter(attr)
6356

6457

6558
def test_generate_setter_integer():
66-
attr = Field(name="exampleAttribute", type="int")
67-
expected = f"""
68-
public void setExampleAttribute(int exampleAttribute) {{
69-
this.exampleAttribute = exampleAttribute;
70-
}}"""
71-
assert (generate_setter(attr) == expected)
59+
attr = field_exampleAttribute_int
60+
61+
assert (generate_setter(attr) == expected_setExampleAttribute_int)
7262

7363

7464
def test_generate_setter_string():
75-
attr = Field(name="someName", type="String")
76-
expected = f"""
77-
public void setSomeName(String someName) {{
78-
this.someName = someName;
79-
}}"""
80-
assert (generate_setter(attr) == expected)
65+
attr = field_someName_String
66+
67+
assert (generate_setter(attr) == expected_setSomeName_String)
8168

8269

8370
def test_generate_setter_custom_object():
84-
attr = Field(name="customData", type="CustomObject")
85-
expected = f"""
86-
public void setCustomData(CustomObject customData) {{
87-
this.customData = customData;
88-
}}"""
89-
assert (generate_setter(attr) == expected)
71+
attr = field_customData_CustomObject
72+
73+
assert (generate_setter(attr) == expected_setCustomData_CustomObject)
9074

9175

9276
def test_generate_setter_invalid_name():
93-
EMPTY_NAMES = {None, ""}
94-
invalid_names = JAVA_KEYWORDS | JAVA_BUILTIN_TYPES | JAVA_LITERALS | EMPTY_NAMES
95-
for name in invalid_names:
77+
for name in illegal_names:
9678
attr = Field(name=name, type="String")
9779
with pytest.raises(ValueError):
9880
generate_setter(attr)
9981

82+
83+
def test_generate_getters_and_setters():
84+
attr1 = field_exampleAttribute_int
85+
attr2 = field_customData_CustomObject
86+
attributes = [attr1, attr2]
87+
88+
expected = "\n\n".join([
89+
expected_getExampleAttribute_int,
90+
expected_setExampleAttribute_int,
91+
expected_getCustomData_CustomObject,
92+
expected_setCustomData_CustomObject
93+
])
94+
assert generate_getters_and_setters(attributes) == expected
95+
96+
97+
def test_generate_field_declaration():
98+
attr = field_exampleAttribute_int
99+
expected = """
100+
/**
101+
* javadoc description
102+
*/
103+
private int exampleAttribute;"""
104+
105+
assert generate_field_declaration(attr) == expected
106+
107+
108+
def test_generate_field_declaration_no_description():
109+
attr = field_someName_String
110+
expected = """
111+
private String someName;"""
112+
113+
assert generate_field_declaration(attr) == expected
114+
115+
116+
def test_generate_field_declaration_invalid_name():
117+
for name in illegal_names:
118+
attr = Field(name=name, type="String")
119+
with pytest.raises(ValueError):
120+
generate_field_declaration(attr)
121+
122+
123+
def test_generate_fields_block():
124+
attr1 = field_exampleAttribute_int
125+
attr2 = field_someName_String
126+
attr3 = field_customData_CustomObject
127+
attributes = [attr1, attr2, attr3]
128+
expected = """
129+
/**
130+
* javadoc description
131+
*/
132+
private int exampleAttribute;\n
133+
private String someName;\n
134+
/**
135+
* another javadoc description
136+
*/
137+
private CustomObject customData;"""
138+
assert generate_fields_block(attributes) == expected
139+
140+
141+
def test_generate_hash_code():
142+
attr1 = field_exampleAttribute_int
143+
attr2 = field_someName_String
144+
attr3 = field_customData_CustomObject
145+
attributes = [attr1, attr2, attr3]
146+
expected = """
147+
@Override
148+
public int hashCode() {
149+
return Objects.hash(
150+
getExampleAttribute(),
151+
getSomeName(),
152+
getCustomData()
153+
);
154+
}"""
155+
assert generate_hash_code(attributes) == expected
156+
157+
158+
def test_generate_hash_code_invalid_name():
159+
for name in illegal_names:
160+
attr = Field(name=name, type="String")
161+
with pytest.raises(ValueError):
162+
generate_hash_code([attr])

0 commit comments

Comments
 (0)