├── .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 | ![DrawToCode](docs/Draw2CodeLogo.png) 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 | [![UFPA](docs/logo_ufpa_github_footer.png)](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 | --------------------------------------------------------------------------------