From d63713b23eef63917fe71d6941a6517e9ab3cfb4 Mon Sep 17 00:00:00 2001 From: Caleb Sitton Date: Wed, 19 Jun 2024 08:18:24 -0600 Subject: [PATCH] Expanded unit tests --- tests/unit_tests/test_heron.py | 189 ++++++++++++++++++++++++--------- tests/unit_tests/tests | 11 ++ 2 files changed, 149 insertions(+), 51 deletions(-) create mode 100644 tests/unit_tests/tests diff --git a/tests/unit_tests/test_heron.py b/tests/unit_tests/test_heron.py index 75c15691..c57cb79d 100644 --- a/tests/unit_tests/test_heron.py +++ b/tests/unit_tests/test_heron.py @@ -1,61 +1,148 @@ +import os +import sys import unittest from unittest.mock import mock_open, patch, MagicMock import xml.etree.ElementTree as ET +FORCE_LOC = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir)) +sys.path.append(FORCE_LOC) from FORCE.src.heron import create_componentsets_in_HERON -class TestCreateComponentSetsInHERON(unittest.TestCase): - - def setUp(self): - # Example of a minimal XML structure - self.heron_xml = """ - - - - - 100 - - - - - """ - self.tree = ET.ElementTree(ET.fromstring(self.heron_xml)) - - @patch('xml.etree.ElementTree.parse') - @patch('os.listdir') - @patch('builtins.open', - new_callable=mock_open, - read_data="""{ - "Component Set Name": "NewComponent", - "Reference Driver": 1000, - "Reference Driver Power Units": "kW", - "Reference Price (USD)": 2000, - "Scaling Factor": 0.5 - }""") - def test_new_component_creation(self, mock_file, mock_listdir, mock_parse): - # Setup the mock to return an XML tree - mock_parse.return_value = self.tree - mock_listdir.return_value = ['componentSet1.json'] - - # Call the function - result_tree = create_componentsets_in_HERON("/fake/folder", "/fake/heron_input.xml") - - # Verify the XML was updated correctly - components = result_tree.findall('.//Component[@name="NewComponent"]') - self.assertEqual(len(components), 1) - economics = components[0].find('economics') - self.assertIsNotNone(economics) - - # Verify the CashFlow node was created - cashflows = economics.findall('CashFlow') - self.assertEqual(len(cashflows), 1) - self.assertEqual(cashflows[0].attrib['name'], 'NewComponent_capex') +class TestMinimalInput(unittest.TestCase): + + def setUp(self): + # Example of a minimal XML structure + self.heron_xml = """ + + + + + + + + + """ + self.tree = ET.ElementTree(ET.fromstring(self.heron_xml)) + + @patch('xml.etree.ElementTree.parse') + @patch('os.listdir') + @patch('builtins.open', + new_callable=mock_open, + read_data="""{ + "Component Set Name": "NewComponent", + "Reference Driver": 1000, + "Reference Driver Power Units": "kW", + "Reference Price (USD)": 2000, + "Scaling Factor": 0.5 + }""") + def test_minimal_input(self, mock_file, mock_listdir, mock_parse): + # Set up the mock to return an XML tree + mock_parse.return_value = self.tree + mock_listdir.return_value = ['componentSetFake.json'] + + # Call the function + result_tree = create_componentsets_in_HERON("/fake/folder", "/fake/heron_input.xml") + + # Verify the XML was updated correctly + new_components = result_tree.findall('.//Component[@name="NewComponent"]') + self.assertEqual(len(new_components), 1) + economics = new_components[0].find('economics') + self.assertIsNotNone(economics) + + # Verify the CashFlow node was created + cashflows = economics.findall('CashFlow') + self.assertEqual(len(cashflows), 1) + self.assertEqual(cashflows[0].attrib['name'], 'NewComponent_capex') + + # Verify the reference driver and price updates + ref_driver = cashflows[0].find('./reference_driver/fixed_value') + self.assertEqual(ref_driver.text, '1.0') # The driver should have been converted from kW to MW + +class TestExpandedInput(unittest.TestCase): + + def setUp(self): + # Added case and datagenerator nodes (should be transferred blindly) and extra components + self.heron_xml = """ + + + + + + + + + + + + - # Verify the reference driver and price updates - ref_driver = cashflows[0].find('./reference_driver/fixed_value') - self.assertEqual(ref_driver.text, '1.0') # The driver should have been converted from kW to MW + + + + + + + + + + + + + """ + self.tree = ET.ElementTree(ET.fromstring(self.heron_xml)) + + @patch('xml.etree.ElementTree.parse') + @patch('os.listdir') + @patch('builtins.open', + new_callable=mock_open, + read_data="""{ + "Component Set Name": "NewComponent", + "Reference Driver": 1000, + "Reference Driver Power Units": "mW", + "Reference Price (USD)": 2000, + "Scaling Factor": 0.5 + }""") + def test_expanded_input(self, mock_open, mock_listdir, mock_parse): + # Set up the mock to return an XML tree + mock_parse.return_value = self.tree + # No additional data for XML + mock_listdir.return_value = ["componentSetFake.json"] + + # Call the function + result_tree = create_componentsets_in_HERON("/fake/folder", "/fake/heron_input.xml") + + # Verify Case node was transferred + with (self.subTest("Case node has been corrupted")): + cases = result_tree.findall('./Case') + self.assertEqual(len(cases), 1) + self.assertIsNotNone(cases[0].find('./untouched_content_Case')) + + # Verify Component nodes were merged + componentNodes = result_tree.findall("./Components/Component") + self.assertEqual(len(componentNodes), 3) + + for comp in componentNodes: + if comp.get('name') == 'ExistingComponent0': + # Verify CashFlow with type + cashflows = comp.findall('./economics/CashFlow') + self.assertEqual(len(cashflows), 1) + self.assertEqual(cashflows[0].attrib['type'], 'one-time') + elif comp.get('name') == 'ExistingComponent1': + # Verify CashFlow with type + cashflows = comp.findall('./economics/CashFlow') + self.assertEqual(len(cashflows), 1) + self.assertEqual(cashflows[0].attrib['type'], 'repeating') + elif comp.get('name') == 'NewComponent': + # Verify reference driver + ref_driver = comp.find('./economics/CashFlow/reference_driver/fixed_value') + self.assertEqual(ref_driver.text, '1000') # Check that mW were not converted + break - # Add more tests here to cover other conditions and edge cases + # Verify DataGenerators node was transferred + with (self.subTest("DataGenerators node has been corrupted")): + dataGens = result_tree.findall('./DataGenerators') + self.assertEqual(len(dataGens), 1) + self.assertIsNotNone(dataGens[0].find('./untouched_content_DG')) if __name__ == '__main__': - unittest.main() + unittest.main() diff --git a/tests/unit_tests/tests b/tests/unit_tests/tests new file mode 100644 index 00000000..980dfbdc --- /dev/null +++ b/tests/unit_tests/tests @@ -0,0 +1,11 @@ +[Tests] + [./TestMinimalInput] + type = GenericExecutable + executable = python test_heron.py + [../] + + [./TestExpandedInput] + type = GenericExecutable + executable = python test_heron.py + [../] +[] \ No newline at end of file