├── .gitignore
├── LICENSE
├── README.md
├── docs
├── Draw2CodeLogo.png
├── arch.drawio
├── arrows.png
├── logo_ufpa_github_footer.png
└── toCode.drawio
├── examples
├── orcs.xml
└── strategy.xml
├── main.py
├── requirements.txt
├── src
├── __init__.py
├── dataToCode
│ ├── __init__.py
│ ├── dataClasses
│ │ ├── __init__.py
│ │ ├── attribute.py
│ │ ├── classData.py
│ │ ├── interface.py
│ │ ├── method.py
│ │ ├── modifier.py
│ │ └── visibility.py
│ ├── languages
│ │ ├── ToJava
│ │ │ ├── __init__.py
│ │ │ ├── classToJava.py
│ │ │ ├── fileNameToJava.py
│ │ │ ├── inheritanceToJava.py
│ │ │ ├── interfaceToJava.py
│ │ │ ├── languageJava.py
│ │ │ ├── methodModifierToJava.py
│ │ │ └── methodToJava.py
│ │ ├── __init__.py
│ │ ├── classToCode.py
│ │ ├── fileNameToCode.py
│ │ ├── inheritanceToCode.py
│ │ ├── interfaceToCode.py
│ │ ├── languageInterface.py
│ │ ├── methodModifierToCode.py
│ │ ├── methodToCode.py
│ │ └── toPython
│ │ │ ├── __init__.py
│ │ │ ├── classToPython.py
│ │ │ ├── fileNameToPython.py
│ │ │ ├── initToPython.py
│ │ │ ├── interfaceToPython.py
│ │ │ ├── languagePython.py
│ │ │ ├── methodToPython.py
│ │ │ └── visibilityToPython.py
│ └── write_files.py
└── xmlToData
│ ├── __init__.py
│ ├── classParser.py
│ ├── drawIoXmlParser.py
│ ├── interfaceParser.py
│ ├── regexExtractors
│ ├── __init__.py
│ ├── attributeNameExtractor.py
│ ├── methodNameExtractor.py
│ ├── parametersExtractor.py
│ ├── returnTypeExtractor.py
│ └── visibilityExtractor.py
│ └── uml_samples
│ ├── complete_uml.xml
│ ├── orcs.xml
│ ├── uml1.xml
│ ├── uml_extends.xml
│ ├── uml_interface.xml
│ └── uml_test.xml
└── test
├── __init__.py
├── strategy.xml
├── test_dataToCode
├── __init__.py
├── code_examples
│ ├── java
│ │ ├── java_example_1.txt
│ │ └── java_example_2.txt
│ └── python
│ │ ├── interface_example_1.txt
│ │ ├── interface_example_2.txt
│ │ ├── python_example_1.txt
│ │ ├── python_example_2.txt
│ │ ├── python_example_3.txt
│ │ └── python_example_4.txt
├── test_data_classes
│ ├── __init__.py
│ ├── test_attribute.py
│ ├── test_class_data.py
│ ├── test_interface.py
│ └── test_method.py
├── test_to_java
│ ├── __init__.py
│ ├── test_inheritanceToCode.py
│ ├── test_interface_to_java.py
│ ├── test_method_to_java.py
│ ├── test_name_to_java.py
│ └── test_system
│ │ ├── __init__.py
│ │ ├── strategy_example
│ │ ├── .Context.java.swp
│ │ ├── ConcreteStrategyA.java
│ │ ├── ConcreteStrategyB.java
│ │ ├── Context.java
│ │ ├── Strategy.java
│ │ └── __init__.py
│ │ ├── test_system.py
│ │ └── ultimate_example
│ │ ├── Attribute.java
│ │ ├── FatOrc.java
│ │ ├── HighOrc.java
│ │ ├── IAttack.java
│ │ ├── IFood.java
│ │ ├── ISpell.java
│ │ ├── IWalk.java
│ │ ├── ObeseOrc.java
│ │ ├── Orc.java
│ │ └── Weapon.java
├── test_to_python
│ ├── __init__.py
│ ├── test_fileNameToPython.py
│ ├── test_initToPython.py
│ ├── test_methodToPython.py
│ └── test_system
│ │ ├── __init__.py
│ │ ├── strategy_example
│ │ ├── concrete_strategy_a.py
│ │ ├── concrete_strategy_b.py
│ │ ├── context.py
│ │ └── strategy.py
│ │ ├── test_system.py
│ │ └── ultimate_example
│ │ ├── attribute.py
│ │ ├── fat_orc.py
│ │ ├── high_orc.py
│ │ ├── i_attack.py
│ │ ├── i_food.py
│ │ ├── i_spell.py
│ │ ├── i_walk.py
│ │ ├── obese_orc.py
│ │ ├── orc.py
│ │ └── weapon.py
└── tests_examples
│ ├── test_classToJava.py
│ ├── test_classToPython.py
│ └── test_interfaceToPython.py
├── test_xmlToData
├── __init__.py
├── test_drawIoXmlParser.py
└── test_regexExtractors
│ ├── __init__.py
│ ├── test_attributeNameExtractor.py
│ ├── test_methodNameExtractor.py
│ ├── test_parametersExtractor.py
│ ├── test_returnTypeExtractor.py
│ └── test_visibilityExtractor.py
└── ultimate_uml_test.xml
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/python
3 | # Edit at https://www.gitignore.io/?templates=python
4 |
5 | ### Python ###
6 | # Byte-compiled / optimized / DLL files
7 | __pycache__/
8 | *.py[cod]
9 | *$py.class
10 | .idea/
11 | # C extensions
12 | *.so
13 |
14 | # Distribution / packaging
15 | .Python
16 | build/
17 | develop-eggs/
18 | dist/
19 | downloads/
20 | eggs/
21 | .eggs/
22 | lib/
23 | lib64/
24 | parts/
25 | sdist/
26 | var/
27 | wheels/
28 | pip-wheel-metadata/
29 | share/python-wheels/
30 | *.egg-info/
31 | .installed.cfg
32 | *.egg
33 | MANIFEST
34 |
35 | # PyInstaller
36 | # Usually these files are written by a python script from a template
37 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
38 | *.manifest
39 | *.spec
40 |
41 | # Installer logs
42 | pip-log.txt
43 | pip-delete-this-directory.txt
44 |
45 | # Unit test / coverage reports
46 | htmlcov/
47 | .tox/
48 | .nox/
49 | .coverage
50 | .coverage.*
51 | .cache
52 | nosetests.xml
53 | coverage.xml
54 | *.cover
55 | .hypothesis/
56 | .pytest_cache/
57 |
58 | # Translations
59 | *.mo
60 | *.pot
61 |
62 | # Scrapy stuff:
63 | .scrapy
64 |
65 | # Sphinx documentation
66 | docs/_build/
67 |
68 | # PyBuilder
69 | target/
70 |
71 | # pyenv
72 | .python-version
73 |
74 | # pipenv
75 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
76 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
77 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
78 | # install all needed dependencies.
79 | #Pipfile.lock
80 |
81 | # celery beat schedule file
82 | celerybeat-schedule
83 |
84 | # SageMath parsed files
85 | *.sage.py
86 |
87 | # Spyder project settings
88 | .spyderproject
89 | .spyproject
90 |
91 | # Rope project settings
92 | .ropeproject
93 |
94 | # Mr Developer
95 | .mr.developer.cfg
96 | .project
97 | .pydevproject
98 |
99 | # mkdocs documentation
100 | /site
101 |
102 | # mypy
103 | .mypy_cache/
104 | .dmypy.json
105 | dmypy.json
106 |
107 | # Pyre type checker
108 | .pyre/
109 |
110 | ### Pycharm ###
111 | .idea/
112 | /venv/
113 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 CoffeeOverflow
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 |
4 | DrawToCode receives an UML diagram from [Draw.io](https://www.draw.io/) and
5 | makes code from it.
6 |
7 | ## Getting Started
8 |
9 | We don't have the intent to cover all Draw.io features and all programming
10 | languages, to know what you can
11 | use, go to the [Wiki](https://github.com/CoffeeOverflow/DrawToCode/wiki/Technical-Stuff).
12 |
13 | ### Programming Languages Accepted
14 |
15 | * Python
16 | * Java
17 |
18 | You can add another language by following the instructions on the
19 | [Wiki](https://github.com/CoffeeOverflow/DrawToCode/wiki).
20 |
21 | ### Prerequisites
22 |
23 | * Python 3.6.7+
24 |
25 | Install required packages by:
26 |
27 | ```bash
28 | pip install -r requirements.txt
29 | ```
30 |
31 | ### Usage
32 |
33 | ```bash
34 | python main.py --help
35 | ```
36 |
37 | #### Example
38 |
39 | ```
40 | python main.py --xml_file=orc.xml --code_path=/tmp/orc/ --language=python
41 | ```
42 |
43 | ## Running the Tests
44 |
45 | ```bash
46 | pytest-3 tests/
47 | ```
48 |
49 | #### Show Coverage
50 |
51 | ```bash
52 | pytest-3 --cov=src/ tests/
53 | ```
54 |
55 | ## Contributing
56 |
57 | Feel free to fork the project, we do not have the intent to close issues or
58 | accept pull requests.
59 |
60 | ## Authors
61 |
62 | ### [CoffeOverflow Team](https://github.com/CoffeeOverflow)
63 |
64 | * [Aian Shay](https://github.com/aianshay)
65 | * [Pedro Victor](https://github.com/Arouck)
66 | * [Renan Cunha](https://github.com/renan-cunha)
67 | * [Vitor Cantão](https://github.com/VitorCantao)
68 |
69 | ## License
70 |
71 | This project is licensed under the MIT License - see the [LICENSE](https://github.com/CoffeeOverflow/DrawToCode/blob/master/LICENSE) file
72 | for details.
73 |
74 | ## Acknowledgments
75 |
76 | This repository was developed as the final project of the [Project Analysis and
77 | Design](http://gustavopinto.org/teaching/pad) course, with the guidance of [Gustavo Pinto](https://github.com/gustavopinto),
78 | a professor at the Federal University of Pará. Click [here](https://docs.google.com/presentation/d/1j5E7s0f4vdqB3NgDm9Xl38Vo6kSPYseHy_20xzKqSos/edit?usp=sharing) to see the project presentation.
79 |
80 | [](https://portal.ufpa.br/ "Visite o site da UFPA")
81 |
--------------------------------------------------------------------------------
/docs/Draw2CodeLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/docs/Draw2CodeLogo.png
--------------------------------------------------------------------------------
/docs/arch.drawio:
--------------------------------------------------------------------------------
1 | 7Zhdb5swFIZ/DZeLwIYmuWxIt0VLpU6ptOSqcsENVg2OjNOQ/fqZYsKHoaUTHdnWmwq/2MZ+z9NjnxjQDZMvHO2Ca+ZjagDTTww4NwCYOLb8mwrHTHDMSSZsOfEzySqEFfmJlWgqdU98HFc6CsaoILuq6LEowp6oaIhzdqh2e2C0+tUd2mJNWHmI6uoP4osg35ZZ6F8x2Qb5ly1TvQlR3lkJcYB8dihJ8MqALmdMZE9h4mKaepf7ko373PL2tDCOI9FlwHRBrVtncX83XR6/x4/J/fLb3Sc1yxOie7Vhd7lQ6xXH3ATO9pGP03lMA84OARF4tUNe+vYgoy61QIRUtiz5qGbEXOCkdanWyQAJDmYhFvwou6gBECrPFDRgotqHIgRW7mtQsv9CaUhFfXuaujBGPihv3uAT0Hxah/QG8Rjzwd2ynKpblj20W1Bza44EcimKY/m/PLRfdbqG98vW/Lplrsykg1vlgHOzytGs0kzCkX+ZZn7Z8lLkiFf1BSdErFMLR8BRzY1yNH2eJ+XGMW9EcvXZKCdvbvIJ00Yx7LmVj8tWh33tlKmFQO6A7bmHX8/VAvEtFq/lKj2kpZA5DRHLNY4pEuSputymMKov3DAiN9KajGyrRkK2TTWqfFzVJgJmdSJYRyrzQZvomarTtn8ftIseQDsxUyamBFALMzmgVpnOkfMinz1yBjpyBj8464Gz8X/LGezImf3BWQ+cTfrkbDSuHIJmR9AKuDYl7N4dNLsjaC13oQ/Q3gSapWe09fVSg01eSkUVr1hw9ohdRhmXSsQi2XP2QCitSYiSbZQyKkGQ5RecpVdcIkv2S/UiJL6ffqbxgly9Qhs9lBN2ze+pfke2G7gB73VFtqZaABqLiX8mAnad+KEjAPqoUloKju65djxIsu1apWSUnk22nfSUbW34Z7Mt6KNOaTyeO9fDYLCCePxXHuznh5psFr9DZ92LH/Ph1S8=
--------------------------------------------------------------------------------
/docs/arrows.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/docs/arrows.png
--------------------------------------------------------------------------------
/docs/logo_ufpa_github_footer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/docs/logo_ufpa_github_footer.png
--------------------------------------------------------------------------------
/docs/toCode.drawio:
--------------------------------------------------------------------------------
1 | 7Vbfb5swEP5reMwEeKTNY5t0WbdWapVI654iB1/BmsHIOAT218/ENr+zTlOn9mEvie8739n3fceBg5ZJuRY4i+85Aeb4LikdtHJ8/zL4qH5roNJA4F5qIBKUaMhrgQ39CQZ0DXqgBPLeRsk5kzTrgyFPUwhlD8NC8GN/2zNn/VMzHMEI2ISYjdFvlMjYluW2+GegUWxP9lzjSbDdbIA8xoQfOxC6cdBScC71KimXwGruLC867tMZb3MxAan8k4DFLfO2we1+t7irHvMf5f7u625m1CkwO5iCHX/OVL5rQgu1jOrlli+VrE6dX/v2wrosoo7tBEzkUP84ydTi5KCpBPGMQ2jg32Y70Scrq4ngh5RAXZar3MeYSthkdTK0OqomVFgsE6Ysr4nu0mSYK0BIKDuQoW0NPAEpKrXFei+MhNXAPrYd4VmZ4043zA2GTRNGTepWJ7UwUk3LFs+uZbXzHu+vFuusmHHXK3YzfyTbln/BBX4Nqka8TLB3liq0GFDlvjVVaIKqh0rGPH13ZPnorcmaGgcDkiAlV/VcVVbIcJ7TsM+Lql1UT13je03oBz+w9qo0DGurslZJ5VNnrcMCY7VBtWFj9O2AjGb46GnP+UGE8PIjJbGIQL40MceSdiQLJhSzmACGJS36152S0ZzwwNWoPD+J0LATdJkmqvsyGCRq3ko2kTdIpHkYJTp1VVP23zfa/N812sU7bzT0v9FepdGU2X486e3tFyi6+QU=
--------------------------------------------------------------------------------
/examples/orcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/examples/strategy.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import click
2 |
3 | from src.dataToCode.write_files import write_files
4 | from src.xmlToData.drawIoXmlParser import DrawIoXmlParser
5 |
6 |
7 | @click.command()
8 | @click.option('--xml_file', required=True, prompt=True, type=click.File(mode='r'),
9 | help='The XML file path')
10 | @click.option('--code_path', required=True, prompt=True, type=click.Path(exists=True),
11 | help='The path of the code to be written')
12 | @click.option('--language', required=True, prompt=True,
13 | type=click.Choice(['python', 'java'], case_sensitive=False),
14 | help='The programming language of the code to be written')
15 | def run(xml_file, code_path, language):
16 | """Program that writes code of an UML class diagram"""
17 | draw_io_xml_parser = DrawIoXmlParser(xml_file)
18 | list_of_classes, list_of_interfaces = draw_io_xml_parser.read_xml()
19 |
20 | objects = list_of_classes + list_of_interfaces
21 |
22 | write_files(objects, code_path, language)
23 |
24 |
25 | if __name__ == '__main__':
26 | run()
27 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | click
2 | bs4
3 | pytest
4 |
5 |
--------------------------------------------------------------------------------
/src/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/src/__init__.py
--------------------------------------------------------------------------------
/src/dataToCode/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/src/dataToCode/__init__.py
--------------------------------------------------------------------------------
/src/dataToCode/dataClasses/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/src/dataToCode/dataClasses/__init__.py
--------------------------------------------------------------------------------
/src/dataToCode/dataClasses/attribute.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.visibility import Visibility
2 |
3 |
4 | class Attribute:
5 | def __init__(self, name: str, type_: str,
6 | visibility: Visibility = Visibility.private):
7 | self.name = name
8 | self.type_ = type_
9 | self.visibility = visibility
10 |
11 | def __eq__(self, other: "Attribute"):
12 | cond1 = self.name == other.name
13 | cond2 = self.type_ == other.type_
14 | cond3 = self.visibility == other.visibility
15 | if cond1 and cond2 and cond3:
16 | result = True
17 | else:
18 | result = False
19 | return result
20 |
--------------------------------------------------------------------------------
/src/dataToCode/dataClasses/classData.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.attribute import Attribute
2 | from src.dataToCode.dataClasses.method import Method
3 | from src.dataToCode.dataClasses.interface import Interface
4 | from src.dataToCode.dataClasses.visibility import Visibility
5 | from src.dataToCode.dataClasses.modifier import Modifier
6 | from typing import List
7 |
8 |
9 | class ClassData:
10 | def __init__(self, name: str,
11 | fields: List[Attribute] = [],
12 | methods: List[Method] = [],
13 | inheritances: List['ClassData'] = [],
14 | implementations: List[Interface] = [],
15 | visibility: Visibility = Visibility.public,
16 | modifier: Modifier = Modifier.none):
17 |
18 | self.name = name
19 | self.fields = fields
20 | self.methods = methods
21 | self.inheritances = inheritances
22 | self.implementations = implementations
23 | self.visibility = visibility
24 | self.modifier = modifier
25 |
26 | def __eq__(self, other: "ClassData"):
27 | cond1 = self.name == other.name
28 | cond2 = self.fields == other.fields
29 | cond3 = self.methods == other.methods
30 | cond4 = self.inheritances == other.inheritances
31 | cond5 = self.implementations == other.implementations
32 | cond6 = self.visibility == other.visibility
33 | cond7 = self.modifier == other.modifier
34 |
35 | if cond1 and cond2 and cond3 and cond4 and cond5 and cond6 and cond7:
36 | return True
37 | else:
38 | return False
39 |
--------------------------------------------------------------------------------
/src/dataToCode/dataClasses/interface.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.visibility import Visibility
2 | from typing import List
3 | from src.dataToCode.dataClasses.method import Method
4 |
5 |
6 | class Interface:
7 | def __init__(self, name: str,
8 | methods: List[Method],
9 | visibility: Visibility = Visibility.public,
10 | interfaces: List['Interface'] = []):
11 |
12 | self.name = name
13 | self.methods = methods
14 | self.interfaces = interfaces
15 | self.visibility = visibility
16 |
17 | def __eq__(self, other: "Interface"):
18 | cond1 = self.name == other.name
19 | cond2 = self.methods == other.methods
20 | cond3 = self.interfaces == other.interfaces
21 | cond4 = self.visibility == other.visibility
22 |
23 | if cond1 and cond2 and cond3 and cond4:
24 | return True
25 | else:
26 | return False
27 |
--------------------------------------------------------------------------------
/src/dataToCode/dataClasses/method.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.visibility import Visibility
2 | from src.dataToCode.dataClasses.modifier import Modifier
3 | from src.dataToCode.dataClasses.attribute import Attribute
4 | from typing import List
5 |
6 |
7 | class Method:
8 | def __init__(self, name: str,
9 | return_type: str = "void",
10 | parameters: List[Attribute] = [],
11 | visibility: Visibility = Visibility.public,
12 | modifier: Modifier = Modifier.none):
13 |
14 | self.name = name
15 | self.return_type = return_type
16 | self.parameters = parameters
17 | self.visibility = visibility
18 | self.modifier = modifier
19 |
20 | def __eq__(self, other: "Method"):
21 | cond1 = self.name == other.name
22 | cond2 = self.return_type == other.return_type
23 | cond3 = self.visibility == other.visibility
24 | cond4 = self.modifier == other.modifier
25 | cond5 = len(self.parameters) == len(other.parameters)
26 |
27 | if not(cond1 and cond2 and cond3 and cond4 and cond5):
28 | return False
29 | for x, y in zip(self.parameters, other.parameters):
30 | if x != y:
31 | return False
32 |
33 | return True
34 |
35 |
--------------------------------------------------------------------------------
/src/dataToCode/dataClasses/modifier.py:
--------------------------------------------------------------------------------
1 | from enum import Enum
2 |
3 |
4 | class Modifier(Enum):
5 | static = "static"
6 | abstract = "abstract"
7 | override = "override"
8 | none = ""
9 |
10 |
--------------------------------------------------------------------------------
/src/dataToCode/dataClasses/visibility.py:
--------------------------------------------------------------------------------
1 | from enum import Enum
2 |
3 |
4 | class Visibility(Enum):
5 | public = "public"
6 | private = "private"
7 | protected = "protected"
8 | package = "package"
9 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/ToJava/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/src/dataToCode/languages/ToJava/__init__.py
--------------------------------------------------------------------------------
/src/dataToCode/languages/ToJava/classToJava.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.languages.classToCode import ClassToCode
2 | from src.dataToCode.dataClasses.classData import ClassData
3 | from src.dataToCode.dataClasses.modifier import Modifier
4 | from src.dataToCode.languages.ToJava.methodToJava import MethodToJava
5 | from src.dataToCode.languages.ToJava.interfaceToJava import InterfaceToJava
6 | from src.dataToCode.languages.ToJava.inheritanceToJava import InheritanceToJava
7 |
8 |
9 | class ClassToJava(ClassToCode):
10 |
11 | def __init__(self, class_data: ClassData):
12 | self.class_data = class_data
13 | self.method_to_code = MethodToJava(self.class_data.methods, False)
14 | self.inheritance_to_code = InheritanceToJava(self.class_data.inheritances)
15 |
16 | def convert(self) -> str:
17 | return (f"import java.util.*;\n\n{self.__formatted_class_header()}\n"
18 | f"{self.__formatted_fields()}"
19 | f"{self.method_to_code.get_formatted_methods()}\n"
20 | f"}}")
21 |
22 | def __formatted_class_header(self):
23 | return (f"{self.class_data.visibility.name} {self.class_data.modifier.value}"
24 | f"{'' if self.class_data.modifier is Modifier.none else ' '}"
25 | f"class {self.class_data.name}{self.inheritance_to_code.get_formatted()}"
26 | f"{InterfaceToJava.codeImplementedInterfaces(self.class_data.implementations)}"
27 | f" {{\n")
28 |
29 | def __formatted_fields(self):
30 | if len(self.class_data.fields) > 0:
31 | class_fields = [f"\t{fields.visibility.value} {fields.type_} {fields.name};"
32 | for fields in self.class_data.fields]
33 |
34 | return '\n'.join(class_fields) + \
35 | ("\n\n" if self.class_data.methods else "")
36 | else:
37 | return ""
38 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/ToJava/fileNameToJava.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.languages.fileNameToCode import FileNameToCode
2 | from src.dataToCode.dataClasses.classData import ClassData
3 | from src.dataToCode.dataClasses.interface import Interface
4 | from typing import Union
5 |
6 |
7 | class FileNameToJava(FileNameToCode):
8 |
9 | def __init__(self, object_data: Union[ClassData, Interface]):
10 | self.name = object_data.name
11 |
12 | def get_file_name(self) -> str:
13 | return f"{self.name}.java"
14 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/ToJava/inheritanceToJava.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.languages.inheritanceToCode import InheritanceToCode
2 | from src.dataToCode.dataClasses.classData import ClassData
3 |
4 |
5 | class InheritanceToJava(InheritanceToCode):
6 | def __init__(self, inheritances: [ClassData]):
7 | self.inheritances = inheritances
8 |
9 | def get_formatted(self) -> str:
10 | if self.inheritances:
11 | return f" extends {self.__formatted_names()}"
12 | else:
13 | return ''
14 |
15 | def __formatted_names(self) -> str:
16 | inheritance_list = [f"{class_data.name}"
17 | for class_data in self.inheritances]
18 | return ', '.join(inheritance_list)
19 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/ToJava/interfaceToJava.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.languages.interfaceToCode import InterfaceToCode
2 | from src.dataToCode.dataClasses.interface import Interface
3 | from src.dataToCode.languages.ToJava.methodToJava import MethodToJava
4 |
5 | from typing import List
6 |
7 | class InterfaceToJava(InterfaceToCode):
8 |
9 | def __init__(self, interface: Interface):
10 | self.interface = interface
11 | self.method_to_code = MethodToJava(self.interface.methods, True)
12 |
13 | def convert(self) -> str:
14 |
15 | return (f"import java.util.*;\n\n"
16 | f"{self.interface.visibility.name} interface {self.interface.name}"
17 | f"{self.codeImplementedInterfaces(self.interface.interfaces)} {{\n\n"
18 | f"{self.method_to_code.get_formatted_methods()}\n"
19 | f"}}")
20 |
21 | @staticmethod
22 | def codeImplementedInterfaces(interfaces_list: List[Interface]) -> str:
23 | if len(interfaces_list) > 0:
24 | interfaces_names = [x.name for x in interfaces_list]
25 | interfaces_string = ", ".join(interfaces_names)
26 | result = f" implements {interfaces_string}"
27 | else:
28 | result = ""
29 | return result
30 |
31 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/ToJava/languageJava.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.classData import ClassData
2 | from src.dataToCode.dataClasses.interface import Interface
3 | from src.dataToCode.languages.languageInterface import LanguageInterface
4 | from src.dataToCode.languages.ToJava.classToJava import ClassToJava
5 | from src.dataToCode.languages.ToJava.interfaceToJava import InterfaceToJava
6 | from src.dataToCode.languages.ToJava.fileNameToJava import FileNameToJava
7 | from typing import Union
8 |
9 |
10 | class LanguageJava(LanguageInterface):
11 |
12 | def get_class_code(self, class_data: ClassData) -> str:
13 | class_java = ClassToJava(class_data)
14 | return class_java.convert()
15 |
16 | def get_interface_code(self, interface: Interface) -> str:
17 | interface_java = InterfaceToJava(interface)
18 | return interface_java.convert()
19 |
20 | def get_file_name(self, object_data: Union[ClassData, Interface]) -> str:
21 | file_name_to_java = FileNameToJava(object_data)
22 | return file_name_to_java.get_file_name()
23 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/ToJava/methodModifierToJava.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.languages.methodModifierToCode import MethodModifierToCode
2 | from src.dataToCode.dataClasses.method import Method
3 | from src.dataToCode.dataClasses.modifier import Modifier
4 |
5 |
6 | class MethodModifierToJava(MethodModifierToCode):
7 | def __init__(self, method: Method):
8 | self.method = method
9 |
10 | def formatted_modifier(self) -> str:
11 | return f"{self.__get_modifier_value() + self.__get_modifier_space()}"
12 |
13 | def formatted_override(self) -> str:
14 | if self.method.modifier is Modifier.override:
15 | return f"@{self.method.modifier.value}\n\t"
16 | else:
17 | return ""
18 |
19 | def __get_modifier_value(self) -> str:
20 | if self.method.modifier is Modifier.override:
21 | return ''
22 | else:
23 | return self.method.modifier.value
24 |
25 | def __get_modifier_space(self) -> str:
26 | if self.method.modifier in [Modifier.none, Modifier.override]:
27 | return ''
28 | else:
29 | return " "
30 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/ToJava/methodToJava.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.languages.methodToCode import MethodToCode
2 | from src.dataToCode.dataClasses.method import Method
3 | from src.dataToCode.dataClasses.attribute import Attribute
4 | from src.dataToCode.languages.ToJava.methodModifierToJava \
5 | import MethodModifierToJava
6 | from typing import List
7 |
8 |
9 | class MethodToJava(MethodToCode):
10 | def __init__(self, methods: List[Method], is_from_interface: bool):
11 | self.methods = methods
12 | self.is_from_interface = is_from_interface
13 |
14 | def get_formatted_methods(self) -> str:
15 | methods_str_list = [f"\t{self.__convert_method(method)}"
16 | for method in self.methods]
17 | return '\n\n'.join(methods_str_list)
18 |
19 | def __convert_method(self, method: Method) -> str:
20 | modifier_to_java = MethodModifierToJava(method)
21 |
22 | return (f"{modifier_to_java.formatted_override()}"
23 | f"{method.visibility.name} "
24 | f"{modifier_to_java.formatted_modifier()}"
25 | f"{method.return_type} {method.name}"
26 | f"({self.__formatted_parameters(method.parameters)})"
27 | f"{self.__formatted_body()}")
28 |
29 | def __formatted_body(self) -> str:
30 | if self.is_from_interface:
31 | return ";"
32 | else:
33 | return " {\n\t\tthrow new UnsupportedOperationException();\n\t}"
34 |
35 | def __formatted_parameters(self, parameters: List[Attribute]) -> str:
36 | parameters = [f"{parameter.type_} {parameter.name}"
37 | for parameter in parameters]
38 | return ', '.join(parameters)
39 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/src/dataToCode/languages/__init__.py
--------------------------------------------------------------------------------
/src/dataToCode/languages/classToCode.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class ClassToCode(ABC):
5 | @abstractmethod
6 | def convert(self) -> str:
7 | pass
8 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/fileNameToCode.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class FileNameToCode(ABC):
5 |
6 | @abstractmethod
7 | def get_file_name(self) -> str:
8 | pass
9 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/inheritanceToCode.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class InheritanceToCode(ABC):
5 | @abstractmethod
6 | def get_formatted(self) -> str:
7 | pass
8 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/interfaceToCode.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class InterfaceToCode(ABC):
5 | @abstractmethod
6 | def convert(self) -> str:
7 | pass
8 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/languageInterface.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 | from src.dataToCode.dataClasses.classData import ClassData
3 | from src.dataToCode.dataClasses.interface import Interface
4 | from typing import Union
5 |
6 |
7 | class LanguageInterface(ABC):
8 |
9 | @abstractmethod
10 | def get_class_code(self, class_data: ClassData) -> str:
11 | pass
12 |
13 | @abstractmethod
14 | def get_interface_code(self, interface: Interface) -> str:
15 | pass
16 |
17 | @abstractmethod
18 | def get_file_name(self, object_data: Union[ClassData, Interface]) -> str:
19 | pass
20 |
21 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/methodModifierToCode.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class MethodModifierToCode(ABC):
5 | @abstractmethod
6 | def formatted_modifier(self) -> str:
7 | pass
8 |
9 | @abstractmethod
10 | def formatted_override(self) -> str:
11 | pass
12 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/methodToCode.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class MethodToCode(ABC):
5 | @abstractmethod
6 | def get_formatted_methods(self) -> str:
7 | pass
8 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/toPython/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/src/dataToCode/languages/toPython/__init__.py
--------------------------------------------------------------------------------
/src/dataToCode/languages/toPython/classToPython.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.classData import ClassData
2 | from src.dataToCode.dataClasses.modifier import Modifier
3 | from src.dataToCode.languages.classToCode import ClassToCode
4 | from src.dataToCode.languages.toPython.initToPython import InitToPython
5 | from src.dataToCode.languages.toPython.methodToPython import MethodToPython
6 | from src.dataToCode.languages.toPython.fileNameToPython import FileNameToPython
7 |
8 | class ClassToPython(ClassToCode):
9 | def __init__(self, class_data: ClassData):
10 | self.class_data = class_data
11 | all_methods = self.class_data.methods
12 |
13 | for implementation in self.class_data.implementations:
14 | for method in implementation.methods:
15 | if method not in all_methods:
16 | all_methods.append(method)
17 |
18 | all_methods = list(all_methods)
19 | self.method_to_code = MethodToPython(all_methods, False)
20 | self.init_to_python = InitToPython(self.class_data.fields)
21 |
22 | def convert(self) -> str:
23 | return (f"{self.__formatted_imports()}"
24 | f"class {self.class_data.name}"
25 | f"({self.__formatted_inheritances()}):\n"
26 | f"\n{self.init_to_python.get_formatted()}\n"
27 | f"{self.method_to_code.get_formatted_methods()}\n")
28 |
29 | def __formatted_imports(self) -> str:
30 | inheritances = self.class_data.inheritances + self.class_data.implementations
31 | imports = [f"from {FileNameToPython(inheritance).get_file_name()[:-3]} import {inheritance.name}"
32 | for inheritance in inheritances]
33 | optional_import = self.__optional_abc_import()
34 | space = '\n\n\n' if inheritances else '\n\n' if optional_import else ""
35 | return optional_import + '\n'.join(imports) + space
36 |
37 | def __optional_abc_import(self) -> str:
38 | for method in self.class_data.methods:
39 | if method.modifier is Modifier.abstract:
40 | return "from abc import ABC, abstractmethod\n"
41 | return ""
42 |
43 | def __formatted_inheritances(self) -> str:
44 | inheritances = self.class_data.inheritances + self.class_data.implementations
45 | inheritances_name = [f"{inheritance.name}"
46 | for inheritance in inheritances]
47 | return ', '.join(inheritances_name)
48 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/toPython/fileNameToPython.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.classData import ClassData
2 | from src.dataToCode.dataClasses.interface import Interface
3 | from src.dataToCode.languages.fileNameToCode import FileNameToCode
4 | from typing import Union
5 | import re
6 |
7 |
8 | class FileNameToPython(FileNameToCode):
9 | def __init__(self, data: Union[ClassData, Interface]):
10 | self.data = data
11 |
12 | def get_file_name(self) -> str:
13 | words = re.findall("[A-Z][^A-Z]*", self.data.name)
14 | formatted_name = '_'.join(words)
15 | return formatted_name.lower() + '.py'
16 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/toPython/initToPython.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | from src.dataToCode.dataClasses.attribute import Attribute
3 | from src.dataToCode.languages.toPython.visibilityToPython import visibility_to_python
4 |
5 |
6 | class InitToPython:
7 | def __init__(self, class_fields: List[Attribute]):
8 | self.class_fields = class_fields
9 |
10 | def get_formatted(self) -> str:
11 | pass_ = '\t\tpass'
12 | return (f"\tdef __init__(self" + self.__formatted_parameters() + "):\n"
13 | f"{self.__formatted_assignments() if self.class_fields else pass_}\n")
14 |
15 | def __formatted_parameters(self) -> str:
16 | fields_name = [f"{field.name}"
17 | for field in self.class_fields]
18 | return f", {', '.join(fields_name)}" if self.class_fields else ""
19 |
20 | def __formatted_assignments(self) -> str:
21 | class_fields = [f"\t\tself.{visibility_to_python[field.visibility]}"
22 | f"{field.name} = {field.name}"
23 | for field in self.class_fields]
24 | return '\n'.join(class_fields)
25 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/toPython/interfaceToPython.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.interface import Interface
2 | from src.dataToCode.languages.interfaceToCode import InterfaceToCode
3 | from src.dataToCode.languages.toPython.methodToPython import MethodToPython
4 | from src.dataToCode.languages.toPython.fileNameToPython import FileNameToPython
5 |
6 |
7 | class InterfaceToPython(InterfaceToCode):
8 | def __init__(self, interface: Interface):
9 | self.interface = interface
10 | self.method_to_code = MethodToPython(self.interface.methods, True)
11 |
12 | def convert(self) -> str:
13 | return (f"{self.__formatted_imports()}"
14 | f"class {self.interface.name}"
15 | f"({self.__formatted_inheritances()}):\n"
16 | f"\n{self.method_to_code.get_formatted_methods()}\n")
17 |
18 | def __formatted_imports(self) -> str:
19 | imports = [f"from {FileNameToPython(inheritance).get_file_name()[:-3]} import {inheritance.name}"
20 | for inheritance in self.interface.interfaces]
21 | space = '\n\n\n' if self.interface.interfaces else '\n\n'
22 | return "from abc import ABC, abstractmethod\n" + '\n'.join(imports) + space
23 |
24 | def __formatted_inheritances(self) -> str:
25 | inheritances_name = [f"{interface.name}"
26 | for interface in self.interface.interfaces]
27 | abstract_import = "ABC, " if self.interface.interfaces else "ABC"
28 | return abstract_import + ', '.join(inheritances_name)
29 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/toPython/languagePython.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.classData import ClassData
2 | from src.dataToCode.dataClasses.interface import Interface
3 | from src.dataToCode.languages.languageInterface import LanguageInterface
4 | from src.dataToCode.languages.toPython.classToPython import ClassToPython
5 | from src.dataToCode.languages.toPython.interfaceToPython import InterfaceToPython
6 | from src.dataToCode.languages.toPython.fileNameToPython import FileNameToPython
7 | from typing import Union
8 |
9 |
10 | class LanguagePython(LanguageInterface):
11 |
12 | def get_class_code(self, class_data: ClassData) -> str:
13 | class_python = ClassToPython(class_data)
14 | return class_python.convert()
15 |
16 | def get_interface_code(self, interface: Interface) -> str:
17 | interface_python = InterfaceToPython(interface)
18 | return interface_python.convert()
19 |
20 | def get_file_name(self, object_data: Union[ClassData, Interface]) -> str:
21 | file_name_to_python = FileNameToPython(object_data)
22 | return file_name_to_python.get_file_name()
23 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/toPython/methodToPython.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 |
3 | from src.dataToCode.dataClasses.attribute import Attribute
4 | from src.dataToCode.languages.toPython.visibilityToPython import visibility_to_python
5 | from src.dataToCode.languages.methodToCode import MethodToCode
6 | from src.dataToCode.dataClasses.method import Method
7 | from src.dataToCode.dataClasses.modifier import Modifier
8 |
9 |
10 | class MethodToPython(MethodToCode):
11 | def __init__(self, methods: List[Method], is_from_interface: bool):
12 | self.methods = methods
13 | self.is_from_interface = is_from_interface
14 |
15 | def get_formatted_methods(self) -> str:
16 | methods_str_list = [f"\t{self.__convert_method(method)}"
17 | for method in self.methods]
18 | return '\n\n'.join(methods_str_list)
19 |
20 | def __convert_method(self, method: Method) -> str:
21 | return (f"{self.__formatted_modifier(method)}"
22 | f"def {visibility_to_python[method.visibility]}"
23 | f"{method.name}("
24 | f"{'self' if method.modifier is not Modifier.static else ''}"
25 | f"{', ' if method.parameters and method.modifier is not Modifier.static else ''}"
26 | f"{self.__formatted_parameters(method.parameters)}):"
27 | f"{self.__formatted_body()}")
28 |
29 | def __formatted_body(self) -> str:
30 | return "\n\t\tpass"
31 |
32 | def __formatted_parameters(self, parameters: List[Attribute]) -> str:
33 | parameters = [f"{parameter.name}"
34 | for parameter in parameters]
35 | return ', '.join(parameters)
36 |
37 | def __formatted_modifier(self, method: Method) -> str:
38 | if method.modifier is Modifier.abstract or self.is_from_interface:
39 | return "@abstractmethod\n\t"
40 | elif method.modifier is Modifier.static:
41 | return "@staticmethod\n\t"
42 | else:
43 | return ""
44 |
--------------------------------------------------------------------------------
/src/dataToCode/languages/toPython/visibilityToPython.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.visibility import Visibility
2 |
3 | visibility_to_python = {Visibility.private: "__",
4 | Visibility.protected: "_",
5 | Visibility.public: "",
6 | Visibility.package: ""}
7 |
--------------------------------------------------------------------------------
/src/dataToCode/write_files.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from src.dataToCode.dataClasses.classData import ClassData
4 | from src.dataToCode.dataClasses.interface import Interface
5 | from src.dataToCode.languages.ToJava.languageJava import LanguageJava
6 | from src.dataToCode.languages.toPython.languagePython import LanguagePython
7 | from src.dataToCode.languages.languageInterface import LanguageInterface
8 |
9 | from typing import List, Union
10 |
11 |
12 | def select_language(language: str) -> LanguageInterface:
13 | language_writer: LanguageInterface
14 | if language == "python":
15 | language_writer = LanguagePython()
16 | elif language == "java":
17 | language_writer = LanguageJava()
18 | else:
19 | raise ValueError("This language is not implemented")
20 | return language_writer
21 |
22 |
23 | def write_files(objects: List[Union[ClassData, Interface]],
24 | path: str, language: str) -> None:
25 |
26 | print('\n')
27 | language_writer = select_language(language)
28 | for element in objects:
29 | if type(element) == ClassData:
30 | source_code = language_writer.get_class_code(element)
31 | elif type(element) == Interface:
32 | source_code = language_writer.get_interface_code(element)
33 | else:
34 | raise ValueError(f"{type(element)} is not acceptable "
35 | f"Use classData or interface")
36 |
37 | name = language_writer.get_file_name(element)
38 | element_file_path = os.path.join(path, name)
39 |
40 | with open(element_file_path, "w") as element_file:
41 | element_file.write(source_code)
42 |
43 | print(f"'{name}' created")
44 | print('Done.')
45 |
--------------------------------------------------------------------------------
/src/xmlToData/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/src/xmlToData/__init__.py
--------------------------------------------------------------------------------
/src/xmlToData/classParser.py:
--------------------------------------------------------------------------------
1 | import xml.etree.ElementTree as ET
2 | from bs4 import BeautifulSoup as bs
3 | from src.dataToCode.dataClasses.attribute import Attribute
4 | from src.dataToCode.dataClasses.classData import ClassData
5 | from src.dataToCode.dataClasses.method import Method
6 | from src.dataToCode.dataClasses.visibility import Visibility
7 | from src.xmlToData.regexExtractors.attributeNameExtractor import AttributeNameExtractor
8 | from src.xmlToData.regexExtractors.methodNameExtractor import MethodNameExtractor
9 | from src.xmlToData.regexExtractors.parametersExtractor import ParametersExtractor
10 | from src.xmlToData.regexExtractors.returnTypeExtractor import ReturnTypeExtractor
11 | from src.xmlToData.regexExtractors.visibilityExtractor import VisibilityExtractor
12 |
13 |
14 | class ClassParser:
15 |
16 | @staticmethod
17 | def read_xml(uml_data: str):
18 | uml_data = uml_data.replace("
", "")
19 | uml_data = uml_data.replace("
", "")
20 | list_of_attributes = []
21 | list_of_methods = []
22 | id_to_name = {}
23 |
24 | html = bs(uml_data, 'html.parser')
25 |
26 | result = html.find_all('p')
27 |
28 | class_name = ''
29 |
30 | for i in range(len(result)):
31 | if result[i].string is not None:
32 | if i == 0:
33 | class_name = result[i].b.string
34 | id_to_name[id] = class_name
35 | else:
36 | visibility = VisibilityExtractor.extract_visibility(result[i].string)
37 | type_ = ReturnTypeExtractor.extract_type(result[i].string)
38 |
39 | if '(' in result[i].string:
40 | name = MethodNameExtractor.extract_name(result[i].string)
41 |
42 | list_of_parameters_string = ParametersExtractor.extract_parameters_string(result[i].string)
43 |
44 | list_of_parameters = []
45 | if len(list_of_parameters_string) != 0 and list_of_parameters_string[0] != '':
46 | for parameter_string in list_of_parameters_string:
47 | parameter_name = AttributeNameExtractor.extract_name(parameter_string)
48 | parameter_type = ReturnTypeExtractor.extract_type(parameter_string)
49 | parameter = Attribute(parameter_name, parameter_type)
50 | list_of_parameters.append(parameter)
51 |
52 | method = Method(name, type_, list_of_parameters, visibility)
53 | list_of_methods.append(method)
54 | else:
55 | name = AttributeNameExtractor.extract_name(result[i].string)
56 | attribute = Attribute(name, type_, visibility)
57 | list_of_attributes.append(attribute)
58 |
59 | return ClassData(class_name, list_of_attributes, list_of_methods)
60 |
--------------------------------------------------------------------------------
/src/xmlToData/drawIoXmlParser.py:
--------------------------------------------------------------------------------
1 | import xml.etree.ElementTree as ET
2 | from typing import Tuple, Dict
3 |
4 | from src.xmlToData.classParser import ClassParser
5 | from src.xmlToData.interfaceParser import InterfaceParser
6 |
7 |
8 | class DrawIoXmlParser:
9 |
10 | def __init__(self, filename: str) -> object:
11 | self.filename = filename
12 |
13 | @staticmethod
14 | def extract_value_from_cells(root) -> Tuple[list, list, Dict[str, list], Dict[str, list]]:
15 | list_of_xml_classes = []
16 | list_of_ids = []
17 | superclass_to_subclasses = {}
18 | implements_dict = {}
19 |
20 | for cell in root.iter('mxCell'):
21 | if cell.get('id') not in ['0', '1']:
22 | if cell.get('value') == 'Extends':
23 | subclass = cell.get('source')
24 | superclass = cell.get('target')
25 |
26 | try:
27 | superclass_to_subclasses[superclass].append(subclass)
28 | except KeyError:
29 | superclass_to_subclasses[superclass] = [subclass]
30 |
31 | elif "endArrow=block;dashed=1" in cell.get('style'): # implements arrow
32 | source_class = cell.get('source')
33 | target_class = cell.get('target') # interface
34 |
35 | try:
36 | implements_dict[target_class].append(source_class)
37 | except KeyError:
38 | implements_dict[target_class] = [source_class]
39 | elif "" in cell.get('value'):
40 | list_of_ids.append(cell.get('id'))
41 | list_of_xml_classes.append(cell.get('value'))
42 |
43 | return list_of_xml_classes, list_of_ids, superclass_to_subclasses, implements_dict
44 |
45 | def read_xml(self):
46 | xml = ET.parse(self.filename)
47 | root = xml.getroot()
48 |
49 | list_of_xml_classes, ids_list, extends_dict, implements_dict = self.extract_value_from_cells(root)
50 |
51 | list_of_classes = []
52 | list_of_interfaces = []
53 | ids_to_names = {}
54 |
55 | for uml_data, class_id in zip(list_of_xml_classes, ids_list):
56 | if "Interface" in uml_data:
57 | interface_ = InterfaceParser.read_xml(uml_data)
58 | list_of_interfaces.append(interface_)
59 | ids_to_names[class_id] = interface_.name
60 | else:
61 | class_ = ClassParser.read_xml(uml_data)
62 | list_of_classes.append(class_)
63 | ids_to_names[class_id] = class_.name
64 |
65 | for superclass_id, subclasses in extends_dict.items():
66 | superclass_name = ids_to_names[superclass_id]
67 | for subclass_id in subclasses:
68 | subclass_name = ids_to_names[subclass_id]
69 | for class_ in list_of_classes:
70 | if class_.name == subclass_name:
71 | list_of_inheritances = class_.inheritances.copy()
72 | for superclass_ in list_of_classes:
73 | if superclass_name == superclass_.name:
74 | list_of_inheritances.append(superclass_)
75 | class_.inheritances = list_of_inheritances.copy()
76 |
77 | for interface_id, subclasses in implements_dict.items():
78 | interface_name = ids_to_names[interface_id]
79 | for class_id in subclasses:
80 | class_name = ids_to_names[class_id]
81 | for class_ in list_of_classes:
82 | if class_.name == class_name:
83 | list_of_interfaces_implemented = class_.implementations.copy()
84 | for interface_ in list_of_interfaces:
85 | if interface_name == interface_.name:
86 | list_of_interfaces_implemented.append(interface_)
87 | class_.implementations = list_of_interfaces_implemented.copy()
88 |
89 | return list_of_classes, list_of_interfaces
90 |
--------------------------------------------------------------------------------
/src/xmlToData/interfaceParser.py:
--------------------------------------------------------------------------------
1 | import xml.etree.ElementTree as ET
2 | from bs4 import BeautifulSoup as bs
3 | from src.dataToCode.dataClasses.attribute import Attribute
4 | from src.dataToCode.dataClasses.classData import ClassData
5 | from src.dataToCode.dataClasses.interface import Interface
6 | from src.dataToCode.dataClasses.method import Method
7 | from src.dataToCode.dataClasses.visibility import Visibility
8 | from src.xmlToData.regexExtractors.attributeNameExtractor import AttributeNameExtractor
9 | from src.xmlToData.regexExtractors.methodNameExtractor import MethodNameExtractor
10 | from src.xmlToData.regexExtractors.parametersExtractor import ParametersExtractor
11 | from src.xmlToData.regexExtractors.returnTypeExtractor import ReturnTypeExtractor
12 | from src.xmlToData.regexExtractors.visibilityExtractor import VisibilityExtractor
13 |
14 |
15 | class InterfaceParser:
16 |
17 | @staticmethod
18 | def read_xml(uml_data: str):
19 | list_of_methods = []
20 | list_of_methods_string_literals = []
21 |
22 | html = bs(uml_data, 'html.parser')
23 |
24 | result = html.find_all('p')
25 |
26 | if result[0].b is None:
27 | interface_name = result[1].b.string
28 | else:
29 | interface_name = result[0].b.string
30 |
31 | list_of_methods_string_literals += str(result[-1]).split("
")
32 | if len(list_of_methods_string_literals) == 1:
33 | list_of_methods_string_literals = str(result[-1]).split("
")
34 |
35 | list_of_methods_string_literals[0] = \
36 | list_of_methods_string_literals[0].replace("
", "")
37 | list_of_methods_string_literals[-1] = \
38 | list_of_methods_string_literals[-1].replace("
", "")
39 |
40 | for xml_string in list_of_methods_string_literals:
41 | if xml_string != "":
42 | visibility = VisibilityExtractor.extract_visibility(xml_string)
43 | type_ = ReturnTypeExtractor.extract_type(xml_string)
44 | name = MethodNameExtractor.extract_name(xml_string)
45 | list_of_parameters_string = ParametersExtractor.extract_parameters_string(xml_string)
46 |
47 | list_of_parameters = []
48 | if len(list_of_parameters_string) != 0 and list_of_parameters_string[0] != '':
49 | for parameter_string in list_of_parameters_string:
50 | parameter_name = AttributeNameExtractor.extract_name(parameter_string)
51 | parameter_type = ReturnTypeExtractor.extract_type(parameter_string)
52 | parameter = Attribute(parameter_name, parameter_type)
53 | list_of_parameters.append(parameter)
54 |
55 | method = Method(name, type_, list_of_parameters, visibility)
56 | list_of_methods.append(method)
57 |
58 | return Interface(interface_name, list_of_methods)
59 |
--------------------------------------------------------------------------------
/src/xmlToData/regexExtractors/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/src/xmlToData/regexExtractors/__init__.py
--------------------------------------------------------------------------------
/src/xmlToData/regexExtractors/attributeNameExtractor.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 |
4 | class AttributeNameExtractor:
5 |
6 | @staticmethod
7 | def extract_name(xml_string) -> str:
8 | regex = re.compile(r"\w+\(*.*:")
9 | name = str(regex.findall(xml_string))[2:-3].strip()
10 | return name
11 |
--------------------------------------------------------------------------------
/src/xmlToData/regexExtractors/methodNameExtractor.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 |
4 | class MethodNameExtractor:
5 |
6 | @staticmethod
7 | def extract_name(xml_string) -> str:
8 | regex = re.compile(r"\w+\s*\(")
9 | name = str(regex.findall(xml_string))[2:-3].strip()
10 | return name
11 |
--------------------------------------------------------------------------------
/src/xmlToData/regexExtractors/parametersExtractor.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 |
4 | class ParametersExtractor:
5 |
6 | @staticmethod
7 | def extract_parameters_string(xml_string) -> list:
8 | regex = re.compile(r"\(.*\)")
9 | name = str(regex.findall(xml_string))
10 | unformatted_parameters_string_list = name[3:-3].split(",")
11 | formatted_parameters_string_list = []
12 | for parameter in unformatted_parameters_string_list:
13 | formatted_parameters_string_list.append(parameter.strip())
14 | return formatted_parameters_string_list
15 |
--------------------------------------------------------------------------------
/src/xmlToData/regexExtractors/returnTypeExtractor.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 |
4 | class ReturnTypeExtractor:
5 |
6 | @staticmethod
7 | def extract_type(xml_string) -> str:
8 | xml_string = xml_string.replace('<', '<')
9 | xml_string = xml_string.replace('>', '>')
10 |
11 | regex = re.compile(r"\)*:\s*\w+\<*\w*\>*")
12 | list_of_types = regex.findall(xml_string)
13 |
14 | if ')' in list_of_types[-1]:
15 | return list_of_types[-1].split(':')[1].lstrip()
16 |
17 | return list_of_types[-1][1:].lstrip()
18 |
--------------------------------------------------------------------------------
/src/xmlToData/regexExtractors/visibilityExtractor.py:
--------------------------------------------------------------------------------
1 | import re
2 | from src.dataToCode.dataClasses.visibility import Visibility
3 |
4 |
5 | class VisibilityExtractor:
6 |
7 | @staticmethod
8 | def extract_visibility(xml_string) -> Visibility:
9 | types_of_visibilities = {"+": Visibility.public, "-": Visibility.private, "#": Visibility.protected}
10 | regex = re.compile(r"^\s*.")
11 | visibility = str(regex.findall(xml_string))[2:-2]
12 | return types_of_visibilities[visibility.strip()]
13 |
--------------------------------------------------------------------------------
/src/xmlToData/uml_samples/complete_uml.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/xmlToData/uml_samples/orcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/src/xmlToData/uml_samples/uml1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/xmlToData/uml_samples/uml_extends.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/xmlToData/uml_samples/uml_interface.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/xmlToData/uml_samples/uml_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/test/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/test/__init__.py
--------------------------------------------------------------------------------
/test/strategy.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/test/test_dataToCode/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/test/test_dataToCode/__init__.py
--------------------------------------------------------------------------------
/test/test_dataToCode/code_examples/java/java_example_1.txt:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class Dog {
4 |
5 | public String name;
6 | private int age;
7 |
8 | public void bark() {
9 | throw new UnsupportedOperationException();
10 | }
11 |
12 | private bool growUp(int byAge) {
13 | throw new UnsupportedOperationException();
14 | }
15 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/code_examples/java/java_example_2.txt:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class Orc extends Monster implements IWalk, IAttack {
4 |
5 | public void attack(int damage, Entity entity, Bonus bonus) {
6 | throw new UnsupportedOperationException();
7 | }
8 |
9 | protected static void cry() {
10 | throw new UnsupportedOperationException();
11 | }
12 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/code_examples/python/interface_example_1.txt:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class Example(ABC):
5 |
6 | @abstractmethod
7 | def do(self):
8 | pass
9 |
--------------------------------------------------------------------------------
/test/test_dataToCode/code_examples/python/interface_example_2.txt:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 | from i_foo import IFoo
3 |
4 |
5 | class Example(ABC, IFoo):
6 |
7 | @abstractmethod
8 | def foo(self, a, b):
9 | pass
10 |
11 | @abstractmethod
12 | def do(self):
13 | pass
14 |
--------------------------------------------------------------------------------
/test/test_dataToCode/code_examples/python/python_example_1.txt:
--------------------------------------------------------------------------------
1 | class Dog():
2 |
3 | def __init__(self, name, age):
4 | self.name = name
5 | self.__age = age
6 |
7 | def bark(self):
8 | pass
9 |
10 | def __grow_up(self, by_age):
11 | pass
12 |
--------------------------------------------------------------------------------
/test/test_dataToCode/code_examples/python/python_example_2.txt:
--------------------------------------------------------------------------------
1 | from monster import Monster
2 | from i_walk import IWalk
3 | from i_attack import IAttack
4 |
5 |
6 | class Orc(Monster, IWalk, IAttack):
7 |
8 | def __init__(self):
9 | pass
10 |
11 | def attack(self, damage, entity, bonus):
12 | pass
13 |
14 | @staticmethod
15 | def _cry():
16 | pass
17 |
--------------------------------------------------------------------------------
/test/test_dataToCode/code_examples/python/python_example_3.txt:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 | from i_do_many_things import IDoManyThings
3 |
4 |
5 | class WeirdGodClass(IDoManyThings):
6 |
7 | def __init__(self, mail_reader, configs, network_adapter, test_runner):
8 | self.mail_reader = mail_reader
9 | self.__configs = configs
10 | self.network_adapter = network_adapter
11 | self._test_runner = test_runner
12 |
13 | def initialize(self):
14 | pass
15 |
16 | @abstractmethod
17 | def initialize_2(self):
18 | pass
19 |
20 | @staticmethod
21 | def _do_things(how_much, flag1, flag2):
22 | pass
23 |
24 | def __no_one_will_ever_use_this(self, trash, trash_can):
25 | pass
26 |
--------------------------------------------------------------------------------
/test/test_dataToCode/code_examples/python/python_example_4.txt:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class Test4():
5 |
6 | def __init__(self, m):
7 | self.m = m
8 |
9 | @abstractmethod
10 | def v(self):
11 | pass
12 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_data_classes/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/test/test_dataToCode/test_data_classes/__init__.py
--------------------------------------------------------------------------------
/test/test_dataToCode/test_data_classes/test_attribute.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.attribute import Attribute
2 | import pytest
3 | from src.dataToCode.dataClasses.visibility import Visibility
4 |
5 | testdata = [
6 | (["a", "int", Visibility.public], ["b", "float", Visibility.private], False),
7 | (["a", "int", Visibility.public], ["b", "float", Visibility.public], False),
8 | (["a", "int", Visibility.public], ["b", "int", Visibility.private], False),
9 | (["a", "int", Visibility.public], ["b", "int", Visibility.public], False),
10 | (["a", "int", Visibility.public], ["a", "float", Visibility.private], False),
11 | (["a", "int", Visibility.public], ["a", "float", Visibility.public], False),
12 | (["a", "int", Visibility.public], ["a", "int", Visibility.private], False),
13 | (["a", "int", Visibility.public], ["a", "int", Visibility.public], True),
14 | ]
15 |
16 |
17 | @pytest.mark.parametrize("a,b,expected", testdata)
18 | def test_attribute_equal(a, b, expected):
19 | a = Attribute(a[0], a[1], a[2])
20 | b = Attribute(b[0], b[1], b[2])
21 | output = (a == b)
22 | assert output == expected
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_data_classes/test_class_data.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.attribute import Attribute
2 | import pytest
3 | from src.dataToCode.dataClasses.visibility import Visibility
4 | from src.dataToCode.dataClasses.method import Method
5 | from src.dataToCode.dataClasses.classData import ClassData
6 |
7 | def test_class_equal():
8 | method1 = Method("a")
9 | method2 = Method("a")
10 | a = ClassData("a", methods=[method1])
11 | b = ClassData("a", methods=[method2])
12 | output = a==b
13 | assert output == True
14 |
15 |
16 | def test_class_data_not_equal_name():
17 | method1 = Method("a")
18 | method2 = Method("a")
19 | a = ClassData("a", methods=[method1])
20 | b = ClassData("b", methods=[method2])
21 | output = a==b
22 | assert output == False
23 |
24 |
25 | def test_class_data_diffent_method_number():
26 | method1 = Method("a")
27 | method2 = Method("a")
28 | method3 = Method("b")
29 | a = ClassData("a", methods=[method1])
30 | b = ClassData("a", methods=[method2, method3])
31 | output = a==b
32 | assert output == False
33 |
34 |
35 | def test_class_data_equal_method():
36 | method1 = Method("a")
37 | method2 = Method("a")
38 | method3 = Method("b")
39 | method4 = Method("b")
40 | a = ClassData("a", methods=[method1, method4])
41 | b = ClassData("a", methods=[method2, method3])
42 | output = a==b
43 | assert output == True
44 |
45 |
46 | def test_class_data_not_equal_method():
47 | method1 = Method("a")
48 | method2 = Method("a")
49 | method3 = Method("b")
50 | method4 = Method("c")
51 | a = ClassData("a", methods=[method1, method4])
52 | b = ClassData("a", methods=[method2, method3])
53 | output = a==b
54 | assert output == False
55 |
56 |
57 | def test_class_data_methods_unordered():
58 | method1 = Method("a")
59 | method2 = Method("a")
60 | method3 = Method("b")
61 | method4 = Method("b")
62 | a = ClassData("a", methods=[method1, method4])
63 | b = ClassData("a", methods=[method3, method2])
64 | output = a==b
65 | assert output == False
66 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_data_classes/test_interface.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.attribute import Attribute
2 | import pytest
3 | from src.dataToCode.dataClasses.visibility import Visibility
4 | from src.dataToCode.dataClasses.method import Method
5 | from src.dataToCode.dataClasses.interface import Interface
6 |
7 | def test_interface_equal():
8 | method1 = Method("a")
9 | method2 = Method("a")
10 | a = Interface("a", methods=[method1])
11 | b = Interface("a", methods=[method2])
12 | output = a==b
13 | assert output == True
14 |
15 |
16 | def test_interface_not_equal_name():
17 | method1 = Method("a")
18 | method2 = Method("a")
19 | a = Interface("a", methods=[method1])
20 | b = Interface("b", methods=[method2])
21 | output = a==b
22 | assert output == False
23 |
24 |
25 | def test_interface_diffent_method_number():
26 | method1 = Method("a")
27 | method2 = Method("a")
28 | method3 = Method("b")
29 | a = Interface("a", methods=[method1])
30 | b = Interface("a", methods=[method2, method3])
31 | output = a==b
32 | assert output == False
33 |
34 |
35 | def test_interface_equal_method():
36 | method1 = Method("a")
37 | method2 = Method("a")
38 | method3 = Method("b")
39 | method4 = Method("b")
40 | a = Interface("a", methods=[method1, method4])
41 | b = Interface("a", methods=[method2, method3])
42 | output = a==b
43 | assert output == True
44 |
45 |
46 | def test_interface_not_equal_method():
47 | method1 = Method("a")
48 | method2 = Method("a")
49 | method3 = Method("b")
50 | method4 = Method("c")
51 | a = Interface("a", methods=[method1, method4])
52 | b = Interface("a", methods=[method2, method3])
53 | output = a==b
54 | assert output == False
55 |
56 |
57 | def test_interface_methods_unordered():
58 | method1 = Method("a")
59 | method2 = Method("a")
60 | method3 = Method("b")
61 | method4 = Method("b")
62 | a = Interface("a", methods=[method1, method4])
63 | b = Interface("a", methods=[method3, method2])
64 | output = a==b
65 | assert output == False
66 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_data_classes/test_method.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.attribute import Attribute
2 | import pytest
3 | from src.dataToCode.dataClasses.visibility import Visibility
4 | from src.dataToCode.dataClasses.method import Method
5 |
6 | def test_method_equal():
7 | a = Method("a")
8 | b = Method("a")
9 | output = (a == b)
10 | assert output == True
11 |
12 | def test_method_not_equal_name():
13 | a = Method("a")
14 | b = Method("b")
15 | output = (a == b)
16 | assert output == False
17 |
18 | def test_method_diffent_param_number():
19 | a = Method("a")
20 | parameter = Attribute("a", "int")
21 | b = Method("a", parameters=[parameter])
22 | output = (a == b)
23 | assert output == False
24 |
25 | def test_method_equal_param():
26 | parameter1 = Attribute("a", "int")
27 | parameter2 = Attribute("a", "int")
28 | a = Method("a", parameters=[parameter1])
29 | b = Method("a", parameters=[parameter2])
30 | output = (a == b)
31 | assert output == True
32 |
33 | def test_method_not_equal_param():
34 | parameter1 = Attribute("b", "int")
35 | parameter2 = Attribute("a", "int")
36 | a = Method("a", parameters=[parameter1])
37 | b = Method("a", parameters=[parameter2])
38 | output = (a == b)
39 | assert output == False
40 |
41 | def test_method_equal_params():
42 | parameter1 = Attribute("a", "int")
43 | parameter2 = Attribute("a", "int")
44 | parameter3 = Attribute("b", "int")
45 | parameter4 = Attribute("b", "int")
46 | a = Method("a", parameters=[parameter1, parameter3])
47 | b = Method("a", parameters=[parameter2, parameter4])
48 | output = (a == b)
49 | assert output == True
50 |
51 | def test_method_not_equal_params():
52 | parameter1 = Attribute("a", "int")
53 | parameter2 = Attribute("a", "int")
54 | parameter3 = Attribute("b", "int")
55 | parameter4 = Attribute("c", "int")
56 | a = Method("a", parameters=[parameter1, parameter3])
57 | b = Method("a", parameters=[parameter2, parameter4])
58 | output = (a == b)
59 | assert output == False
60 |
61 | def test_method_params_unordered():
62 | parameter1 = Attribute("a", "int")
63 | parameter2 = Attribute("a", "int")
64 | parameter3 = Attribute("b", "int")
65 | parameter4 = Attribute("b", "int")
66 | a = Method("a", parameters=[parameter1, parameter3])
67 | b = Method("a", parameters=[parameter4, parameter2])
68 | output = (a == b)
69 | assert output == False
70 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/test/test_dataToCode/test_to_java/__init__.py
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_inheritanceToCode.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.dataToCode.languages.ToJava.inheritanceToJava import InheritanceToJava
3 | from src.dataToCode.dataClasses.classData import ClassData
4 |
5 |
6 | def test_no_inheritance_equals_empty_string():
7 | assert InheritanceToJava([]).get_formatted() == ''
8 |
9 |
10 | @pytest.mark.parametrize("inheritance_name", ["name", "Car", "generic_class",
11 | "long_long_long_long_long_long_long"])
12 | def test_single_inheritance_with_letters_only_and_no_space(inheritance_name):
13 | inheritance = ClassData(inheritance_name)
14 | inheritance_to_code = InheritanceToJava([inheritance])
15 | assert inheritance_to_code.get_formatted() == ' extends ' + inheritance_name
16 |
17 |
18 | @pytest.mark.parametrize("name_one, name_two", [("Client", "Father"),
19 | ("generic_class", "not_too_long")])
20 | def test_double_inheritance_with_letters_only_and_no_space(name_one, name_two):
21 | inheritance_one = ClassData(name_one)
22 | inheritance_two = ClassData(name_two)
23 | inheritance_to_code = InheritanceToJava([inheritance_one, inheritance_two])
24 | assert inheritance_to_code.get_formatted() == ' extends ' + name_one + ", " + name_two
25 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_interface_to_java.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.interface import Interface
2 | from src.dataToCode.languages.ToJava.interfaceToJava import InterfaceToJava
3 | from src.dataToCode.dataClasses.method import Method
4 |
5 |
6 | def test_convert_interface():
7 | method = Method("example")
8 | interface = Interface("interface_example", [method])
9 | interface_java = InterfaceToJava(interface)
10 | output = interface_java.convert()
11 | expected = "import java.util.*;\n\npublic interface interface_example {\n\n\tpublic void example();\n}"
12 | assert output == expected
13 |
14 | def test_convert_interface_wit_implement_interface():
15 | method = Method("example")
16 | interface1 = Interface("interface1", [method])
17 | interface2 = Interface("interface2", [method], interfaces=[interface1])
18 | interface_java2 = InterfaceToJava(interface2)
19 | output = interface_java2.convert()
20 | expected = (f"import java.util.*;\n\npublic interface interface2 "
21 | f"implements interface1 {{\n\n\tpublic void example();\n}}")
22 | assert output == expected
23 |
24 | def test_convert_interface_wit_implement_interfacee():
25 | method = Method("example")
26 | interface1 = Interface("interface1", [method])
27 | interface3 = Interface("interface3", [method])
28 | interface2 = Interface("interface2", [method], interfaces=[interface1,
29 | interface3])
30 | interface_java2 = InterfaceToJava(interface2)
31 | output = interface_java2.convert()
32 | expected = (f"import java.util.*;\n\npublic interface interface2 "
33 | f"implements interface1, interface3 {{\n\n\tpublic void example();\n}}")
34 | assert output == expected
35 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_method_to_java.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.dataToCode.languages.ToJava.methodToJava import MethodToJava
3 | from src.dataToCode.dataClasses.method import Method
4 | from src.dataToCode.dataClasses.visibility import Visibility
5 | from src.dataToCode.dataClasses.attribute import Attribute
6 | from src.dataToCode.dataClasses.modifier import Modifier
7 | from typing import List
8 |
9 |
10 | def test_formatted_method():
11 | method = Method("example")
12 | method_to_java = MethodToJava([method], True)
13 | assert method_to_java.get_formatted_methods() == "\tpublic void example();"
14 |
15 | def test_formatted_methods():
16 | method1 = Method("example")
17 | method2 = Method("example2")
18 | method_to_java = MethodToJava([method1, method2], True)
19 | assert method_to_java.get_formatted_methods() == (f"\tpublic void example();"
20 | f"\n\n\tpublic void"
21 | f" example2();")
22 |
23 | visibility_data = [
24 | (Visibility.public, "\tpublic void example();"),
25 | (Visibility.private, "\tprivate void example();"),
26 | (Visibility.package, "\tpackage void example();"),
27 | (Visibility.protected, "\tprotected void example();"),
28 | ]
29 | @pytest.mark.parametrize("visibility, expected", visibility_data)
30 | def test_formatted_method_visibility(visibility, expected):
31 | method = Method("example", visibility=visibility)
32 | method_to_java = MethodToJava([method], True)
33 | assert method_to_java.get_formatted_methods() == expected
34 |
35 |
36 | type_data = [
37 | ("int", "\tpublic int example();"),
38 | ("float", "\tpublic float example();"),
39 | ]
40 | @pytest.mark.parametrize("type_name, expected", type_data)
41 | def test_formatted_method_type(type_name, expected):
42 | method = Method("example", return_type=type_name)
43 | method_to_java = MethodToJava([method], True)
44 | assert method_to_java.get_formatted_methods() == expected
45 |
46 |
47 | parameter_data = [
48 | ([["a", "int"]], "\tpublic void example(int a);"),
49 | ([["a", "int"], ["b", "float"]], "\tpublic void example(int a, float b);"),
50 | ]
51 | @pytest.mark.parametrize("parameters, expected", parameter_data)
52 | def test_formatted_method_parameters(parameters, expected):
53 | parameter_list: List[Attribute] = []
54 | for parameter in parameters:
55 | name, return_type = parameter
56 | new_parameter = Attribute(name, return_type)
57 | parameter_list.append(new_parameter)
58 |
59 | method = Method("example", parameters=parameter_list)
60 | method_to_java = MethodToJava([method], True)
61 | assert method_to_java.get_formatted_methods() == expected
62 |
63 |
64 | body_data = [
65 | (True, "\tpublic void example();"),
66 | (False, (f"\tpublic void example()"
67 | f" {{\n\t\tthrow new UnsupportedOperationException();\n\t}}")),
68 | ]
69 | @pytest.mark.parametrize("is_from_interface, expected", body_data)
70 | def test_formatted_method_body(is_from_interface, expected):
71 | method = Method("example")
72 | method_to_java = MethodToJava([method], is_from_interface)
73 | assert method_to_java.get_formatted_methods() == expected
74 |
75 |
76 | modifier_data = [
77 | (Modifier.abstract, "\tpublic abstract void example();"),
78 | (Modifier.override, "\t@override\n\tpublic void example();"),
79 | (Modifier.static, "\tpublic static void example();"),
80 | ]
81 | @pytest.mark.parametrize("modifier, expected", modifier_data)
82 | def test_formatted_method_modifier(modifier, expected):
83 | method = Method("example", modifier=modifier)
84 | method_to_java = MethodToJava([method], True)
85 | print(method_to_java.get_formatted_methods())
86 | assert method_to_java.get_formatted_methods() == expected
87 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_name_to_java.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.dataToCode.languages.ToJava.fileNameToJava import FileNameToJava
3 | from src.dataToCode.dataClasses.classData import ClassData
4 | from src.dataToCode.dataClasses.interface import Interface
5 | from src.dataToCode.dataClasses.method import Method
6 |
7 |
8 | def test_single_name_class():
9 | class_data = ClassData("Name")
10 | file_name_java = FileNameToJava(class_data)
11 | assert "Name.java" == file_name_java.get_file_name()
12 |
13 |
14 | def test_single_name_interface():
15 | method = Method("test")
16 | interface_data = Interface("StrongName", methods=[method])
17 | file_name_java = FileNameToJava(interface_data)
18 | assert "StrongName.java" == file_name_java.get_file_name()
19 |
20 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/test/test_dataToCode/test_to_java/test_system/__init__.py
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/strategy_example/.Context.java.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/test/test_dataToCode/test_to_java/test_system/strategy_example/.Context.java.swp
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/strategy_example/ConcreteStrategyA.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class ConcreteStrategyA implements Strategy {
4 |
5 | public ArrayList doAlgorithm(ArrayList data) {
6 | throw new UnsupportedOperationException();
7 | }
8 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/strategy_example/ConcreteStrategyB.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class ConcreteStrategyB implements Strategy {
4 |
5 | public ArrayList doAlgorithm(ArrayList data) {
6 | throw new UnsupportedOperationException();
7 | }
8 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/strategy_example/Context.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class Context {
4 |
5 | public Strategy strategy;
6 |
7 | public void doSomeBusinessLogic() {
8 | throw new UnsupportedOperationException();
9 | }
10 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/strategy_example/Strategy.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public interface Strategy {
4 |
5 | public ArrayList doAlgorithm(ArrayList data);
6 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/strategy_example/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/test/test_dataToCode/test_to_java/test_system/strategy_example/__init__.py
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/test_system.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | import os
3 | import filecmp
4 | import subprocess
5 |
6 | from src.dataToCode.dataClasses.attribute import Attribute
7 | from src.dataToCode.dataClasses.classData import ClassData
8 | from src.dataToCode.dataClasses.interface import Interface
9 | from src.dataToCode.dataClasses.method import Method
10 | from src.dataToCode.write_files import write_files
11 | from src.dataToCode.dataClasses.visibility import Visibility
12 | from src.dataToCode.dataClasses.modifier import Modifier
13 |
14 | def test_strategy_example_java(tmpdir):
15 | def create_do_algorithm():
16 | attribute = Attribute("data", "ArrayList")
17 | method = Method("doAlgorithm", parameters=[attribute],
18 | return_type="ArrayList")
19 | return method
20 |
21 | def create_strategy():
22 | method = create_do_algorithm()
23 | strategy = Interface("Strategy", methods=[method])
24 | return strategy
25 |
26 | def create_context():
27 | attribute = Attribute("strategy", "Strategy",
28 | visibility=Visibility.public)
29 | method = Method("doSomeBusinessLogic")
30 | context = ClassData("Context", methods=[method], fields=[attribute])
31 | return context
32 |
33 | def create_concrete_a():
34 | method = create_do_algorithm()
35 | strategy = create_strategy()
36 | concrete_a = ClassData("ConcreteStrategyA", methods=[method],
37 | implementations=[strategy])
38 | return concrete_a
39 |
40 | def create_concrete_b():
41 | method = create_do_algorithm()
42 | strategy = create_strategy()
43 | concrete_b = ClassData("ConcreteStrategyB", methods=[method],
44 | implementations=[strategy])
45 | return concrete_b
46 |
47 | objects = [create_strategy(), create_context(), create_concrete_a(),
48 | create_concrete_b()]
49 | write_files(objects, tmpdir, "java")
50 | files_path = ["Strategy.java", "Context.java", "ConcreteStrategyA.java",
51 | "ConcreteStrategyB.java"]
52 | strategy_path = os.path.abspath(os.path.join(__file__,
53 | "../strategy_example"))
54 | generated_path = [os.path.join(tmpdir, x) for x in files_path]
55 | truth_path = [os.path.join(strategy_path, x) for x in files_path]
56 |
57 | for truth_file_path, generated_file_path in zip(truth_path,
58 | generated_path):
59 |
60 | print(filecmp.cmp(truth_file_path, generated_file_path))
61 | assert filecmp.cmp(truth_file_path, generated_file_path)
62 |
63 |
64 | def test_strategy_xml(tmpdir):
65 |
66 | main_path = os.path.abspath(os.path.join(__file__,"..", "..", "..", "..", "..", "main.py"))
67 | xml_path = os.path.abspath(os.path.join(__file__,"..", "..", "..", "..", "strategy.xml"))
68 | subprocess.run(["python3", main_path,
69 | f"--xml_file={xml_path}", f"--code_path={tmpdir}",
70 | "--language=java"])
71 | files_path = ["Strategy.java", "Context.java",
72 | "ConcreteStrategyA.java",
73 | "ConcreteStrategyB.java"]
74 | strategy_path = os.path.abspath(os.path.join(__file__,
75 | "../strategy_example"))
76 | generated_path = [os.path.join(tmpdir, x) for x in files_path]
77 | truth_path = [os.path.join(strategy_path, x) for x in files_path]
78 |
79 | for truth_file_path, generated_file_path in zip(truth_path,
80 | generated_path):
81 | assert filecmp.cmp(truth_file_path, generated_file_path)
82 |
83 | def test_ultimate_example_java(tmpdir):
84 |
85 | def create_spell():
86 | method = Method("doEffect")
87 | interface = Interface("ISpell", methods=[method])
88 | return interface
89 |
90 | def create_food():
91 | method = Method("getNutrients", return_type="String")
92 | interface = Interface("IFood", methods=[method])
93 | return interface
94 |
95 | def create_weapon():
96 | name = Attribute("name", "String", visibility=Visibility.public)
97 | age = Attribute("age", "int", visibility=Visibility.private)
98 | attribute = Attribute("attribute", "Attribute",
99 | visibility=Visibility.protected)
100 |
101 | getAttribute = Method("getAttribute", return_type="Attribute")
102 | setAttribute = Method("setAttribute", return_type="void",
103 | parameters=[attribute])
104 | weapon = ClassData("Weapon", methods=[getAttribute, setAttribute],
105 | fields=[name, age, attribute])
106 | return weapon
107 |
108 | def create_attribute():
109 | field1 = Attribute("value", "float", visibility=Visibility.public)
110 | field2 = Attribute("multiplier", "float", visibility=Visibility.public)
111 | attribute = ClassData("Attribute", fields=[field1, field2])
112 | return attribute
113 |
114 | def create_walk():
115 | method = Method("walk")
116 | interface = Interface("IWalk", methods=[method])
117 | return interface
118 |
119 | def create_attack():
120 | damage = Attribute("damage", "int", visibility=Visibility.public)
121 | method = Method("attack", parameters=[damage])
122 | interface = Interface("IAttack", methods=[method])
123 | return interface
124 |
125 | def create_orc():
126 | name = Attribute("name", "String", visibility=Visibility.public)
127 | age = Attribute("age", "int", visibility=Visibility.private)
128 | weapon = Attribute("weapon", "Weapon", visibility=Visibility.private)
129 | damage = Attribute("damage", "int", visibility=Visibility.public)
130 | hours = Attribute("hours", "int", visibility=Visibility.public)
131 |
132 | walk = create_walk()
133 | attack_interface = create_attack()
134 |
135 | attack_method = Method("attack", parameters=[damage])
136 | sleep = Method("sleep", parameters=[hours],
137 | visibility=Visibility.private)
138 | walk_method = Method("walk", parameters=[])
139 |
140 | orc = ClassData("Orc", methods=[attack_method, walk_method, sleep],
141 | fields=[name, age, weapon],
142 | implementations=[attack_interface, walk])
143 | return orc
144 |
145 | def create_high_orc():
146 | damage = Attribute("damage", "int", visibility=Visibility.public)
147 | hours = Attribute("hours", "int", visibility=Visibility.public)
148 | spell = Attribute("spell", "ISpell", visibility=Visibility.protected)
149 |
150 | attack = Method("attack", parameters=[damage],
151 | modifier=Modifier.override)
152 | sleep = Method("sleep", parameters=[hours],
153 | visibility=Visibility.private,
154 | modifier=Modifier.override)
155 |
156 | orc = create_orc()
157 |
158 | high_orc = ClassData("HighOrc", methods=[attack, sleep],
159 | fields=[spell], inheritances=[orc])
160 | return high_orc
161 |
162 | def create_fat_orc():
163 | food = Attribute("food", "IFood", visibility=Visibility.public)
164 |
165 | eat = Method("eat", parameters=[food])
166 |
167 | orc = create_orc()
168 |
169 | fat_orc = ClassData("FatOrc", methods=[eat],
170 | inheritances=[orc])
171 | return fat_orc
172 |
173 | def create_obese_orc():
174 | food = Attribute("food", "IFood", visibility=Visibility.public)
175 | heart_attack = Attribute("heartAttackChance", "int",
176 | visibility=Visibility.public)
177 |
178 | eat = Method("eat", parameters=[food], modifier=Modifier.override)
179 |
180 | fat_orc = create_fat_orc()
181 |
182 | obese_orc = ClassData("ObeseOrc", methods=[eat],
183 | fields=[heart_attack], inheritances=[fat_orc])
184 | return obese_orc
185 |
186 | objects = [create_spell(), create_food(), create_weapon(),
187 | create_attribute(), create_attack(), create_walk(),
188 | create_orc(), create_high_orc(), create_fat_orc(),
189 | create_obese_orc()]
190 | write_files(objects, tmpdir, "java")
191 |
192 | ultimate_path = os.path.abspath(os.path.join(__file__,
193 | "../ultimate_example"))
194 | all_files_path = os.listdir(ultimate_path)
195 |
196 | files_path = []
197 | for file_path in all_files_path:
198 | if file_path.endswith(".java"):
199 | files_path.append(file_path)
200 |
201 | generated_path = [os.path.join(tmpdir, x) for x in files_path]
202 | truth_path = [os.path.join(ultimate_path, x) for x in files_path]
203 |
204 | for truth_file_path, generated_file_path in zip(truth_path,
205 | generated_path):
206 | assert filecmp.cmp(truth_file_path, generated_file_path)
207 |
208 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/ultimate_example/Attribute.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class Attribute {
4 |
5 | public float value;
6 | public float multiplier;
7 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/ultimate_example/FatOrc.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class FatOrc extends Orc {
4 |
5 | public void eat(IFood food) {
6 | throw new UnsupportedOperationException();
7 | }
8 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/ultimate_example/HighOrc.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class HighOrc extends Orc {
4 |
5 | protected ISpell spell;
6 |
7 | @override
8 | public void attack(int damage) {
9 | throw new UnsupportedOperationException();
10 | }
11 |
12 | @override
13 | private void sleep(int hours) {
14 | throw new UnsupportedOperationException();
15 | }
16 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/ultimate_example/IAttack.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public interface IAttack {
4 |
5 | public void attack(int damage);
6 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/ultimate_example/IFood.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public interface IFood {
4 |
5 | public String getNutrients();
6 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/ultimate_example/ISpell.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public interface ISpell {
4 |
5 | public void doEffect();
6 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/ultimate_example/IWalk.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public interface IWalk {
4 |
5 | public void walk();
6 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/ultimate_example/ObeseOrc.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class ObeseOrc extends FatOrc {
4 |
5 | public int heartAttackChance;
6 |
7 | @override
8 | public void eat(IFood food) {
9 | throw new UnsupportedOperationException();
10 | }
11 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/ultimate_example/Orc.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class Orc implements IAttack, IWalk {
4 |
5 | public String name;
6 | private int age;
7 | private Weapon weapon;
8 |
9 | public void attack(int damage) {
10 | throw new UnsupportedOperationException();
11 | }
12 |
13 | public void walk() {
14 | throw new UnsupportedOperationException();
15 | }
16 |
17 | private void sleep(int hours) {
18 | throw new UnsupportedOperationException();
19 | }
20 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_java/test_system/ultimate_example/Weapon.java:
--------------------------------------------------------------------------------
1 | import java.util.*;
2 |
3 | public class Weapon {
4 |
5 | public String name;
6 | private int age;
7 | protected Attribute attribute;
8 |
9 | public Attribute getAttribute() {
10 | throw new UnsupportedOperationException();
11 | }
12 |
13 | public void setAttribute(Attribute attribute) {
14 | throw new UnsupportedOperationException();
15 | }
16 | }
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/test/test_dataToCode/test_to_python/__init__.py
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_fileNameToPython.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from src.dataToCode.dataClasses.classData import ClassData
4 | from src.dataToCode.dataClasses.interface import Interface
5 | from src.dataToCode.languages.toPython.fileNameToPython import FileNameToPython
6 |
7 | data = [
8 | ("Orc", "orc.py"),
9 | ("HighOrc", "high_orc.py"),
10 | ("PrettyLongClassName", "pretty_long_class_name.py")
11 | ]
12 |
13 |
14 | @pytest.mark.parametrize("data_name, expected", data)
15 | def test_file_names_with_class(data_name, expected):
16 | assert FileNameToPython(ClassData(data_name)).get_file_name() == expected
17 |
18 | @pytest.mark.parametrize("data_name, expected", data)
19 | def test_file_names_with_interface(data_name, expected):
20 | assert FileNameToPython(Interface(data_name, [])).get_file_name() == expected
21 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_initToPython.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.dataToCode.dataClasses.attribute import Attribute
3 | from src.dataToCode.dataClasses.visibility import Visibility
4 | from src.dataToCode.languages.toPython.initToPython import InitToPython
5 |
6 |
7 | def test_no_attributes_init():
8 | expected = "\tdef __init__(self):\n\t\tpass\n"
9 | assert InitToPython([]).get_formatted() == expected
10 |
11 |
12 | def test_init_with_one_private_attribute():
13 | att = Attribute("example", "void")
14 | expected = f"\tdef __init__(self, example):" \
15 | f"\n\t\tself.__example = example\n"
16 | assert InitToPython([att]).get_formatted() == expected
17 |
18 |
19 | def test_init_with_two_public_attributes():
20 | att1 = Attribute("example1", "void", Visibility.public)
21 | att2 = Attribute("example2", "void", Visibility.public)
22 | expected = (f"\tdef __init__(self, example1, example2):"
23 | f"\n\t\tself.example1 = example1"
24 | f"\n\t\tself.example2 = example2\n")
25 | assert InitToPython([att1, att2]).get_formatted() == expected
26 |
27 |
28 | def test_init_with_three_attributes_with_different_visibilities():
29 | att1 = Attribute("example1", "void", Visibility.public)
30 | att2 = Attribute("example2", "void", Visibility.protected)
31 | att3 = Attribute("example3", "void", Visibility.private)
32 | expected = (f"\tdef __init__(self, example1, example2, example3):"
33 | f"\n\t\tself.example1 = example1"
34 | f"\n\t\tself._example2 = example2"
35 | f"\n\t\tself.__example3 = example3\n")
36 | assert InitToPython([att1, att2, att3]).get_formatted() == expected
37 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_methodToPython.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.dataToCode.languages.toPython.methodToPython import MethodToPython
3 | from src.dataToCode.dataClasses.method import Method
4 | from src.dataToCode.dataClasses.visibility import Visibility
5 | from src.dataToCode.dataClasses.attribute import Attribute
6 | from src.dataToCode.dataClasses.modifier import Modifier
7 | from typing import List
8 |
9 |
10 | def test_formatted_method():
11 | method = Method("example")
12 | method_to_python = MethodToPython([method], False)
13 | assert method_to_python.get_formatted_methods() == (f"\tdef example(self):\n"
14 | f"\t\tpass")
15 |
16 |
17 | def test_formatted_methods():
18 | method1 = Method("example")
19 | method2 = Method("example2")
20 | method_to_python = MethodToPython([method1, method2], False)
21 | expected_one = (f"\tdef example(self):\n"
22 | f"\t\tpass")
23 | expected_two = (f"\tdef example2(self):\n"
24 | f"\t\tpass")
25 | assert method_to_python.get_formatted_methods() == expected_one + "\n\n" + expected_two
26 |
27 |
28 | visibility_data = [
29 | (Visibility.public, "\tdef example(self):\n\t\tpass"),
30 | (Visibility.private, "\tdef __example(self):\n\t\tpass"),
31 | (Visibility.package, "\tdef example(self):\n\t\tpass"),
32 | (Visibility.protected, "\tdef _example(self):\n\t\tpass"),
33 | ]
34 |
35 |
36 | @pytest.mark.parametrize("visibility, expected", visibility_data)
37 | def test_formatted_method_visibility(visibility, expected):
38 | method = Method("example", visibility=visibility)
39 | method_to_python = MethodToPython([method], False)
40 | assert method_to_python.get_formatted_methods() == expected
41 |
42 |
43 | parameter_data = [
44 | ([["a", "int"]], "\tdef example(self, a):\n\t\tpass"),
45 | ([["a", "int"], ["b", "float"]], "\tdef example(self, a, b):\n\t\tpass"),
46 | ]
47 |
48 |
49 | @pytest.mark.parametrize("parameters, expected", parameter_data)
50 | def test_formatted_method_parameters(parameters, expected):
51 | parameter_list: List[Attribute] = []
52 | for parameter in parameters:
53 | name, return_type = parameter
54 | new_parameter = Attribute(name, return_type)
55 | parameter_list.append(new_parameter)
56 |
57 | method = Method("example", parameters=parameter_list)
58 | method_to_python = MethodToPython([method], False)
59 | assert method_to_python.get_formatted_methods() == expected
60 |
61 |
62 | body_data = [
63 | (True, "\t@abstractmethod\n\tdef example(self):\n\t\tpass"),
64 | (False, "\tdef example(self):\n\t\tpass"),
65 | ]
66 |
67 |
68 | @pytest.mark.parametrize("is_from_interface, expected", body_data)
69 | def test_formatted_method_body(is_from_interface, expected):
70 | method = Method("example")
71 | method_to_python = MethodToPython([method], is_from_interface)
72 | assert method_to_python.get_formatted_methods() == expected
73 |
74 |
75 | modifier_data = [
76 | (Modifier.abstract, "\t@abstractmethod\n\tdef example(self):\n\t\tpass"),
77 | (Modifier.override, "\tdef example(self):\n\t\tpass"),
78 | (Modifier.static, "\t@staticmethod\n\tdef example():\n\t\tpass"),
79 | ]
80 |
81 |
82 | @pytest.mark.parametrize("modifier, expected", modifier_data)
83 | def test_formatted_method_modifier(modifier, expected):
84 | method = Method("example", modifier=modifier)
85 | method_to_python = MethodToPython([method], False)
86 | print(method_to_python.get_formatted_methods())
87 | assert method_to_python.get_formatted_methods() == expected
88 |
89 | def test_static_protected_method_with_parameters():
90 | param = Attribute("name", "String")
91 | method = Method("example", "int", [param],
92 | Visibility.protected, Modifier.static)
93 | method_to_python = MethodToPython([method], False)
94 | expected = "\t@staticmethod\n\tdef _example(name):\n\t\tpass"
95 | assert method_to_python.get_formatted_methods() == expected
96 |
97 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/test/test_dataToCode/test_to_python/test_system/__init__.py
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/strategy_example/concrete_strategy_a.py:
--------------------------------------------------------------------------------
1 | from strategy import Strategy
2 |
3 |
4 | class ConcreteStrategyA(Strategy):
5 |
6 | def __init__(self):
7 | pass
8 |
9 | def doAlgorithm(self, data):
10 | pass
11 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/strategy_example/concrete_strategy_b.py:
--------------------------------------------------------------------------------
1 | from strategy import Strategy
2 |
3 |
4 | class ConcreteStrategyB(Strategy):
5 |
6 | def __init__(self):
7 | pass
8 |
9 | def doAlgorithm(self, data):
10 | pass
11 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/strategy_example/context.py:
--------------------------------------------------------------------------------
1 | class Context():
2 |
3 | def __init__(self, strategy):
4 | self.strategy = strategy
5 |
6 | def doSomeBusinessLogic(self):
7 | pass
8 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/strategy_example/strategy.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class Strategy(ABC):
5 |
6 | @abstractmethod
7 | def doAlgorithm(self, data):
8 | pass
9 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/test_system.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | import os
3 | import filecmp
4 | import subprocess
5 |
6 | from src.dataToCode.dataClasses.attribute import Attribute
7 | from src.dataToCode.dataClasses.classData import ClassData
8 | from src.dataToCode.dataClasses.interface import Interface
9 | from src.dataToCode.dataClasses.method import Method
10 | from src.dataToCode.write_files import write_files
11 | from src.dataToCode.dataClasses.visibility import Visibility
12 | from src.dataToCode.dataClasses.modifier import Modifier
13 |
14 |
15 | def test_strategy_example(tmpdir):
16 |
17 | def create_do_algorithm():
18 | attribute = Attribute("data", "str")
19 | method = Method("doAlgorithm", parameters=[attribute])
20 | return method
21 |
22 | def create_strategy():
23 | method = create_do_algorithm()
24 | strategy = Interface("Strategy", methods=[method])
25 | return strategy
26 |
27 | def create_context():
28 | attribute = Attribute("strategy", "Strategy",
29 | visibility=Visibility.public)
30 | method = Method("doSomeBusinessLogic")
31 | context = ClassData("Context", methods=[method], fields=[attribute])
32 | return context
33 |
34 | def create_concrete_a():
35 | method = create_do_algorithm()
36 | strategy = create_strategy()
37 | concrete_a = ClassData("ConcreteStrategyA", methods=[method],
38 | implementations=[strategy])
39 | return concrete_a
40 |
41 | def create_concrete_b():
42 | method = create_do_algorithm()
43 | strategy = create_strategy()
44 | concrete_b = ClassData("ConcreteStrategyB", methods=[method],
45 | implementations=[strategy])
46 | return concrete_b
47 |
48 | objects = [create_strategy(), create_context(), create_concrete_a(),
49 | create_concrete_b()]
50 | write_files(objects, tmpdir, "python")
51 | files_path = ["strategy.py", "context.py", "concrete_strategy_a.py",
52 | "concrete_strategy_b.py"]
53 | strategy_path = os.path.abspath(os.path.join(__file__,
54 | "../strategy_example"))
55 | generated_path = [os.path.join(tmpdir, x) for x in files_path]
56 | truth_path = [os.path.join(strategy_path, x) for x in files_path]
57 |
58 | for truth_file_path, generated_file_path in zip(truth_path,
59 | generated_path):
60 | assert filecmp.cmp(truth_file_path, generated_file_path)
61 |
62 | def test_strategy_xml(tmpdir):
63 |
64 | main_path = os.path.abspath(os.path.join(__file__,"../../../../../main.py"))
65 | xml_path = os.path.abspath(os.path.join(__file__,"../../../../strategy.xml"))
66 | subprocess.run(["python3", main_path,
67 | f"--xml_file={xml_path}", f"--code_path={tmpdir}",
68 | "--language=python"])
69 | files_path = ["strategy.py", "context.py", "concrete_strategy_a.py",
70 | "concrete_strategy_b.py"]
71 | strategy_path = os.path.abspath(os.path.join(__file__,
72 | "../strategy_example"))
73 | generated_path = [os.path.join(tmpdir, x) for x in files_path]
74 | truth_path = [os.path.join(strategy_path, x) for x in files_path]
75 |
76 | for truth_file_path, generated_file_path in zip(truth_path,
77 | generated_path):
78 | assert filecmp.cmp(truth_file_path, generated_file_path)
79 |
80 | def test_ultimate_example(tmpdir):
81 |
82 | def create_spell():
83 | method = Method("doEffect")
84 | interface = Interface("ISpell", methods=[method])
85 | return interface
86 |
87 | def create_food():
88 | method = Method("getNutrients", return_type="str")
89 | interface = Interface("IFood", methods=[method])
90 | return interface
91 |
92 | def create_weapon():
93 | name = Attribute("name", "str", visibility=Visibility.public)
94 | age = Attribute("age", "int", visibility=Visibility.private)
95 | attribute = Attribute("attribute", "Attribute",
96 | visibility=Visibility.protected)
97 |
98 | getAttribute = Method("getAttribute", return_type="Attribute")
99 | setAttribute = Method("setAttribute", return_type="void",
100 | parameters=[attribute])
101 | weapon = ClassData("Weapon", methods=[getAttribute, setAttribute],
102 | fields=[name, age, attribute])
103 | return weapon
104 |
105 | def create_attribute():
106 | method = Method("method")
107 | field = Attribute("field", "Type", visibility=Visibility.public)
108 | attribute = ClassData("Attribute", methods=[method],
109 | fields=[field])
110 | return attribute
111 |
112 | def create_walk():
113 | method = Method("walk")
114 | interface = Interface("IWalk", methods=[method])
115 | return interface
116 |
117 | def create_attack():
118 | damage = Attribute("damage", "int", visibility=Visibility.public)
119 | method = Method("attack", parameters=[damage])
120 | interface = Interface("IAttack", methods=[method])
121 | return interface
122 |
123 | def create_orc():
124 | name = Attribute("name", "str", visibility=Visibility.public)
125 | age = Attribute("age", "int", visibility=Visibility.private)
126 | damage = Attribute("damage", "int", visibility=Visibility.public)
127 | hours = Attribute("hours", "int", visibility=Visibility.public)
128 |
129 | walk = create_walk()
130 | attack_interface = create_attack()
131 |
132 | attack_method = Method("attack", parameters=[damage])
133 | sleep = Method("sleep", parameters=[hours],
134 | visibility=Visibility.private)
135 |
136 | orc = ClassData("Orc", methods=[attack_method, sleep],
137 | fields=[name, age],
138 | implementations=[attack_interface, walk])
139 | return orc
140 |
141 | def create_high_orc():
142 | damage = Attribute("damage", "int", visibility=Visibility.public)
143 | hours = Attribute("hours", "int", visibility=Visibility.public)
144 | spell = Attribute("spell", "ISpell", visibility=Visibility.public)
145 |
146 | attack = Method("attack", parameters=[damage],
147 | modifier=Modifier.override)
148 | sleep = Method("sleep", parameters=[hours],
149 | visibility=Visibility.private,
150 | modifier=Modifier.override)
151 |
152 | orc = create_orc()
153 |
154 | high_orc = ClassData("HighOrc", methods=[attack, sleep],
155 | fields=[spell], inheritances=[orc])
156 | return high_orc
157 |
158 | def create_fat_orc():
159 | food = Attribute("food", "IFood", visibility=Visibility.public)
160 |
161 | eat = Method("eat", parameters=[food])
162 |
163 | orc = create_orc()
164 |
165 | fat_orc = ClassData("FatOrc", methods=[eat],
166 | inheritances=[orc])
167 | return fat_orc
168 |
169 | def create_obese_orc():
170 | food = Attribute("food", "IFood", visibility=Visibility.public)
171 | heart_attack = Attribute("heartAttackChance", "int",
172 | visibility=Visibility.public)
173 |
174 | eat = Method("eat", parameters=[food], modifier=Modifier.override)
175 |
176 | fat_orc = create_fat_orc()
177 |
178 | obese_orc = ClassData("ObeseOrc", methods=[eat],
179 | fields=[heart_attack], inheritances=[fat_orc])
180 | return obese_orc
181 |
182 | objects = [create_spell(), create_food(), create_weapon(),
183 | create_attribute(), create_attack(), create_walk(),
184 | create_orc(), create_high_orc(), create_fat_orc(),
185 | create_obese_orc()]
186 | write_files(objects, tmpdir, "python")
187 |
188 | ultimate_path = os.path.abspath(os.path.join(__file__,
189 | "../ultimate_example"))
190 | all_files_path = os.listdir(ultimate_path)
191 |
192 | files_path = []
193 | for file_path in all_files_path:
194 | if file_path.endswith(".py"):
195 | files_path.append(file_path)
196 |
197 | generated_path = [os.path.join(tmpdir, x) for x in files_path]
198 | truth_path = [os.path.join(ultimate_path, x) for x in files_path]
199 |
200 | for truth_file_path, generated_file_path in zip(truth_path,
201 | generated_path):
202 | assert filecmp.cmp(truth_file_path, generated_file_path)
203 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/ultimate_example/attribute.py:
--------------------------------------------------------------------------------
1 | class Attribute():
2 |
3 | def __init__(self, field):
4 | self.field = field
5 |
6 | def method(self):
7 | pass
8 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/ultimate_example/fat_orc.py:
--------------------------------------------------------------------------------
1 | from orc import Orc
2 |
3 |
4 | class FatOrc(Orc):
5 |
6 | def __init__(self):
7 | pass
8 |
9 | def eat(self, food):
10 | pass
11 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/ultimate_example/high_orc.py:
--------------------------------------------------------------------------------
1 | from orc import Orc
2 |
3 |
4 | class HighOrc(Orc):
5 |
6 | def __init__(self, spell):
7 | self.spell = spell
8 |
9 | def attack(self, damage):
10 | pass
11 |
12 | def __sleep(self, hours):
13 | pass
14 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/ultimate_example/i_attack.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class IAttack(ABC):
5 |
6 | @abstractmethod
7 | def attack(self, damage):
8 | pass
9 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/ultimate_example/i_food.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class IFood(ABC):
5 |
6 | @abstractmethod
7 | def getNutrients(self):
8 | pass
9 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/ultimate_example/i_spell.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class ISpell(ABC):
5 |
6 | @abstractmethod
7 | def doEffect(self):
8 | pass
9 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/ultimate_example/i_walk.py:
--------------------------------------------------------------------------------
1 | from abc import ABC, abstractmethod
2 |
3 |
4 | class IWalk(ABC):
5 |
6 | @abstractmethod
7 | def walk(self):
8 | pass
9 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/ultimate_example/obese_orc.py:
--------------------------------------------------------------------------------
1 | from fat_orc import FatOrc
2 |
3 |
4 | class ObeseOrc(FatOrc):
5 |
6 | def __init__(self, heartAttackChance):
7 | self.heartAttackChance = heartAttackChance
8 |
9 | def eat(self, food):
10 | pass
11 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/ultimate_example/orc.py:
--------------------------------------------------------------------------------
1 | from i_attack import IAttack
2 | from i_walk import IWalk
3 |
4 |
5 | class Orc(IAttack, IWalk):
6 |
7 | def __init__(self, name, age):
8 | self.name = name
9 | self.__age = age
10 |
11 | def attack(self, damage):
12 | pass
13 |
14 | def __sleep(self, hours):
15 | pass
16 |
17 | def walk(self):
18 | pass
19 |
--------------------------------------------------------------------------------
/test/test_dataToCode/test_to_python/test_system/ultimate_example/weapon.py:
--------------------------------------------------------------------------------
1 | class Weapon():
2 |
3 | def __init__(self, name, age, attribute):
4 | self.name = name
5 | self.__age = age
6 | self._attribute = attribute
7 |
8 | def getAttribute(self):
9 | pass
10 |
11 | def setAttribute(self, attribute):
12 | pass
13 |
--------------------------------------------------------------------------------
/test/test_dataToCode/tests_examples/test_classToJava.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.interface import Interface
2 | from src.dataToCode.dataClasses.method import Method
3 | from src.dataToCode.dataClasses.attribute import Attribute
4 | from src.dataToCode.dataClasses.classData import ClassData
5 | from src.dataToCode.languages.ToJava.classToJava import ClassToJava
6 | from src.dataToCode.dataClasses.modifier import Modifier
7 | from src.dataToCode.dataClasses.visibility import Visibility
8 | import os.path as path
9 |
10 | examples_folder = path.abspath(
11 | path.join(__file__, "../../code_examples/java/"))
12 |
13 |
14 | def test_java_example_1():
15 | att1 = Attribute("name", "String", Visibility.public)
16 | att2 = Attribute("age", "int", Visibility.private)
17 |
18 | method1 = Method("bark", "void", [], Visibility.public)
19 | param1 = Attribute("byAge", "int", Visibility.public)
20 | method2 = Method("growUp", "bool", [param1], Visibility.private)
21 | dog_class = ClassData("Dog", [att1, att2], [method1, method2])
22 |
23 | with open(path.join(examples_folder, "java_example_1.txt"), 'r') as java_example:
24 | expected = java_example.read()
25 |
26 | result = ClassToJava(dog_class).convert()
27 | assert result == expected
28 |
29 |
30 | def test_java_example_2():
31 | param1 = Attribute("damage", "int")
32 | param2 = Attribute("entity", "Entity")
33 | param3 = Attribute("bonus", "Bonus")
34 | method1 = Method("attack", "void", [param1, param2, param3])
35 | method2 = Method("cry", "void", [], Visibility.protected, Modifier.static)
36 | orc_class = ClassData("Orc", [], [method1, method2],
37 | [ClassData("Monster")], [Interface("IWalk", []), Interface("IAttack", [])])
38 |
39 | with open(examples_folder + "/java_example_2.txt", 'r') as java_example:
40 | expected = java_example.read()
41 |
42 | result = ClassToJava(orc_class).convert()
43 | assert result == expected
44 |
--------------------------------------------------------------------------------
/test/test_dataToCode/tests_examples/test_classToPython.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.interface import Interface
2 | from src.dataToCode.dataClasses.method import Method
3 | from src.dataToCode.dataClasses.attribute import Attribute
4 | from src.dataToCode.dataClasses.classData import ClassData
5 | from src.dataToCode.languages.toPython.classToPython import ClassToPython
6 | from src.dataToCode.dataClasses.modifier import Modifier
7 | from src.dataToCode.dataClasses.visibility import Visibility
8 | import os.path as path
9 |
10 | examples_folder = path.abspath(
11 | path.join(__file__, "../../code_examples/python/"))
12 |
13 |
14 | def test_python_example_1():
15 | att1 = Attribute("name", "String", Visibility.public)
16 | att2 = Attribute("age", "int", Visibility.private)
17 |
18 | method1 = Method("bark", "void", [], Visibility.public)
19 | param1 = Attribute("by_age", "int", Visibility.public)
20 | method2 = Method("grow_up", "bool", [param1], Visibility.private)
21 | dog_class = ClassData("Dog", [att1, att2], [method1, method2])
22 |
23 | with open(path.join(examples_folder, "python_example_1.txt"), 'r') as python_example:
24 | expected = python_example.read()
25 |
26 | result = ClassToPython(dog_class).convert()
27 | assert result == expected
28 |
29 |
30 | def test_python_example_2():
31 | param1 = Attribute("damage", "int")
32 | param2 = Attribute("entity", "Entity")
33 | param3 = Attribute("bonus", "Bonus")
34 | method1 = Method("attack", "void", [param1, param2, param3])
35 | method2 = Method("cry", "void", [], Visibility.protected, Modifier.static)
36 | orc_class = ClassData("Orc", [], [method1, method2],
37 | [ClassData("Monster")], [Interface("IWalk", []), Interface("IAttack", [])])
38 |
39 | with open(examples_folder + "/python_example_2.txt", 'r') as python_example:
40 | expected = python_example.read()
41 |
42 | result = ClassToPython(orc_class).convert()
43 | assert result == expected
44 |
45 |
46 | def test_python_example_3():
47 | field1 = Attribute("mail_reader", "MailReader", Visibility.public)
48 | field2 = Attribute("configs", "Configs", Visibility.private)
49 | field3 = Attribute("network_adapter", "NetworkAdapter", Visibility.public)
50 | field4 = Attribute("test_runner", "TestRunner", Visibility.protected)
51 |
52 | param1 = Attribute("how_much", "int")
53 | param2 = Attribute("flag1", "bool")
54 | param3 = Attribute("flag2", "bool")
55 |
56 | method1 = Method("initialize", "void")
57 | method2 = Method("initialize_2", "void", modifier=Modifier.abstract)
58 | method3 = Method("do_things", "void", [param1, param2, param3],
59 | Visibility.protected, Modifier.static)
60 | method4 = Method("no_one_will_ever_use_this", "string",
61 | [Attribute("trash", "void"), Attribute("trash_can", "void")],
62 | Visibility.private)
63 |
64 | weird_god_class = ClassData("WeirdGodClass", [field1, field2, field3, field4],
65 | [method1, method2, method3, method4], [],
66 | [Interface("IDoManyThings", [])])
67 |
68 | with open(examples_folder + "/python_example_3.txt", 'r') as python_example:
69 | expected = python_example.read()
70 |
71 | result = ClassToPython(weird_god_class).convert()
72 | assert result == expected
73 |
74 |
75 | def test_python_example_4():
76 | att1 = Attribute("m", "String", Visibility.public)
77 |
78 | method = Method("v", "void", [], Visibility.public, modifier=Modifier.abstract)
79 | dog_class = ClassData("Test4", [att1], [method])
80 |
81 | with open(path.join(examples_folder, "python_example_4.txt"), 'r') as python_example:
82 | expected = python_example.read()
83 |
84 | result = ClassToPython(dog_class).convert()
85 | assert result == expected
86 |
--------------------------------------------------------------------------------
/test/test_dataToCode/tests_examples/test_interfaceToPython.py:
--------------------------------------------------------------------------------
1 | from src.dataToCode.dataClasses.attribute import Attribute
2 | from src.dataToCode.dataClasses.interface import Interface
3 | from src.dataToCode.dataClasses.method import Method
4 | from src.dataToCode.languages.toPython.interfaceToPython import InterfaceToPython
5 | from src.dataToCode.dataClasses.visibility import Visibility
6 | import os.path as path
7 |
8 | examples_folder = path.abspath(
9 | path.join(__file__, "../../code_examples/python/"))
10 |
11 |
12 | def test_interface_example_1():
13 | method1 = Method("do", "void", [], Visibility.public)
14 | example = Interface("Example", [method1])
15 |
16 | with open(path.join(examples_folder, "interface_example_1.txt"), 'r') as python_example:
17 | expected = python_example.read()
18 |
19 | result = InterfaceToPython(example).convert()
20 | assert result == expected
21 |
22 |
23 | def test_interface_example_2():
24 | method1 = Method("foo", "void",
25 | [Attribute("a", "void"), Attribute("b", "int")],
26 | Visibility.public)
27 | method2 = Method("do", "void", [], Visibility.public)
28 | example = Interface("Example", [method1, method2],
29 | Visibility.public, [Interface("IFoo", [])])
30 |
31 | with open(path.join(examples_folder, "interface_example_2.txt"), 'r') as python_example:
32 | expected = python_example.read()
33 |
34 | result = InterfaceToPython(example).convert()
35 | assert result == expected
36 |
--------------------------------------------------------------------------------
/test/test_xmlToData/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/test/test_xmlToData/__init__.py
--------------------------------------------------------------------------------
/test/test_xmlToData/test_drawIoXmlParser.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from src.dataToCode.dataClasses.attribute import Attribute
4 | from src.dataToCode.dataClasses.classData import ClassData
5 | from src.dataToCode.dataClasses.interface import Interface
6 | from src.dataToCode.dataClasses.method import Method
7 | from src.dataToCode.dataClasses.visibility import Visibility
8 | from src.xmlToData.drawIoXmlParser import DrawIoXmlParser
9 | import os.path as path
10 | import xml.etree.ElementTree as ET
11 |
12 |
13 | def test_interfaces_returned_read_xml():
14 | examples_folder = path.abspath(path.join(__file__, "../../../src/xmlToData/uml_samples/uml_interface.xml"))
15 | interface_ = Interface("CalculoDeSalario", [Method("calcular_salario_1", "float",
16 | [Attribute("funcionario", "Funcionario")]),
17 | Method("calcular_salario_2", "float",
18 | [Attribute("funcionario", "Funcionario"),
19 | Attribute("carga_horaria", "int")])], Visibility.public)
20 | list_of_classes, list_of_interfaces = DrawIoXmlParser(examples_folder).read_xml()
21 | assert list_of_interfaces[0] == interface_
22 |
23 |
24 | def test_classes_returned_read_xml():
25 | examples_folder = path.abspath(path.join(__file__, "../../../src/xmlToData/uml_samples/uml1.xml"))
26 | class_ = ClassData("Humano",
27 | [Attribute("idade", "int", Visibility.public), Attribute("anos", "float", Visibility.private)],
28 | [Method("get_idade", "int", [Attribute("nome", "string"), Attribute("altura", "double")],
29 | Visibility.public), Method("get_anos", "float", [], Visibility.private)])
30 | list_of_classes, list_of_interfaces = DrawIoXmlParser(examples_folder).read_xml()
31 | assert list_of_classes[0] == class_
32 |
33 |
34 | def test_extract_value_from_cells():
35 | examples_folder = path.abspath(path.join(__file__, "../../../src/xmlToData/uml_samples/uml_interface.xml"))
36 | xml = ET.parse(examples_folder)
37 | root = xml.getroot()
38 | list_of_ids = ['-cuIEp4vuOl5B3aBU6dm-1']
39 | list_of_xml_classes = [
40 | "<<Interface>>
CalculoDeSalario
+ calcular_salario_1(funcionario: Funcionario): float
+ calcular_salario_2(funcionario: Funcionario, carga_horaria: int): float
"]
41 | list_of_xml_classes_, list_of_ids_, superclass_to_subclasses, implements_dict = \
42 | DrawIoXmlParser.extract_value_from_cells(root)
43 | assert implements_dict == {}
44 | assert superclass_to_subclasses == {}
45 | assert list_of_xml_classes == list_of_xml_classes_
46 | assert list_of_ids == list_of_ids_
47 |
48 |
49 | def test():
50 | examples_folder = path.abspath(path.join(__file__, "../../../test/ultimate_uml_test.xml"))
51 | a = DrawIoXmlParser(examples_folder)
52 | class_list, interface_list = a.read_xml()
53 |
54 | for class_ in class_list:
55 | print(class_.name)
56 | for attribute in class_.fields:
57 | print(attribute.visibility, attribute.name, attribute.type_)
58 | for method in class_.methods:
59 | print(method.visibility, method.name, method.return_type)
60 | for parameter in method.parameters:
61 | print(parameter.name, parameter.type_)
62 | print()
63 |
64 | for interface_ in interface_list:
65 | print(interface_.name)
66 | for method in interface_.methods:
67 | print(method.visibility, method.name, method.return_type)
68 | for parameter in method.parameters:
69 | print(parameter.name, parameter.type_)
70 | print()
71 |
--------------------------------------------------------------------------------
/test/test_xmlToData/test_regexExtractors/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CoffeeOverflow/DrawToCode/718ab54bb6a35eb471571e1d1b7990dc08e2ca35/test/test_xmlToData/test_regexExtractors/__init__.py
--------------------------------------------------------------------------------
/test/test_xmlToData/test_regexExtractors/test_attributeNameExtractor.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from src.xmlToData.regexExtractors.attributeNameExtractor import AttributeNameExtractor
4 |
5 |
6 | @pytest.mark.parametrize("xml_string", ["- age : int ",
7 | "# age: float ",
8 | " + age : string"])
9 | def test_extract_attribute_name_with_and_without_white_spaces(xml_string):
10 | attribute_name = AttributeNameExtractor.extract_name(xml_string)
11 | assert attribute_name == "age"
12 |
--------------------------------------------------------------------------------
/test/test_xmlToData/test_regexExtractors/test_methodNameExtractor.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.xmlToData.regexExtractors.methodNameExtractor import MethodNameExtractor
3 |
4 |
5 | @pytest.mark.parametrize("xml_string", ["+ add_weight(): float ",
6 | "# add_weight (float additional_weight): List ",
7 | " - add_weight (double height) : int"])
8 | def test_extract_method_name_with_and_without_white_spaces(xml_string):
9 | method_name = MethodNameExtractor.extract_name(xml_string)
10 | assert method_name == "add_weight"
11 |
--------------------------------------------------------------------------------
/test/test_xmlToData/test_regexExtractors/test_parametersExtractor.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from src.xmlToData.regexExtractors.parametersExtractor import ParametersExtractor
4 |
5 |
6 | @pytest.mark.parametrize("xml_string", ["+ get_age(): int",
7 | "# add_weight( ): int",
8 | "- set_height( ): int"])
9 | def test_extract_empty_parameters_string_list(xml_string):
10 | list_of_parameters_string = ParametersExtractor.extract_parameters_string(xml_string)
11 | assert list_of_parameters_string == ['']
12 |
13 |
14 | @pytest.mark.parametrize("xml_string", ["+ get_age(int number,float real_number): int",
15 | "# add_weight( int number , float real_number): int",
16 | "- set_height( int number, float real_number ): int"])
17 | def test_extract_parameters_string_list_with_and_without_white_spaces(xml_string):
18 | list_of_parameters_string = ParametersExtractor.extract_parameters_string(xml_string)
19 | assert list_of_parameters_string == ["int number", "float real_number"]
20 |
--------------------------------------------------------------------------------
/test/test_xmlToData/test_regexExtractors/test_returnTypeExtractor.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.xmlToData.regexExtractors.returnTypeExtractor import ReturnTypeExtractor
3 |
4 |
5 | @pytest.mark.parametrize("xml_string", ["- age:int ", "# weight: int ",
6 | " + height: int"])
7 | def test_extract_type_int_from_attributes(xml_string):
8 | type_ = ReturnTypeExtractor.extract_type(xml_string)
9 | assert type_ == "int"
10 |
11 |
12 | @pytest.mark.parametrize("xml_string", ["- age: float ", "# weight: float ",
13 | " + height: float"])
14 | def test_extract_type_float_from_attributes(xml_string):
15 | type_ = ReturnTypeExtractor.extract_type(xml_string)
16 | assert type_ == "float"
17 |
18 |
19 | @pytest.mark.parametrize("xml_string", ["- age: List ", "# weight: List ",
20 | " + height: List"])
21 | def test_extract_type_list_from_attributes(xml_string):
22 | type_ = ReturnTypeExtractor.extract_type(xml_string)
23 | assert type_ == "List"
24 |
25 |
26 | @pytest.mark.parametrize("xml_string", ["- age: void ", "# weight: void ",
27 | " + height: void"])
28 | def test_extract_type_void_from_attributes(xml_string):
29 | type_ = ReturnTypeExtractor.extract_type(xml_string)
30 | assert type_ == "void"
31 |
32 |
33 | @pytest.mark.parametrize("xml_string", ["+ get_age(): int ",
34 | "# add_weight(float additional_weight): int ",
35 | " - set_height(double height): int"])
36 | def test_extract_return_type_int_from_methods(xml_string):
37 | return_type = ReturnTypeExtractor.extract_type(xml_string)
38 | assert return_type == "int"
39 |
40 |
41 | @pytest.mark.parametrize("xml_string", ["+ get_age(): void ",
42 | "# add_weight(float additional_weight): void ",
43 | " - set_height(double height): void"])
44 | def test_extract_return_type_void_from_methods(xml_string):
45 | return_type = ReturnTypeExtractor.extract_type(xml_string)
46 | assert return_type == "void"
47 |
48 |
49 | @pytest.mark.parametrize("xml_string", ["+ get_age(): List ",
50 | "# add_weight(float additional_weight): List ",
51 | " - set_height(double height): List"])
52 | def test_extract_return_type_list_from_methods(xml_string):
53 | return_type = ReturnTypeExtractor.extract_type(xml_string)
54 | assert return_type == "List"
55 |
56 |
57 | @pytest.mark.parametrize("xml_string", ["+ get_age(): float ",
58 | "# add_weight(float additional_weight): float ",
59 | " - set_height(double height): float"])
60 | def test_extract_return_type_float_from_methods(xml_string):
61 | return_type = ReturnTypeExtractor.extract_type(xml_string)
62 | assert return_type == "float"
63 |
--------------------------------------------------------------------------------
/test/test_xmlToData/test_regexExtractors/test_visibilityExtractor.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from src.dataToCode.dataClasses.visibility import Visibility
3 | from src.xmlToData.regexExtractors.visibilityExtractor import VisibilityExtractor
4 |
5 |
6 | @pytest.mark.parametrize("xml_string", ["+ age: int", "+ weight: float",
7 | " + height: double"])
8 | def test_extract_public_visibility_from_attributes(xml_string):
9 | visibility = VisibilityExtractor.extract_visibility(xml_string)
10 | assert visibility == Visibility.public
11 |
12 |
13 | @pytest.mark.parametrize("xml_string", ["- age: int", "- weight: float",
14 | " - height: double"])
15 | def test_extract_private_visibility_from_attributes(xml_string):
16 | visibility = VisibilityExtractor.extract_visibility(xml_string)
17 | assert visibility == Visibility.private
18 |
19 |
20 | @pytest.mark.parametrize("xml_string", ["# age: int", "# weight: float",
21 | " # height: double"])
22 | def test_extract_protected_visibility_from_attributes(xml_string):
23 | visibility = VisibilityExtractor.extract_visibility(xml_string)
24 | assert visibility == Visibility.protected
25 |
26 |
27 | @pytest.mark.parametrize("xml_string", ["+ get_age(): int", "+ add_weight(float additional_wight): float",
28 | " + set_height(double height): void"])
29 | def test_extract_public_visibility_from_methods(xml_string):
30 | visibility = VisibilityExtractor.extract_visibility(xml_string)
31 | assert visibility in [Visibility.protected, Visibility.public, Visibility.private]
32 |
33 |
34 | @pytest.mark.parametrize("xml_string", ["- get_age(): int", "- add_weight(float additional_wight): float",
35 | " - set_height(double height): void"])
36 | def test_extract_private_visibility_from_methods(xml_string):
37 | visibility = VisibilityExtractor.extract_visibility(xml_string)
38 | assert visibility in [Visibility.protected, Visibility.public, Visibility.private]
39 |
40 |
41 | @pytest.mark.parametrize("xml_string", ["# get_age(): int", "# add_weight(float additional_wight): float",
42 | " # set_height(double height): void"])
43 | def test_extract_protected_visibility_from_methods(xml_string):
44 | visibility = VisibilityExtractor.extract_visibility(xml_string)
45 | assert visibility in [Visibility.protected, Visibility.public, Visibility.private]
46 |
--------------------------------------------------------------------------------
/test/ultimate_uml_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------