Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Object to XML Functionality with Tests #1

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:

strategy:
matrix:
python-version: [3.9]
python-version: [3.12]

steps:

Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ sphinx_mdinclude = "^0.5.1"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

[tool.pytest.ini_options]
pythonpath = "arcade-xml-generator"
33 changes: 33 additions & 0 deletions src/ObjectToXML.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import xml.etree.ElementTree as ET
from dataclasses import dataclass, field
from typing import List

@dataclass(frozen=True, order=True)
class xml_object:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be camel case

name: str
self_closing: bool = False #True if < tag />
attribute_dict: dict = field(default_factory=dict)
children: List['xml_object'] = field(default_factory=list)
parent: 'xml_object' = None # Added parent attribute


def __post_init__(self):
# Set parent attribute for each child
for child in self.children:
child.parent = self

def convert_to_element_tree(self):
element = ET.Element(self.name, self.attribute_dict)
for child in self.children:
child_element = child.convert_to_element_tree()
element.append(child_element)
return element
def save_XML(self, file_name):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure you follow a style guide with spacing the methods

tree = ET.ElementTree(self.convert_to_element_tree())
print(type(tree))
ET.indent(tree, space="\t", level=0)
tree.write(file_name, encoding="utf-8")




1 change: 1 addition & 0 deletions src/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from src.ObjectToXML import xml_object
1 change: 1 addition & 0 deletions tests/unit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from unit.test_ObjectToXML import TestObjectCreation
81 changes: 81 additions & 0 deletions tests/unit/test_ObjectToXML.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import unittest
import sys
import os

current_script_path = os.path.dirname(os.path.abspath(__file__))
relative_path_to_xml_object = os.path.normpath(os.path.join(current_script_path, '../../src/'))
sys.path.append(relative_path_to_xml_object)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

flag to fix at another point

from ObjectToXML import xml_object

output ="""
<population id="C" init="100" class="cancer_stem">
<population.parameter id="DIVISION_POTENTIAL" value="3" />
<population.parameter id="COMPRESSION_TOLERANCE" value="8.7" />
<population.parameter id="SYNTHESIS_DURATION" module="proliferation" value="10" />
<population.parameter id="meta_pref" scale="1.5" />
<population.parameter id="migra_threshold" scale="0.5" />
<population.parameter id="CELL_VOLUME_MEAN" scale="0.58" />
<population.process id="METABOLISM" version="complex" />
<population.process id="SIGNALING" version="complex" />
<population.parameter id="MIGRA_PROB" process="signaling" value="0" />
<population.process id="SIGNALING" version="complex" />
<population.parameter id="DIVISION_POTENTIAL" value="20" />
<population.parameter id="MIGRATION_RATE" module="migration" value="2" />
</population>
"""

class TestObjectCreation(unittest.TestCase):
"""Test the class xml_object creation method"""

def setUp_nochildren_noparent(self):
self.population_simple = xml_object(name = 'population', attribute_dict = {'id':'C', 'init':'100', 'class':'cancer'}, self_closing = False)
def setUp_children(self):
"""
populations
|-population
|-population parameter
|-population process
|-population process
"""
self.tree_with_children = xml_object(name = 'populations', self_closing = False)
self.tree_with_children.children.append(xml_object(name = 'population', attribute_dict = {'id':'C', 'init':'100', 'class':'cancer'}, self_closing = False))
self.tree_with_children.children[0].children.append(xml_object(name = 'population.parameter', attribute_dict = {'id':'DIVISION_POTENTIAL', 'value':'3'}, self_closing = True))
self.tree_with_children.children[0].children.append(xml_object(name = 'population.process', attribute_dict = {'id':'METABOLISM', 'version':'complex'}, self_closing = True))
self.tree_with_children.children[0].children.append(xml_object(name = 'population.process', attribute_dict = {'id':'SIGNALING', 'version':'complex'}, self_closing = True) )

print(self)
print("olaf")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sure these debug print statements get removed before you send to pull request

print(self)

def test_to_convert_to_element_tree_simple(self):
self.setUp_nochildren_noparent()
root_element = xml_object.convert_to_element_tree(self.population_simple)
self.assertEqual(root_element.tag, 'population')
self.assertEqual(root_element.attrib, {'id':'C', 'init':'100', 'class':'cancer'})
xml_object.save_XML(self.population_simple, "simpleTest.xml")

def test_to_convert_to_element_tree_children(self):
self.setUp_children()
root_element = xml_object.convert_to_element_tree(self.tree_with_children)

self.assertEqual(root_element.tag, 'populations')
self.assertEqual(root_element[0].tag, 'population')
self.assertEqual(root_element[0].attrib, {'id':'C', 'init':'100', 'class':'cancer'})

children_elements = list(root_element[0])

self.assertEqual(children_elements[0].tag, 'population.parameter')
self.assertEqual(children_elements[0].attrib, {'id':'DIVISION_POTENTIAL', 'value':'3'})

self.assertEqual(children_elements[1].tag, 'population.process')
self.assertEqual(children_elements[1].attrib, {'id':'METABOLISM', 'version':'complex'})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are cleaner ways to do this but we don't need to do that now


self.assertEqual(children_elements[2].tag, 'population.process')
self.assertEqual(children_elements[2].attrib, {'id':'SIGNALING', 'version':'complex'})

xml_object.save_XML(self.tree_with_children, "childrenTest.xml")



if __name__ == "__main__":
unittest.main()