Skip to content

Commit

Permalink
Added Perf_Test__MGraph_Json
Browse files Browse the repository at this point in the history
  • Loading branch information
DinisCruz committed Jan 16, 2025
1 parent 669b319 commit aa0a79c
Show file tree
Hide file tree
Showing 11 changed files with 218 additions and 41 deletions.
3 changes: 3 additions & 0 deletions mgraph_ai/mgraph/domain/Domain__MGraph__Graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ def edge(self, edge_id: Random_Guid) -> Domain__MGraph__Edge:
def edges(self) -> List[Domain__MGraph__Edge]:
return [self.mgraph_edge(edge=edge) for edge in self.model.edges()]

def edges_ids(self):
return self.model.edges_ids()

def graph_id(self):
return self.model.data.graph_id

Expand Down
14 changes: 7 additions & 7 deletions mgraph_ai/providers/json/MGraph__Json.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from mgraph_ai.mgraph.actions.MGraph__Data import MGraph__Data
from mgraph_ai.mgraph.actions.MGraph__Edit import MGraph__Edit
from mgraph_ai.mgraph.actions.MGraph__Storage import MGraph__Storage
from mgraph_ai.providers.json.actions.MGraph__Json__Export import MGraph__Json__Export
from mgraph_ai.providers.json.actions.MGraph__Json__Load import MGraph__Json__Load
from mgraph_ai.providers.json.domain.Domain__MGraph__Json__Graph import Domain__MGraph__Json__Graph
from osbot_utils.type_safe.Type_Safe import Type_Safe
from mgraph_ai.mgraph.actions.MGraph__Data import MGraph__Data
from mgraph_ai.mgraph.actions.MGraph__Edit import MGraph__Edit
from mgraph_ai.mgraph.actions.MGraph__Storage import MGraph__Storage
from mgraph_ai.providers.json.actions.MGraph__Json__Export import MGraph__Json__Export
from mgraph_ai.providers.json.actions.MGraph__Json__Load import MGraph__Json__Load
from mgraph_ai.providers.json.domain.Domain__MGraph__Json__Graph import Domain__MGraph__Json__Graph
from osbot_utils.type_safe.Type_Safe import Type_Safe


class MGraph__Json(Type_Safe): # Main JSON graph manager
Expand Down
20 changes: 12 additions & 8 deletions mgraph_ai/providers/json/actions/MGraph__Json__Export.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from typing import Union, Dict, List, Optional, Any
from osbot_utils.utils.Files import file_save
from osbot_utils.utils.Json import json_dumps
from mgraph_ai.providers.json.domain.Domain__MGraph__Json__Node__Dict import Domain__MGraph__Json__Node__Dict
from mgraph_ai.providers.json.domain.Domain__MGraph__Json__Node__List import Domain__MGraph__Json__Node__List
from mgraph_ai.providers.json.domain.Domain__MGraph__Json__Node__Value import Domain__MGraph__Json__Node__Value
from mgraph_ai.providers.json.domain.Domain__MGraph__Json__Graph import Domain__MGraph__Json__Graph
from mgraph_ai.mgraph.actions.MGraph__Export import MGraph__Export
from typing import Union, Dict, List, Optional, Any
from mgraph_ai.providers.json.actions.exporters.MGraph__Export__Json__Dot import MGraph__Export__Json__Dot
from osbot_utils.utils.Files import file_save
from osbot_utils.utils.Json import json_dumps
from mgraph_ai.providers.json.domain.Domain__MGraph__Json__Node__Dict import Domain__MGraph__Json__Node__Dict
from mgraph_ai.providers.json.domain.Domain__MGraph__Json__Node__List import Domain__MGraph__Json__Node__List
from mgraph_ai.providers.json.domain.Domain__MGraph__Json__Node__Value import Domain__MGraph__Json__Node__Value
from mgraph_ai.providers.json.domain.Domain__MGraph__Json__Graph import Domain__MGraph__Json__Graph
from mgraph_ai.mgraph.actions.MGraph__Export import MGraph__Export

class MGraph__Json__Export(MGraph__Export): # JSON export handler
graph: Domain__MGraph__Json__Graph
Expand All @@ -26,6 +27,9 @@ def to_string(self, indent: Optional[int] = None) -> str: # Export to JSON stri
data = self.to_dict()
return json_dumps(data, indent=indent)

def to_dot(self):
return MGraph__Export__Json__Dot(graph=self.graph)

def to_file(self, file_path: str, indent: Optional[int] = None) -> bool: # Export to JSON file
file_contents = self.to_string(indent=indent)
if file_contents:
Expand Down
4 changes: 2 additions & 2 deletions mgraph_ai/providers/json/actions/MGraph__Json__Load.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ def __init__(self, graph: Domain__MGraph__Json__Graph):
def from_string(self, json_str: str) -> Domain__MGraph__Json__Graph: # Import from JSON string
data = json_loads(json_str)
if data:
return self.from_dict(data)
return self.from_json(data)

def from_dict(self, data: Any) -> Domain__MGraph__Json__Graph: # Import from Python object
def from_json(self, data: Any) -> Domain__MGraph__Json__Graph: # Import from Python object
self.graph.set_root_content(data)
return self.graph

Expand Down
69 changes: 69 additions & 0 deletions mgraph_ai/providers/json/utils/Perf_Test__MGraph_Json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from typing import Union
from mgraph_ai.providers.json.MGraph__Json import MGraph__Json
from osbot_utils.context_managers.capture_duration import capture_duration
from osbot_utils.utils.Http import GET_json
from osbot_utils.type_safe.Type_Safe import Type_Safe

class Model__Perf_Test__Duration(Type_Safe):
duration__get_source_json : float
duration__mgraph_parse : float
duration__dot_creation : float
duration__total : float

class Perf_Test__MGraph_Json(Type_Safe):
perf_test_duration : Model__Perf_Test__Duration
source_json : Union[str, list, dict]
mgraph_json : MGraph__Json
target_url : str
dot_code : str

def setup__get_source_json_from_url(self):
with capture_duration() as duration:
self.source_json = GET_json(self.target_url)
self.perf_test_duration.duration__get_source_json = duration.seconds
self.perf_test_duration.duration__total += duration.seconds

return self

def step__create_mgraph(self):
with capture_duration() as duration:
self.mgraph_json.load().from_json(self.source_json)
self.perf_test_duration.duration__dot_creation = duration.seconds
self.perf_test_duration.duration__total += duration.seconds
return self

def step__create_dot(self):
with capture_duration() as duration:
self.dot_code = self.mgraph_json.export().to_dot().to_string()
self.perf_test_duration.duration__mgraph_parse = duration.seconds
self.perf_test_duration.duration__total += duration.seconds
return self

def run_workflow__on_url(self, target_url):
self.target_url = target_url
(self.setup__get_source_json_from_url ()
.step__create_mgraph ()
.step__create_dot ())

def run_workflow__on_json(self, source_json):
self.source_json = source_json
(self.step__create_mgraph()
.step__create_dot ())

def print(self):
print()
print("----- Perf Test Results ----")
print()
print(f" Target URL: {self.target_url}")
print(f" Nodes : {len(self.mgraph_json.graph.nodes_ids())}")
print(f" Edges : {len(self.mgraph_json.graph.edges_ids())}")
print(f" Dot Code : {len(self.dot_code)}")
print()
print(f"duration__get_source_json: {self.perf_test_duration.duration__get_source_json}")
print(f"duration__mgraph_parse : {self.perf_test_duration.duration__mgraph_parse}")
print(f"duration__dot_creation : {self.perf_test_duration.duration__dot_creation}")
print('---------------------------------')
print(f"duration__total : {self.perf_test_duration.duration__total:.3f}")
print('---------------------------------')
print()

Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ def test_init(self): # Tes
assert 'counters' in self.exporter.context

def test_node_type_detection(self): # Test node type detection
self.mgraph.load().from_dict(self.test_data)
self.mgraph.load().from_json(self.test_data)
root = self.mgraph.graph.root_content()

assert self.exporter.get_node_type(root) == Export__Json__Node_Type.OBJECT

array_data = [1, 2, 3]
self.mgraph.load().from_dict(array_data)
self.mgraph.load().from_json(array_data)
array_root = self.mgraph.graph.root_content()
assert self.exporter.get_node_type(array_root) == Export__Json__Node_Type.ARRAY

value_data = "test"
self.mgraph.load().from_dict(value_data)
self.mgraph.load().from_json(value_data)
value_root = self.mgraph.graph.root_content()
assert self.exporter.get_node_type(value_root) == Export__Json__Node_Type.VALUE

Expand All @@ -77,19 +77,19 @@ def test_id_generation(self): # Test
assert self.exporter.generate_node_id("property") == "property_0"

def test_object_export(self): # Test object export
self.mgraph.load().from_dict({"key": "value"})
self.mgraph.load().from_json({"key": "value"})
output = self.exporter.to_string()
assert output == "test_output"
assert self.exporter.last_processed[0] == "object"

def test_array_export(self): # Test array export
self.mgraph.load().from_dict([1, 2, 3])
self.mgraph.load().from_json([1, 2, 3])
output = self.exporter.to_string()
assert output == "test_output"
assert self.exporter.last_processed[0] == "array"

def test_value_export(self): # Test value export
self.mgraph.load().from_dict("test")
self.mgraph.load().from_json("test")
output = self.exporter.to_string()
assert output == "test_output"
assert self.exporter.last_processed[0] == "value"
Expand All @@ -103,7 +103,7 @@ def failing_process():
raise Exception("Test error")

self.exporter.process_object_node = failing_process
self.mgraph.load().from_dict({"key": "value"})
self.mgraph.load().from_json({"key": "value"})

with self.assertRaises(Export__Json__Format_Error):
self.exporter.to_string()
Expand All @@ -112,5 +112,5 @@ def failing_process():
self.exporter.to_file("nonexistent/path/file.txt")

def test_file_export(self): # Test file export with mock
self.mgraph.load().from_dict(self.test_data)
self.mgraph.load().from_json(self.test_data)
assert self.exporter.to_file("test.txt") is True
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def test_format_node_attributes(self): # Test
assert self.exporter.format_node_attributes({}) == ""

def test_simple_value_export(self): # Test value node export
self.mgraph.load().from_dict("test_value")
self.mgraph.load().from_json("test_value")
dot = self.exporter.to_string()
assert dot == """\
digraph {
Expand All @@ -71,7 +71,7 @@ def test_simple_value_export(self): # Test

def test_array_export(self): # Test array node export
test_array = [1, 2, "three"]
self.mgraph.load().from_dict(test_array)
self.mgraph.load().from_json(test_array)
dot = self.exporter.to_string()
assert dot == """\
digraph {
Expand All @@ -96,7 +96,7 @@ def test_array_export(self): # Test

def test_object_export(self): # Test object node export
test_obj = {"key1": "value1", "key2": 42}
self.mgraph.load().from_dict(test_obj)
self.mgraph.load().from_json(test_obj)
dot = self.exporter.to_string()
assert dot == """\
digraph {
Expand All @@ -120,7 +120,7 @@ def test_object_export(self): # Test
}"""

def test_complex_structure(self): # Test complex nested structure
self.mgraph.load().from_dict(self.test_data)
self.mgraph.load().from_json(self.test_data)
dot = self.exporter.to_string()

# Basic structure checks
Expand All @@ -147,7 +147,7 @@ def test_complex_structure(self): # Test
assert Export__Json__Relation_Type.ARRAY_ITEM in dot

def test_visual_attributes(self): # Test visual styling
self.mgraph.load().from_dict(self.test_data)
self.mgraph.load().from_json(self.test_data)
dot = self.exporter.to_string()

# Style attributes
Expand All @@ -174,7 +174,7 @@ def test_nested_structure(self): # Test
}
}
}
self.mgraph.load().from_dict(nested_data)
self.mgraph.load().from_json(nested_data)
assert json_loads(self.mgraph.export().to_string()) == nested_data # BUG
dot = self.exporter.to_string()
assert dot == """\
Expand Down Expand Up @@ -225,7 +225,7 @@ def test_nested_structure(self): # Test
}"""

def test_dot_syntax(self): # Test valid DOT syntax elements
self.mgraph.load().from_dict(self.test_data)
self.mgraph.load().from_json(self.test_data)
dot = self.exporter.to_string()

# Basic DOT syntax elements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def setUp(self):
"object" : {"key": "value"}}

def test_export_formats(self): # Test different export formats
self.mgraph.load().from_dict(self.test_data)
self.mgraph.load().from_json(self.test_data)

dict_export = self.mgraph.export().to_dict() # Test dict export
str_export = self.mgraph.export().to_string() # Test string export without indent
Expand All @@ -32,7 +32,7 @@ def test_export_formats(self):

def test_file_operations(self): # Test file import/export
file_path = "test.json"
self.mgraph.load().from_dict(self.test_data) # Test export to file
self.mgraph.load().from_json(self.test_data) # Test export to file
assert self.mgraph.export().to_file(str(file_path), indent=2) is True
assert file_exists(file_path) is True

Expand Down
14 changes: 7 additions & 7 deletions tests/unit/providers/json/actions/test_MGraph__Json__Load.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def setUp(self):
"object" : {"key": "value"}}

def test_import_from_dict(self): # Test importing from dict
graph = self.mgraph.load().from_dict(self.test_data)
graph = self.mgraph.load().from_json(self.test_data)
root_content = graph.root_content()
assert isinstance(root_content, Domain__MGraph__Json__Node__Dict)
assert root_content.property("string" ) == "value"
Expand All @@ -33,7 +33,7 @@ def test_import_from_string(self):
assert root_content.property("list") == [1, 2, 3]

def test_export_to_dict(self): # Test exporting to dict
self.mgraph.load().from_dict(self.test_data)
self.mgraph.load().from_json(self.test_data)
exported = self.mgraph.export().to_dict()
assert exported == self.test_data
assert exported["string" ] == "value"
Expand All @@ -44,22 +44,22 @@ def test_export_to_dict(self):
assert exported["object" ] == {"key": "value"}

def test_export_to_string(self): # Test exporting to JSON string
self.mgraph.load().from_dict(self.test_data)
self.mgraph.load().from_json(self.test_data)
exported = self.mgraph.export().to_string()
assert json_loads(exported) == self.test_data

def test_primitive_values(self): # Test handling primitive values
values = ["string", 42, 3.14, True, False, None ]
for value in values:
graph = self.mgraph.load().from_dict(value)
graph = self.mgraph.load().from_json(value)
root_content = graph.root_content()
assert isinstance(root_content, Domain__MGraph__Json__Node__Value)
assert root_content.value == value
assert self.mgraph.export().to_dict() == value

def test_array_handling(self): # Test array operations
array_data = [1, "two", {"three": 3}, [4, 5]]
graph = self.mgraph.load().from_dict(array_data)
graph = self.mgraph.load().from_json(array_data)
root_content = graph.root_content()
assert isinstance(root_content, Domain__MGraph__Json__Node__List)
items = root_content.items()
Expand All @@ -72,7 +72,7 @@ def test_array_handling(self):
def test_nested_structures(self): # Test nested JSON structures
nested_data = {"level1": {"level2": {"level3": {"array": [1, 2, {"key": "value"}],
"value": "nested" }}}}
graph = self.mgraph.load().from_dict(nested_data)
graph = self.mgraph.load().from_json(nested_data)
root_content = graph.root_content()
assert isinstance(root_content, Domain__MGraph__Json__Node__Dict)
assert self.mgraph.export().to_dict() == nested_data
Expand All @@ -81,7 +81,7 @@ def test_empty_structures(self):
empty_data = { "empty_object" : {} ,
"empty_array" : [] ,
"empty_string" : "" }
graph = self.mgraph.load().from_dict(empty_data)
graph = self.mgraph.load().from_json(empty_data)
root_content = graph.root_content()
assert isinstance(root_content, Domain__MGraph__Json__Node__Dict)
assert self.mgraph.export().to_dict() == empty_data
Loading

0 comments on commit aa0a79c

Please sign in to comment.