336 lines
12 KiB
Python
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" |