mosaicode/tests/control/test_codegenerator_pure.py

336 lines
12 KiB
Python

# -*- coding: utf-8 -*-
"""
Tests for CodeGenerator (pure logic, no GUI dependencies).
"""
import pytest
from pathlib import Path
import tempfile
import shutil
import json
from unittest.mock import Mock, patch, MagicMock
# Mock the GTK import before importing CodeGenerator
import sys
from unittest.mock import MagicMock
# Create a mock for gi module
mock_gi = MagicMock()
sys.modules['gi'] = mock_gi
sys.modules['gi.repository'] = MagicMock()
sys.modules['gi.repository.Gtk'] = MagicMock()
# Now we can import CodeGenerator
from mosaicode.control.codegenerator import CodeGenerator
@pytest.fixture
def test_dir():
"""Create temporary test directory."""
test_dir = Path(tempfile.mkdtemp(prefix="mosaicode_test_"))
yield test_dir
if test_dir.exists():
shutil.rmtree(test_dir)
@pytest.fixture
def mock_diagram():
"""Create a mock diagram for testing."""
diagram = Mock()
# Mock blocks
block1 = Mock()
block1.id = 1
block1.type = "test.block1"
block1.label = "Block 1"
block1.weight = 0
block1.connections = []
block1.codes = {"function": "print('Hello from block 1')"}
block1.gen_codes = {}
block1.ports = []
block1.get_properties.return_value = []
block2 = Mock()
block2.id = 2
block2.type = "test.block2"
block2.label = "Block 2"
block2.weight = 0
block2.connections = []
block2.codes = {"function": "print('Hello from block 2')"}
block2.gen_codes = {}
block2.ports = []
block2.get_properties.return_value = []
diagram.blocks = {1: block1, 2: block2}
diagram.connectors = []
# Mock code template
code_template = Mock()
code_template.code_parts = ["function", "declaration"]
code_template.command = "python $dir_name$index.py"
code_template.name = "test_template"
code_template.description = "Test template"
code_template.properties = []
diagram.code_template = code_template
return diagram
class TestCodeGeneratorPure:
"""Test cases for CodeGenerator (pure logic)."""
def test_code_generator_initialization(self, mock_diagram):
"""Test CodeGenerator initialization."""
code_generator = CodeGenerator(mock_diagram)
assert code_generator is not None
assert code_generator._CodeGenerator__diagram == mock_diagram
assert code_generator._CodeGenerator__block_list == []
assert code_generator._CodeGenerator__connections == []
assert code_generator._CodeGenerator__codes == {}
def test_prepare_block_list(self, mock_diagram):
"""Test block list preparation."""
code_generator = CodeGenerator(mock_diagram)
# Test prepare block list
result = code_generator._CodeGenerator__prepare_block_list()
assert result is True
# Check that blocks were added to the list
assert len(code_generator._CodeGenerator__block_list) == 2
# Check that blocks have weight and connections initialized
for block in code_generator._CodeGenerator__block_list:
assert block.weight == 0
assert block.connections == []
def test_sort_block_list(self, mock_diagram):
"""Test block list sorting."""
code_generator = CodeGenerator(mock_diagram)
code_generator._CodeGenerator__prepare_block_list()
# Test sort block list
result = code_generator._CodeGenerator__sort_block_list()
assert result is True
# All blocks should still have weight 0 since there are no connections
for block in code_generator._CodeGenerator__block_list:
assert block.weight == 0
def test_sort_block_list_with_connections(self):
"""Test block list sorting with connections."""
# Create mock diagram with connections
diagram = Mock()
# Create blocks
block1 = Mock()
block1.id = 1
block1.weight = 0
block1.connections = []
block2 = Mock()
block2.id = 2
block2.weight = 0
block2.connections = []
# Create connection
connection = Mock()
connection.output = block1
connection.input = block2
# Set up connections
block1.connections = [connection]
diagram.blocks = {1: block1, 2: block2}
diagram.connectors = [connection]
code_generator = CodeGenerator(diagram)
code_generator._CodeGenerator__prepare_block_list()
# Test sort block list
result = code_generator._CodeGenerator__sort_block_list()
assert result is True
# Block2 should have higher weight than block1
block1_weight = next(b.weight for b in code_generator._CodeGenerator__block_list if b.id == 1)
block2_weight = next(b.weight for b in code_generator._CodeGenerator__block_list if b.id == 2)
assert block2_weight > block1_weight
def test_generate_port_var_name_code(self, mock_diagram):
"""Test port variable name code generation."""
code_generator = CodeGenerator(mock_diagram)
# Create mock block and port
block = Mock()
block.id = 1
block.type = "test.block"
port = Mock()
port.var_name = "$port[name]$"
port.name = "test_port"
# Test port variable name generation
result = code_generator._CodeGenerator__generate_port_var_name_code(block, port)
assert result == "test_port"
def test_generate_block_code_parts(self, mock_diagram):
"""Test block code parts generation."""
code_generator = CodeGenerator(mock_diagram)
code_generator._CodeGenerator__prepare_block_list()
code_generator._CodeGenerator__sort_block_list()
# Test generate block code parts
result = code_generator._CodeGenerator__generate_block_code_parts()
assert result is True
# Check that codes were generated for each part
assert "function" in code_generator._CodeGenerator__codes
assert "declaration" in code_generator._CodeGenerator__codes
def test_generate_block_code(self, mock_diagram):
"""Test individual block code generation."""
code_generator = CodeGenerator(mock_diagram)
code_generator._CodeGenerator__prepare_block_list()
# Get first block
block = code_generator._CodeGenerator__block_list[0]
# Test generate block code
result = code_generator._CodeGenerator__generate_block_code(block)
assert result is True
# Check that gen_codes were created for the block
assert "function" in block.gen_codes
assert block.gen_codes["function"] == "print('Hello from block 1')"
def test_generate_file_code(self, mock_diagram, test_dir):
"""Test file code generation."""
# Mock diagram.language e patch_name para evitar TypeError
mock_diagram.language = "python"
mock_diagram.patch_name = "test_patch"
# Mock code_template.codes para evitar erro de iteração
mock_diagram.code_template.codes = {"function": "print('Hello World')"}
code_generator = CodeGenerator(mock_diagram)
code_generator._CodeGenerator__prepare_block_list()
code_generator._CodeGenerator__sort_block_list()
code_generator._CodeGenerator__generate_block_code_parts()
# Test generate file code com template simples
template_code = "print('Hello World')"
result = code_generator._CodeGenerator__generate_file_code(template_code)
assert isinstance(result, str)
assert "Hello World" in result
def test_generate_code_integration(self, mock_diagram, test_dir):
"""Test complete code generation integration."""
# Mock diagram.language e patch_name para evitar TypeError
mock_diagram.language = "python"
mock_diagram.patch_name = "test_patch"
# Mock code_template.codes para evitar erro de iteração
mock_diagram.code_template.codes = {"function": "print('Hello World')"}
code_generator = CodeGenerator(mock_diagram)
# Test complete code generation
result = code_generator.generate_code()
assert isinstance(result, dict)
assert "function" in result
assert "Hello World" in result["function"]
def test_code_generator_with_properties(self):
"""Test code generator with block properties."""
# Create mock diagram with properties
diagram = Mock()
# Create block with properties
block = Mock()
block.id = 1
block.type = "test.block"
block.label = "Test Block"
block.weight = 0
block.connections = []
block.codes = {"function": "print('Hello from block')"}
block.gen_codes = {}
block.ports = []
# Mock properties
properties = [
{"name": "prop1", "value": "value1"},
{"name": "prop2", "value": "value2"}
]
block.get_properties.return_value = properties
diagram.blocks = {1: block}
diagram.connectors = []
# Mock code template
code_template = Mock()
code_template.code_parts = ["function"]
code_template.command = "python $dir_name$index.py"
code_template.name = "test_template"
code_template.description = "Test template"
code_template.properties = []
diagram.code_template = code_template
code_generator = CodeGenerator(diagram)
code_generator._CodeGenerator__prepare_block_list()
# Test that properties are handled correctly
block = code_generator._CodeGenerator__block_list[0]
properties = block.get_properties()
assert len(properties) == 2
assert properties[0]["name"] == "prop1"
assert properties[1]["name"] == "prop2"
def test_code_generator_with_ports(self):
"""Test code generator with block ports."""
# Create mock diagram with ports
diagram = Mock()
# Create block with ports
block = Mock()
block.id = 1
block.type = "test.block"
block.label = "Test Block"
block.weight = 0
block.connections = []
block.codes = {"function": "print('Hello from block')"}
block.gen_codes = {}
# Mock ports
port1 = Mock()
port1.name = "input1"
port1.type = "float"
port1.conn_type = "INPUT"
port2 = Mock()
port2.name = "output1"
port2.type = "float"
port2.conn_type = "OUTPUT"
block.ports = [port1, port2]
block.get_properties.return_value = []
diagram.blocks = {1: block}
diagram.connectors = []
# Mock code template
code_template = Mock()
code_template.code_parts = ["function"]
code_template.command = "python $dir_name$index.py"
code_template.name = "test_template"
code_template.description = "Test template"
code_template.properties = []
diagram.code_template = code_template
code_generator = CodeGenerator(diagram)
code_generator._CodeGenerator__prepare_block_list()
# Test that ports are handled correctly
block = code_generator._CodeGenerator__block_list[0]
assert len(block.ports) == 2
assert block.ports[0].name == "input1"
assert block.ports[1].name == "output1"