Files
PeakRDL-BusDecoder/tests/unit/test_body.py
Arnav Sacheti 93276ff616 fix (#13)
* fix

* fix pyrefly

* remove tests

* Update tests/unit/test_exporter.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update src/peakrdl_busdecoder/listener.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update tests/unit/test_exporter.py

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix iter

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-26 14:40:03 -07:00

286 lines
8.5 KiB
Python

"""Tests for body classes used in code generation."""
import pytest
from peakrdl_busdecoder.body import (
Body,
CombinationalBody,
ForLoopBody,
IfBody,
StructBody,
)
class TestBody:
"""Test the base Body class."""
def test_empty_body(self):
"""Test empty body returns empty string."""
body = Body()
assert str(body) == ""
assert not body # Should be falsy when empty
def test_add_single_line(self):
"""Test adding a single line to body."""
body = Body()
body += "line1"
assert str(body) == "line1"
assert body # Should be truthy when not empty
def test_add_multiple_lines(self):
"""Test adding multiple lines to body."""
body = Body()
body += "line1"
body += "line2"
body += "line3"
expected = "line1\nline2\nline3"
assert str(body) == expected
def test_add_returns_self(self):
"""Test that add operation returns self for chaining."""
body = Body()
body += "line1"
body += "line2"
# Chaining works because += returns self
assert len(body.lines) == 2
def test_add_nested_body(self):
"""Test adding another body as a line."""
outer = Body()
inner = Body()
inner += "inner1"
inner += "inner2"
outer += "outer1"
outer += inner
outer += "outer2"
expected = "outer1\ninner1\ninner2\nouter2"
assert str(outer) == expected
class TestForLoopBody:
"""Test the ForLoopBody class."""
def test_genvar_for_loop(self):
"""Test genvar-style for loop."""
body = ForLoopBody("genvar", "i", 4)
body += "statement1;"
body += "statement2;"
result = str(body)
assert "for (genvar i = 0; i < 4; i++)" in result
assert "statement1;" in result
assert "statement2;" in result
assert "end" in result
def test_int_for_loop(self):
"""Test int-style for loop."""
body = ForLoopBody("int", "j", 8)
body += "assignment = value;"
result = str(body)
assert "for (int j = 0; j < 8; j++)" in result
assert "assignment = value;" in result
assert "end" in result
def test_empty_for_loop(self):
"""Test empty for loop."""
body = ForLoopBody("genvar", "k", 2)
result = str(body)
# Empty for loop should still have structure
assert "for (genvar k = 0; k < 2; k++)" in result
def test_nested_for_loops(self):
"""Test nested for loops."""
outer = ForLoopBody("genvar", "i", 3)
inner = ForLoopBody("genvar", "j", 2)
inner += "nested_statement;"
outer += inner
result = str(outer)
assert "for (genvar i = 0; i < 3; i++)" in result
assert "for (genvar j = 0; j < 2; j++)" in result
assert "nested_statement;" in result
class TestIfBody:
"""Test the IfBody class."""
def test_simple_if(self):
"""Test simple if statement."""
body = IfBody()
with body.cm("condition1") as b:
b += "statement1;"
result = str(body)
assert "if (condition1)" in result
assert "statement1;" in result
assert "end" in result
def test_if_else(self):
"""Test if-else statement."""
body = IfBody()
with body.cm("condition1") as b:
b += "if_statement;"
with body.cm(None) as b: # None for else
b += "else_statement;"
result = str(body)
assert "if (condition1)" in result
assert "if_statement;" in result
assert "else" in result
assert "else_statement;" in result
def test_if_elif_else(self):
"""Test if-elif-else chain."""
body = IfBody()
with body.cm("condition1") as b:
b += "statement1;"
with body.cm("condition2") as b:
b += "statement2;"
with body.cm(None) as b: # None for else
b += "statement3;"
result = str(body)
assert "if (condition1)" in result
assert "statement1;" in result
assert "else if (condition2)" in result
assert "statement2;" in result
assert "else" in result
assert "statement3;" in result
def test_multiple_elif(self):
"""Test multiple elif statements."""
body = IfBody()
with body.cm("cond1") as b:
b += "stmt1;"
with body.cm("cond2") as b:
b += "stmt2;"
with body.cm("cond3") as b:
b += "stmt3;"
result = str(body)
assert "if (cond1)" in result
assert "else if (cond2)" in result
assert "else if (cond3)" in result
def test_empty_if_branches(self):
"""Test if statement with empty branches."""
body = IfBody()
with body.cm("condition"):
pass
result = str(body)
assert "if (condition)" in result
def test_nested_if(self):
"""Test nested if statements."""
outer = IfBody()
with outer.cm("outer_cond") as outer_body:
inner = IfBody()
with inner.cm("inner_cond") as inner_body:
inner_body += "nested_statement;"
outer_body += inner
result = str(outer)
assert "if (outer_cond)" in result
assert "if (inner_cond)" in result
assert "nested_statement;" in result
class TestCombinationalBody:
"""Test the CombinationalBody class."""
def test_simple_combinational_block(self):
"""Test simple combinational block."""
body = CombinationalBody()
body += "assign1 = value1;"
body += "assign2 = value2;"
result = str(body)
assert "always_comb" in result
assert "begin" in result
assert "assign1 = value1;" in result
assert "assign2 = value2;" in result
assert "end" in result
def test_empty_combinational_block(self):
"""Test empty combinational block."""
body = CombinationalBody()
result = str(body)
assert "always_comb" in result
assert "begin" in result
assert "end" in result
def test_combinational_with_if_statement(self):
"""Test combinational block with if statement."""
cb = CombinationalBody()
ifb = IfBody()
with ifb.cm("condition") as b:
b += "assignment = value;"
cb += ifb
result = str(cb)
assert "always_comb" in result
assert "if (condition)" in result
assert "assignment = value;" in result
class TestStructBody:
"""Test the StructBody class."""
def test_simple_struct(self):
"""Test simple struct definition."""
body = StructBody("my_struct_t", packed=True, typedef=True)
body += "logic [7:0] field1;"
body += "logic field2;"
result = str(body)
assert "typedef struct packed" in result
assert "my_struct_t" in result
assert "logic [7:0] field1;" in result
assert "logic field2;" in result
def test_unpacked_struct(self):
"""Test unpacked struct definition."""
body = StructBody("unpacked_t", packed=False, typedef=True)
body += "int field1;"
result = str(body)
assert "typedef struct" in result
assert "packed" not in result or "typedef struct {" in result
assert "unpacked_t" in result
def test_struct_without_typedef(self):
"""Test struct without typedef."""
body = StructBody("my_struct", packed=True, typedef=False)
body += "logic field;"
result = str(body)
# When typedef=False, packed is not used
assert "struct {" in result
assert "typedef" not in result
assert "my_struct" in result
def test_empty_struct(self):
"""Test empty struct."""
body = StructBody("empty_t", packed=True, typedef=True)
result = str(body)
assert "typedef struct packed" in result
assert "empty_t" in result
def test_nested_struct(self):
"""Test struct with nested struct."""
outer = StructBody("outer_t", packed=True, typedef=True)
inner = StructBody("inner_t", packed=True, typedef=True)
inner += "logic field1;"
outer += "logic field2;"
outer += str(inner) # Include inner struct as a string
result = str(outer)
assert "outer_t" in result
assert "field2;" in result
# Inner struct should appear in the string
assert "inner_t" in result