Init Commit: Moved bproto to seperate repo
This commit is contained in:
38
test/compiler/ast/test_ast_message.py
Normal file
38
test/compiler/ast/test_ast_message.py
Normal file
@@ -0,0 +1,38 @@
|
||||
import sys
|
||||
import pytest
|
||||
from typing import Any
|
||||
sys.path.append('src/')
|
||||
|
||||
from protocol_components.dtypes import BprotoFieldBaseType
|
||||
from parser.parser import create_ast_parser, bproto_ErrorListener
|
||||
from parser.ast_visitor import BprotoASTVisitor
|
||||
|
||||
|
||||
@pytest.mark.parametrize("source_text,expected_output", [
|
||||
("uint64\n", (BprotoFieldBaseType.UINT64, 1, None)),
|
||||
("float32\n", (BprotoFieldBaseType.FLOAT32, 1, None)),
|
||||
("float32[8]\n", (BprotoFieldBaseType.FLOAT32, 8, None)),
|
||||
])
|
||||
def test_ast_field_dtype_defintion(
|
||||
source_text: str,
|
||||
expected_output: tuple[BprotoFieldBaseType, int, Any]):
|
||||
|
||||
err_listner = bproto_ErrorListener()
|
||||
parser = create_ast_parser(source_text, err_listner)
|
||||
ast = parser.dtype()
|
||||
vinterp = BprotoASTVisitor()
|
||||
|
||||
assert len(err_listner.syntax_error_list) == 0
|
||||
|
||||
res = vinterp.visit(ast)
|
||||
assert isinstance(res, tuple)
|
||||
assert len(res) == 3
|
||||
|
||||
# Correct dtype
|
||||
assert res[0] == expected_output[0].value
|
||||
|
||||
# Correct array size
|
||||
assert res[1] == expected_output[1]
|
||||
|
||||
# Correct refrerence; Should normally be None be Non
|
||||
assert res[2] == expected_output[2]
|
||||
23
test/compiler/ast/test_ast_tag_line.py
Normal file
23
test/compiler/ast/test_ast_tag_line.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import sys
|
||||
sys.path.append('src/')
|
||||
|
||||
from parser.parser import create_ast_parser, bproto_ErrorListener
|
||||
from parser.ast_visitor import BprotoASTVisitor
|
||||
|
||||
|
||||
def test_ast_tag_line():
|
||||
source = "protocol HCP version 25\n"
|
||||
|
||||
err_listner = bproto_ErrorListener()
|
||||
parser = create_ast_parser(source, err_listner)
|
||||
ast = parser.protocol_header()
|
||||
vinterp = BprotoASTVisitor()
|
||||
|
||||
assert len(err_listner.syntax_error_list) == 0
|
||||
|
||||
res = vinterp.visit(ast)
|
||||
assert isinstance(res, tuple)
|
||||
assert len(res) == 2
|
||||
name, version = res
|
||||
assert name == "HCP"
|
||||
assert version == 25
|
||||
26
test/compiler/backend/test_comiler_c.py
Normal file
26
test/compiler/backend/test_comiler_c.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import sys
|
||||
from compiler import BprotoCompiler
|
||||
sys.path.append('src/')
|
||||
|
||||
from errors import BprotoCompilerError
|
||||
from backend.rendering.cBackend import CBackendRenderer
|
||||
from backend.fsOutput import BackendFileSystemOutput
|
||||
|
||||
|
||||
def test_compiler_c_smoke_test():
|
||||
# Load Refernces
|
||||
with open("test/test_protocol.bproto") as f:
|
||||
source_text = f.read()
|
||||
|
||||
# Comile Stuff
|
||||
compiler = BprotoCompiler([
|
||||
CBackendRenderer(".")
|
||||
], "template")
|
||||
|
||||
try:
|
||||
output: BackendFileSystemOutput = compiler.compile(source_text, ".")
|
||||
except BprotoCompilerError:
|
||||
assert False, "This should run througth"
|
||||
|
||||
output.saveToDisk("test/backend_output/c")
|
||||
output.toString()
|
||||
59
test/compiler/backend/test_compiler_python.py
Normal file
59
test/compiler/backend/test_compiler_python.py
Normal file
@@ -0,0 +1,59 @@
|
||||
import sys
|
||||
import pytest
|
||||
from compiler import BprotoCompiler
|
||||
sys.path.append('src/')
|
||||
|
||||
from errors import BprotoCompilerError
|
||||
from backend.rendering.pythonBackend import PythonBackendRenderer
|
||||
from backend.fsOutput import BackendFileSystemOutput
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_compiler_python_against_ref():
|
||||
# Load Refernces
|
||||
with open("test/test_protocol.bproto") as f:
|
||||
source_text = f.read()
|
||||
|
||||
# Comile Stuff
|
||||
compiler = BprotoCompiler([
|
||||
PythonBackendRenderer(".")
|
||||
], "template")
|
||||
|
||||
try:
|
||||
output: BackendFileSystemOutput = compiler.compile(source_text, ".")
|
||||
except BprotoCompilerError:
|
||||
assert False, "This should run througth"
|
||||
|
||||
output.saveToDisk("test/backend_output/python")
|
||||
string_output = output.toString()
|
||||
|
||||
with open("test/reference/python/HCP_protocol_enum.py") as f:
|
||||
assert f.read() == string_output.get("HCP_protocol_enum.py")
|
||||
|
||||
with open("test/reference/python/HCP_protocol_bitfield.py") as f:
|
||||
assert f.read() == string_output.get("HCP_protocol_bitfield.py")
|
||||
|
||||
with open("test/reference/python/HCP_protocol_message_ids.py") as f:
|
||||
assert f.read() == string_output.get("HCP_protocol_message_ids.py")
|
||||
|
||||
with open("test/reference/python/HCP_protocol_packets.py") as f:
|
||||
assert f.read() == string_output.get("HCP_protocol_packets.py")
|
||||
|
||||
|
||||
def test_compiler_python_smoke_test():
|
||||
# Load Refernces
|
||||
with open("test/test_protocol.bproto") as f:
|
||||
source_text = f.read()
|
||||
|
||||
# Comile Stuff
|
||||
compiler = BprotoCompiler([
|
||||
PythonBackendRenderer(".")
|
||||
], "template")
|
||||
|
||||
try:
|
||||
output: BackendFileSystemOutput = compiler.compile(source_text, ".")
|
||||
except BprotoCompilerError:
|
||||
assert False, "This should run througth"
|
||||
|
||||
output.saveToDisk("test/backend_output/python")
|
||||
output.toString()
|
||||
32
test/compiler/backend/test_compiler_txt.py
Normal file
32
test/compiler/backend/test_compiler_txt.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import sys
|
||||
from compiler import BprotoCompiler
|
||||
sys.path.append('src/')
|
||||
|
||||
from errors import BprotoCompilerError
|
||||
from backend.rendering.txtBackend import TxtBackendRenderer
|
||||
from backend.fsOutput import BackendFileSystemOutput
|
||||
|
||||
|
||||
def test_compiler_txt_against_ref():
|
||||
with open("test/test_protocol.bproto") as f:
|
||||
source_text = f.read()
|
||||
|
||||
# Comile Stuff
|
||||
compiler = BprotoCompiler([
|
||||
TxtBackendRenderer(".")
|
||||
], "template")
|
||||
|
||||
try:
|
||||
output: BackendFileSystemOutput = compiler.compile(source_text, ".")
|
||||
except BprotoCompilerError:
|
||||
assert False, "This should run througth"
|
||||
|
||||
string_output = output.toString()
|
||||
output.saveToDisk("test/backend_output/txt")
|
||||
|
||||
# Load Refernces
|
||||
with open("test/reference/txt/protocolSummary.txt") as f:
|
||||
expected_output = f.read()
|
||||
|
||||
assert isinstance(string_output.get("protocolSummary.txt"), str)
|
||||
assert string_output.get("protocolSummary.txt") == expected_output
|
||||
168
test/compiler/backend/test_fsOutput.py
Normal file
168
test/compiler/backend/test_fsOutput.py
Normal file
@@ -0,0 +1,168 @@
|
||||
import sys
|
||||
import os
|
||||
import pytest
|
||||
import shutil
|
||||
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||
sys.path.append('src/')
|
||||
|
||||
from backend.fsOutput import BackendFSOutFile, BackendFSOutStaticConent, BackendFSOutFolder, BackendFSOutputJinjaFile
|
||||
|
||||
TEST_FOLDER = "/tmp/protocolGenerator_test_data"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def filesystem_folder():
|
||||
yield TEST_FOLDER
|
||||
shutil.rmtree(TEST_FOLDER)
|
||||
|
||||
print("Cleanup done")
|
||||
|
||||
|
||||
def test_fsOutput_saveToDisk(filesystem_folder: str):
|
||||
jinja_env = Environment(
|
||||
loader=FileSystemLoader("test/data/templates/"),
|
||||
autoescape=select_autoescape()
|
||||
)
|
||||
|
||||
# Setup
|
||||
root_folder = BackendFSOutFolder("root", [
|
||||
BackendFSOutFile("file1", "some content"),
|
||||
BackendFSOutFile("file2", "some other content"),
|
||||
BackendFSOutFolder("subfolder", [
|
||||
BackendFSOutFile("file3", "some more content #2"),
|
||||
BackendFSOutFile("file4", "even more content"),
|
||||
]),
|
||||
BackendFSOutStaticConent("test/data/static_folder/static_content2.txt", "static_content2.txt"),
|
||||
BackendFSOutStaticConent("test/data/static_content1.txt", "static_content1.txt"),
|
||||
BackendFSOutputJinjaFile(jinja_env, "template.jinja2", "template.txt", {"name": "World"})
|
||||
])
|
||||
|
||||
root_folder.saveToDisk(filesystem_folder)
|
||||
|
||||
# Test Structure
|
||||
assert os.path.isdir(filesystem_folder)
|
||||
assert os.path.isfile(filesystem_folder + "/root/file1")
|
||||
assert os.path.isfile(filesystem_folder + "/root/file2")
|
||||
assert os.path.isdir(filesystem_folder + "/root/subfolder")
|
||||
assert os.path.isfile(filesystem_folder + "/root/subfolder/file3")
|
||||
assert os.path.isfile(filesystem_folder + "/root/subfolder/file4")
|
||||
assert os.path.isfile(filesystem_folder + "/root/static_content1.txt")
|
||||
assert os.path.isfile(filesystem_folder + "/root/static_content2.txt")
|
||||
|
||||
assert os.path.isfile(filesystem_folder + "/root/template.txt")
|
||||
|
||||
# Test Content
|
||||
|
||||
with open(filesystem_folder + "/root/file1", "r") as f:
|
||||
assert f.read() == "some content"
|
||||
|
||||
with open(filesystem_folder + "/root/file2", "r") as f:
|
||||
assert f.read() == "some other content"
|
||||
|
||||
with open(filesystem_folder + "/root/subfolder/file3", "r") as f:
|
||||
assert f.read() == "some more content #2"
|
||||
|
||||
with open(filesystem_folder + "/root/subfolder/file4", "r") as f:
|
||||
assert f.read() == "even more content"
|
||||
|
||||
with open(filesystem_folder + "/root/static_content1.txt", "r") as f:
|
||||
assert f.read() == "test1"
|
||||
|
||||
with open(filesystem_folder + "/root/static_content2.txt", "r") as f:
|
||||
assert f.read() == "test2"
|
||||
|
||||
with open(filesystem_folder + "/root/template.txt", "r") as f:
|
||||
assert f.read() == "Hello World!"
|
||||
|
||||
|
||||
def test_fsOutput_treeString():
|
||||
jinja_env = Environment(
|
||||
loader=FileSystemLoader("test/data/templates/"),
|
||||
autoescape=select_autoescape()
|
||||
)
|
||||
|
||||
root_folder = BackendFSOutFolder("root", [
|
||||
BackendFSOutFile("file1", "some content"),
|
||||
BackendFSOutFile("file2", "some other content"),
|
||||
BackendFSOutFolder("subfolder", [
|
||||
BackendFSOutFile("file3", "some more content #2"),
|
||||
BackendFSOutFile("file4", "even more content"),
|
||||
BackendFSOutputJinjaFile(jinja_env, "template.jinja", "generate", {"name": "Jinja2"})
|
||||
]),
|
||||
BackendFSOutStaticConent("test/data/static_folder", "data"),
|
||||
BackendFSOutputJinjaFile(jinja_env, "template.jinja", None, {"name": "World"})
|
||||
])
|
||||
|
||||
string = root_folder.assemble_file_tree_string()
|
||||
assert string == """└── root
|
||||
├── [file1]
|
||||
├── [file2]
|
||||
├── subfolder
|
||||
│ ├── [file3]
|
||||
│ ├── [file4]
|
||||
│ └── Template [generate]
|
||||
├── Static [data]
|
||||
└── Template [template]
|
||||
"""
|
||||
|
||||
|
||||
def test_fsOutput_toString():
|
||||
jinja_env = Environment(
|
||||
loader=FileSystemLoader("test/data/templates/"),
|
||||
autoescape=select_autoescape()
|
||||
)
|
||||
|
||||
root_folder = BackendFSOutFolder("root", [
|
||||
BackendFSOutFile("file1", "some content"),
|
||||
BackendFSOutFile("file2", "some other content"),
|
||||
BackendFSOutFolder("subfolder", [
|
||||
BackendFSOutFile("file3", "some more content #2"),
|
||||
BackendFSOutFile("file4", "even more content"),
|
||||
BackendFSOutputJinjaFile(jinja_env, "template.jinja2", "generate", {"name": "Jinja2"})
|
||||
]),
|
||||
BackendFSOutStaticConent("test/data/static_folder", "data/static_folder"),
|
||||
BackendFSOutStaticConent("test/data/static_content1.txt", "data"),
|
||||
BackendFSOutputJinjaFile(jinja_env, "template.jinja2", None, {"name": "World"})
|
||||
])
|
||||
|
||||
res = root_folder.toString()
|
||||
|
||||
assert res == {
|
||||
"root/file1": "some content",
|
||||
"root/file2": "some other content",
|
||||
"root/subfolder/file3": "some more content #2",
|
||||
"root/subfolder/file4": "even more content",
|
||||
"root/subfolder/generate": "Hello Jinja2!",
|
||||
"root/data/static_content1.txt": "test1",
|
||||
"root/data/static_folder/static_content2.txt": "test2",
|
||||
"root/template": "Hello World!"
|
||||
}
|
||||
|
||||
|
||||
def test_fsOutput_pathnormalization(filesystem_folder: str):
|
||||
|
||||
root_folder = BackendFSOutFolder(".", [
|
||||
BackendFSOutFolder(".", [
|
||||
BackendFSOutFile("file2", "some other content"),
|
||||
]),
|
||||
BackendFSOutFile("file1", "some content"),
|
||||
])
|
||||
|
||||
# Check if this works for toString
|
||||
res = root_folder.toString()
|
||||
assert res == {
|
||||
"file2": "some other content",
|
||||
"file1": "some content"
|
||||
}
|
||||
|
||||
# Check if this works for saveToDisk
|
||||
root_folder.saveToDisk(filesystem_folder)
|
||||
|
||||
assert os.path.isfile(filesystem_folder + "/file1")
|
||||
assert os.path.isfile(filesystem_folder + "/file2")
|
||||
|
||||
with open(filesystem_folder + "/file1", "r") as f:
|
||||
assert f.read() == "some content"
|
||||
|
||||
with open(filesystem_folder + "/file2", "r") as f:
|
||||
assert f.read() == "some other content"
|
||||
49
test/compiler/name_conversion/test_name_bproto_style.py
Normal file
49
test/compiler/name_conversion/test_name_bproto_style.py
Normal file
@@ -0,0 +1,49 @@
|
||||
import sys
|
||||
sys.path.append('src/')
|
||||
|
||||
from nameHandling.base import ComponentName, NameStyleBproto
|
||||
|
||||
|
||||
def test_component_name():
|
||||
assert ComponentName(["test"]) != 1234
|
||||
assert ComponentName(["test"]) == ComponentName(["test"])
|
||||
assert ComponentName(["test"]) != ComponentName(["test", "test"])
|
||||
assert hash(ComponentName(["test"])) == hash(ComponentName(["test"]))
|
||||
assert hash(ComponentName(["test"])) != hash(ComponentName(["test", "test"]))
|
||||
assert repr(ComponentName(["test"])) == "ComponentName(Test)"
|
||||
assert repr(ComponentName(["test", "test"])) == "ComponentName(Test-Test)"
|
||||
|
||||
|
||||
def test_ComponentNameStyleBproto():
|
||||
assert NameStyleBproto.fromStr("test") == ComponentName(["test"])
|
||||
assert NameStyleBproto.fromStr("ThisIsATest") == ComponentName(["this", "is", "a", "test"])
|
||||
assert NameStyleBproto.fromStr("thisIsATest") == ComponentName(["this", "is", "a", "test"])
|
||||
assert NameStyleBproto.fromStr("this-is-a-test") == ComponentName(["this", "is", "a", "test"])
|
||||
assert NameStyleBproto.fromStr("this-Is-A-test") == ComponentName(["this", "is", "a", "test"])
|
||||
assert NameStyleBproto.fromStr("this_is_a_test") == ComponentName(["this", "is", "a", "test"])
|
||||
assert NameStyleBproto.fromStr("this_Is_a_Test") == ComponentName(["this", "is", "a", "test"])
|
||||
assert NameStyleBproto.fromStr("this-Is_ATest") == ComponentName(["this", "is", "a", "test"])
|
||||
assert NameStyleBproto.fromStr("ThisIs-A_test") == ComponentName(["this", "is", "a", "test"])
|
||||
|
||||
|
||||
def test_ComponentNameStyleBproto_context_enum():
|
||||
assert NameStyleBproto.fromStr("test", "enum") == ComponentName(["test"])
|
||||
assert NameStyleBproto.fromStr("ThisIsATest", "enum") == ComponentName(["thisisatest"])
|
||||
assert NameStyleBproto.fromStr("TESTTEST", "enum") == ComponentName(["testtest"])
|
||||
assert NameStyleBproto.fromStr("TEST_TEST", "enum") == ComponentName(["test", "test"])
|
||||
|
||||
|
||||
def test_ComponentNameStyleBproto_comparison():
|
||||
c = NameStyleBproto.fromStr("ThisIsATest")
|
||||
assert c == "this-is-a-test"
|
||||
assert c == "this_is_a_test"
|
||||
assert c == "thisIsATest"
|
||||
assert c == "ThisIsATest"
|
||||
assert c == "This_Is_A_Test"
|
||||
|
||||
|
||||
def test_ComponentNameStyleBproto_from_Component():
|
||||
c = ComponentName(["this", "is", "a", "test"])
|
||||
c2 = NameStyleBproto.fromStr(c)
|
||||
|
||||
assert c == c2
|
||||
40
test/compiler/name_conversion/test_name_brand_applier.py
Normal file
40
test/compiler/name_conversion/test_name_brand_applier.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import sys
|
||||
sys.path.append('src/')
|
||||
|
||||
from nameHandling.brand_applier import BrandApplier
|
||||
from protocol_components.message import Message
|
||||
from nameHandling.base import ComponentName
|
||||
|
||||
|
||||
def test_name_applier():
|
||||
protocolNameApplier = BrandApplier("brand")
|
||||
|
||||
name = ComponentName(["test"])
|
||||
name = protocolNameApplier.apply(name)
|
||||
assert name == ComponentName(["brand", "test"])
|
||||
|
||||
name = ComponentName(["test", "test"])
|
||||
name = protocolNameApplier.apply(name)
|
||||
assert name == ComponentName(["brand", "test", "test"])
|
||||
|
||||
msg = Message(ComponentName(["this", "is", "a", "test"]), 0)
|
||||
msg: Message = protocolNameApplier.apply(msg)
|
||||
assert msg.name == ComponentName(["brand", "this", "is", "a", "test"])
|
||||
|
||||
protocolNameApplier = BrandApplier(ComponentName(["happy", "brand"]))
|
||||
|
||||
msg = Message(ComponentName(["this", "is", "a", "test"]), 0)
|
||||
msg: Message = protocolNameApplier.apply(msg)
|
||||
assert msg.name == ComponentName(["happy", "brand", "this", "is", "a", "test"])
|
||||
|
||||
try:
|
||||
protocolNameApplier.apply(None)
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert isinstance(e, TypeError)
|
||||
|
||||
try:
|
||||
protocolNameApplier = BrandApplier(None)
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert isinstance(e, TypeError)
|
||||
73
test/compiler/name_conversion/test_name_c_style.py
Normal file
73
test/compiler/name_conversion/test_name_c_style.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import sys
|
||||
sys.path.append('src/')
|
||||
|
||||
from nameHandling.base import ComponentName
|
||||
from protocol_components.protocolFactory import FactoryProtocolDefition
|
||||
from protocol_components.enumeration import FactoryEnumeration, Enumeration
|
||||
from protocol_components.bitfields import FactoryBitfield, Bitfield
|
||||
from protocol_components.dtypes import BprotoFieldBaseType
|
||||
from protocol_components.field import FactoryField
|
||||
from protocol_components.message import FactoryMessage, Message
|
||||
from nameHandling.style.cNameStyle import NameStyleC
|
||||
|
||||
|
||||
def test_style_c_fromStr():
|
||||
try:
|
||||
NameStyleC.fromStr("")
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert isinstance(e, NotImplementedError)
|
||||
|
||||
|
||||
def test_style_c_toStr_enum():
|
||||
assert NameStyleC.toStr(ComponentName(["my", "custom", "Values"]), "enum_name") == "MyCustomValues"
|
||||
assert NameStyleC.toStr(ComponentName(["my", "custom", "enum", "value"]), "enum_item") == "MY_CUSTOM_ENUM_VALUE"
|
||||
assert NameStyleC.toStr(ComponentName(["my", "custom", "class"]), "struct_name") == "MyCustomClass"
|
||||
assert NameStyleC.toStr(ComponentName(["my", "custom", "class", "member"]), "struct_member") == "myCustomClassMember"
|
||||
assert NameStyleC.toStr(ComponentName(["my", "custom", "class"]), "bitfield_name") == "MyCustomClass"
|
||||
assert NameStyleC.toStr(ComponentName(["my", "custom", "class", "member"]), "bitfield_member") == "myCustomClassMember"
|
||||
|
||||
|
||||
def test_style_c_preprocessor():
|
||||
protocol_factory = FactoryProtocolDefition()
|
||||
|
||||
enum_factory = FactoryEnumeration()
|
||||
enum_factory.add_value("first-Value", 1)
|
||||
enum_factory.add_value("second-Important-Value", 2)
|
||||
protocol_factory.add_enum(enum_factory.assemble("mode"))
|
||||
|
||||
bitfield_factory = FactoryBitfield()
|
||||
bitfield_factory.add_bit("FirstBit", 0)
|
||||
bitfield_factory.add_bit("SecondBit", 1)
|
||||
protocol_factory.add_bitfield(bitfield_factory.assemble("bitfield1"))
|
||||
|
||||
message_factory = FactoryMessage()
|
||||
message_factory.add_field(FactoryField().assemble("x", 1, BprotoFieldBaseType.FLOAT32, 2, None))
|
||||
message_factory.add_field(FactoryField().assemble("y", 2, BprotoFieldBaseType.FLOAT32, 2, None))
|
||||
protocol_factory.add_message(message_factory.assemble("cordUpdate", 1))
|
||||
|
||||
protocol = protocol_factory.assemble("ABCP", 5)
|
||||
protocol = NameStyleC.preprocess(protocol)
|
||||
|
||||
enum: Enumeration = list(protocol.enums.values())[0]
|
||||
bitfield: Bitfield = list(protocol.bitfields.values())[0]
|
||||
message: Message = list(protocol.messages.values())[0]
|
||||
|
||||
assert isinstance(enum, Enumeration)
|
||||
assert isinstance(bitfield, Bitfield)
|
||||
assert isinstance(message, Message)
|
||||
|
||||
assert NameStyleC.toStr(enum.name, "enum_name") == "Abcp_enum_Mode"
|
||||
assert NameStyleC.toStr(bitfield.name, "bitfield_name") == "Abcp_bitfield_Bitfield1"
|
||||
assert NameStyleC.toStr(message.name, "struct_name") == "Abcp_message_CordUpdate"
|
||||
|
||||
assert enum.values == {
|
||||
ComponentName(["abcp", "_enum_", "mode", "value", "first", "value"]): 1,
|
||||
ComponentName(["abcp", "_enum_", "mode", "value", "second", "important", "value"]): 2
|
||||
}
|
||||
|
||||
assert bitfield.bits == {
|
||||
ComponentName(["first", "bit"]): 0,
|
||||
ComponentName(["second", "bit"]): 1
|
||||
}
|
||||
|
||||
59
test/compiler/name_conversion/test_name_python_style.py
Normal file
59
test/compiler/name_conversion/test_name_python_style.py
Normal file
@@ -0,0 +1,59 @@
|
||||
import sys
|
||||
sys.path.append('src/')
|
||||
|
||||
from nameHandling.base import ComponentName
|
||||
from protocol_components.protocolFactory import FactoryProtocolDefition
|
||||
from protocol_components.enumeration import FactoryEnumeration, Enumeration
|
||||
from protocol_components.bitfields import FactoryBitfield, Bitfield
|
||||
from protocol_components.dtypes import BprotoFieldBaseType
|
||||
from protocol_components.field import FactoryField
|
||||
from protocol_components.message import FactoryMessage, Message
|
||||
from nameHandling.style.pythonNameStyle import NameStylePython
|
||||
|
||||
|
||||
def test_style_python_fromStr():
|
||||
try:
|
||||
NameStylePython.fromStr("")
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert isinstance(e, NotImplementedError)
|
||||
|
||||
|
||||
def test_style_python_toStr_enum():
|
||||
assert NameStylePython.toStr(ComponentName(["my", "custom", "enum"]), "enum_name") == "MyCustomEnum"
|
||||
assert NameStylePython.toStr(ComponentName(["my", "custom", "enum", "value"]), "enum_item") == "MY_CUSTOM_ENUM_VALUE"
|
||||
assert NameStylePython.toStr(ComponentName(["my", "custom", "class"]), "class_name") == "MyCustomClass"
|
||||
assert NameStylePython.toStr(ComponentName(["my", "custom", "class", "member"]), "class_member") == "my_custom_class_member"
|
||||
|
||||
|
||||
def test_style_python_preprocessor():
|
||||
protocol_factory = FactoryProtocolDefition()
|
||||
|
||||
enum_factory = FactoryEnumeration()
|
||||
enum_factory.add_value("first-Value", 1)
|
||||
enum_factory.add_value("second-Important-Value", 2)
|
||||
protocol_factory.add_enum(enum_factory.assemble("mode"))
|
||||
|
||||
bitfield_factory = FactoryBitfield()
|
||||
bitfield_factory.add_bit("FirstBit", 0)
|
||||
bitfield_factory.add_bit("SecondBit", 1)
|
||||
protocol_factory.add_bitfield(bitfield_factory.assemble("bitfield1"))
|
||||
|
||||
message_factory = FactoryMessage()
|
||||
message_factory.add_field(FactoryField().assemble("x", 1, BprotoFieldBaseType.FLOAT32, 2, None))
|
||||
message_factory.add_field(FactoryField().assemble("y", 2, BprotoFieldBaseType.FLOAT32, 2, None))
|
||||
protocol_factory.add_message(message_factory.assemble("cordUpdate", 1))
|
||||
|
||||
protocol = protocol_factory.assemble("HCPT", 5)
|
||||
protocol = NameStylePython.preprocess(protocol)
|
||||
|
||||
enum: Enumeration = list(protocol.enums.values())[0]
|
||||
bitfield: Bitfield = list(protocol.bitfields.values())[0]
|
||||
message: Message = list(protocol.messages.values())[0]
|
||||
|
||||
assert isinstance(enum, Enumeration)
|
||||
assert isinstance(bitfield, Bitfield)
|
||||
|
||||
assert NameStylePython.toStr(enum.name, "enum_name") == "HcptEnumMode"
|
||||
assert NameStylePython.toStr(bitfield.name, "class_name") == "HcptBitfieldBitfield1"
|
||||
assert NameStylePython.toStr(message.name, "class_name") == "HcptMessageCordUpdate"
|
||||
80
test/compiler/test_bitfields.py
Normal file
80
test/compiler/test_bitfields.py
Normal file
@@ -0,0 +1,80 @@
|
||||
import sys
|
||||
sys.path.append('src/')
|
||||
|
||||
from nameHandling.base import ComponentName
|
||||
from protocol_components.bitfields import FactoryBitfield, Bitfield
|
||||
from errors import BprotoDuplicateNameError, BprotoDuplicateBitfieldPositionError, BprotoCompilerError
|
||||
from nameHandling.base import NameStyleBproto
|
||||
|
||||
|
||||
def test_bitfield_factory():
|
||||
fatory = FactoryBitfield()
|
||||
fatory.add_bit("BIT #1", 0)
|
||||
fatory.add_bit("BIT #4", None)
|
||||
fatory.add_bit("BIT #2", 1)
|
||||
fatory.add_bit("BIT #5", 4)
|
||||
fatory.add_bit("BIT #6", None)
|
||||
fatory.add_bit("BIT #3", 2)
|
||||
fatory.add_bit("BIT #7", 6)
|
||||
|
||||
bitfield: Bitfield = fatory.assemble("TestBitfield")
|
||||
|
||||
assert bitfield.name == "TestBitfield"
|
||||
assert isinstance(bitfield.name, ComponentName)
|
||||
assert isinstance(bitfield.get_name(), ComponentName)
|
||||
assert isinstance(bitfield.get_identifier(), ComponentName)
|
||||
|
||||
assert bitfield.bits == {
|
||||
NameStyleBproto.fromStr("BIT #1"): 0,
|
||||
NameStyleBproto.fromStr("BIT #2"): 1,
|
||||
NameStyleBproto.fromStr("BIT #3"): 2,
|
||||
NameStyleBproto.fromStr("BIT #4"): 3,
|
||||
NameStyleBproto.fromStr("BIT #5"): 4,
|
||||
NameStyleBproto.fromStr("BIT #6"): 5,
|
||||
NameStyleBproto.fromStr("BIT #7"): 6,
|
||||
}
|
||||
assert isinstance(list(bitfield.bits.keys())[0], ComponentName)
|
||||
|
||||
|
||||
def test_bitfield_factory_failure_cases_duplicate_name():
|
||||
factory = FactoryBitfield()
|
||||
|
||||
factory.add_bit("BIT #1", 0)
|
||||
factory.add_bit("BIT #1", 1)
|
||||
factory.add_bit("BIT #2", 2)
|
||||
|
||||
try:
|
||||
factory.assemble("TestBitfield")
|
||||
assert False
|
||||
except BprotoCompilerError as e:
|
||||
assert isinstance(e, BprotoDuplicateNameError)
|
||||
|
||||
|
||||
def test_bitfield_factory_failure_cases_duplicate_position():
|
||||
factory = FactoryBitfield()
|
||||
|
||||
factory.add_bit("BIT #1", 0)
|
||||
factory.add_bit("BIT #2", 1)
|
||||
factory.add_bit("BIT #3", 1)
|
||||
|
||||
try:
|
||||
factory.assemble("TestBitfield")
|
||||
assert False
|
||||
except BprotoCompilerError as e:
|
||||
assert isinstance(e, BprotoDuplicateBitfieldPositionError)
|
||||
|
||||
|
||||
def test_bitfield_size_calculation():
|
||||
bitfield = Bitfield("TestBitfield")
|
||||
|
||||
bitfield.length = 7
|
||||
assert bitfield.get_size_bytes() == 1
|
||||
|
||||
bitfield.length = 0
|
||||
assert bitfield.get_size_bytes() == 1
|
||||
|
||||
bitfield.length = 8
|
||||
assert bitfield.get_size_bytes() == 1
|
||||
|
||||
bitfield.length = 9
|
||||
assert bitfield.get_size_bytes() == 2
|
||||
73
test/compiler/test_deep_copy.py
Normal file
73
test/compiler/test_deep_copy.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from nameHandling.base import ComponentName, NameStyleBproto
|
||||
from nameHandling.style.pythonNameStyle import NameStylePython
|
||||
from protocol_components.enumeration import FactoryEnumeration
|
||||
from copy import deepcopy
|
||||
|
||||
|
||||
def test_deepcopy_component_name():
|
||||
name = ComponentName(["This", "Is", "Some", "text"], NameStylePython, source_string="ThisIsSomeText")
|
||||
|
||||
new_name = deepcopy(name)
|
||||
|
||||
name.name_parts = ["Some", "Other", "Stuff"]
|
||||
name.source_string = "SomeOtherStuff"
|
||||
name.source_style = NameStyleBproto
|
||||
|
||||
# Verify Values did not change
|
||||
assert name.name_parts != new_name.name_parts
|
||||
assert name.source_string != new_name.source_string
|
||||
assert name.source_style != new_name.source_style
|
||||
|
||||
|
||||
def test_deepcopy_enum():
|
||||
old_enum_factory = FactoryEnumeration()
|
||||
old_enum_factory.add_value("Value1", 1)
|
||||
old_enum_factory.add_value("Value2", 2)
|
||||
old_enum_factory.add_value("Value3", 3)
|
||||
old_enum = old_enum_factory.assemble("OldEnum")
|
||||
|
||||
new_enum = deepcopy(old_enum)
|
||||
|
||||
# Check ids
|
||||
assert id(new_enum) != id(old_enum)
|
||||
assert id(new_enum.name) != id(old_enum.name)
|
||||
|
||||
assert id(old_enum.values) != id(new_enum.values)
|
||||
|
||||
old_keys = list(old_enum.values.keys())
|
||||
new_keys = list(new_enum.values.keys())
|
||||
assert id(old_keys[0]) != id(new_keys[0])
|
||||
assert id(old_keys[1]) != id(new_keys[1])
|
||||
assert id(old_keys[2]) != id(new_keys[2])
|
||||
|
||||
|
||||
def test_deepcopy_component_names_memo():
|
||||
name1 = NameStyleBproto.fromStr("Value1")
|
||||
name2 = NameStyleBproto.fromStr("Value2")
|
||||
|
||||
assert id(name1) != id(name2)
|
||||
|
||||
name1_copy = deepcopy(name1)
|
||||
assert isinstance(name1_copy, ComponentName)
|
||||
|
||||
assert name1_copy == name1
|
||||
assert id(name1_copy) != id(name1)
|
||||
|
||||
name1_copy2 = deepcopy(name1, {
|
||||
id(name1): name1_copy,
|
||||
id(name1_copy): name1_copy
|
||||
})
|
||||
|
||||
name1_copy3 = deepcopy(name1_copy, {
|
||||
id(name1): name1_copy,
|
||||
id(name1_copy): name1_copy
|
||||
})
|
||||
|
||||
assert isinstance(name1_copy2, ComponentName)
|
||||
assert isinstance(name1_copy3, ComponentName)
|
||||
|
||||
assert id(name1_copy) == id(name1_copy2)
|
||||
assert id(name1_copy2) != id(name1)
|
||||
|
||||
assert id(name1_copy) == id(name1_copy3)
|
||||
assert id(name1_copy3) != id(name1)
|
||||
228
test/compiler/test_emums.py
Normal file
228
test/compiler/test_emums.py
Normal file
@@ -0,0 +1,228 @@
|
||||
import sys
|
||||
sys.path.append('src/')
|
||||
|
||||
from protocol_components.dtypes import BprotoFieldBaseType
|
||||
from protocol_components.enumeration import FactoryEnumeration, Enumeration
|
||||
from errors import BprotoDuplicateNameError, BprotoDuplicateEnumValueError, BprotoCompilerError, BprotoEnumBitsizeTooLargeError
|
||||
from nameHandling.base import NameStyleBproto, ComponentName
|
||||
|
||||
|
||||
def test_enum_factory():
|
||||
|
||||
factory = FactoryEnumeration()
|
||||
|
||||
factory.add_value("X", 0)
|
||||
factory.add_value("A", 1)
|
||||
factory.add_value("C", 3)
|
||||
factory.add_value("B", 2)
|
||||
factory.add_value("D", None)
|
||||
factory.add_value("E", 5)
|
||||
factory.add_value("F", None)
|
||||
|
||||
enum = factory.assemble("TestEnum")
|
||||
|
||||
assert enum.name == "TestEnum"
|
||||
assert enum.values == {
|
||||
NameStyleBproto.fromStr("X"): 0,
|
||||
NameStyleBproto.fromStr("A"): 1,
|
||||
NameStyleBproto.fromStr("B"): 2,
|
||||
NameStyleBproto.fromStr("C"): 3,
|
||||
NameStyleBproto.fromStr("D"): 4,
|
||||
NameStyleBproto.fromStr("E"): 5,
|
||||
NameStyleBproto.fromStr("F"): 6
|
||||
}
|
||||
|
||||
assert isinstance(enum.name, ComponentName)
|
||||
assert isinstance(enum.get_name(), ComponentName)
|
||||
assert isinstance(enum.get_identifier(), ComponentName)
|
||||
assert isinstance(list(enum.values.keys())[0], ComponentName)
|
||||
|
||||
|
||||
def test_enum_factory_failure_cases_dubplicate_value():
|
||||
|
||||
factory = FactoryEnumeration()
|
||||
|
||||
factory.add_value("X", 0)
|
||||
factory.add_value("Y", 0)
|
||||
factory.add_value("Z", 1)
|
||||
|
||||
try:
|
||||
factory.assemble("TestEnum")
|
||||
assert False
|
||||
except BprotoCompilerError as e:
|
||||
assert isinstance(e, BprotoDuplicateEnumValueError)
|
||||
|
||||
|
||||
def test_enum_factory_failure_cases_duplicate_name():
|
||||
factory = FactoryEnumeration()
|
||||
|
||||
factory.add_value("X", 0)
|
||||
factory.add_value("Y", 1)
|
||||
factory.add_value("Y", 2)
|
||||
|
||||
try:
|
||||
factory.assemble("TestEnum")
|
||||
assert False
|
||||
except BprotoCompilerError as e:
|
||||
assert isinstance(e, BprotoDuplicateNameError)
|
||||
|
||||
|
||||
def test_enum_factory_failure_cases_duplicate_name_and_value():
|
||||
factory = FactoryEnumeration()
|
||||
|
||||
factory.add_value("X", 0)
|
||||
factory.add_value("X", 0)
|
||||
|
||||
try:
|
||||
factory.assemble("TestEnum")
|
||||
assert False
|
||||
except BprotoCompilerError as e:
|
||||
assert isinstance(e, BprotoDuplicateNameError) or isinstance(e, BprotoDuplicateEnumValueError)
|
||||
|
||||
|
||||
def test_enum_sorted():
|
||||
factory = FactoryEnumeration()
|
||||
|
||||
factory.add_value("X", 0)
|
||||
factory.add_value("D", None)
|
||||
factory.add_value("C", 3)
|
||||
factory.add_value("E", 5)
|
||||
factory.add_value("F", None)
|
||||
factory.add_value("B", 2)
|
||||
factory.add_value("A", 1)
|
||||
|
||||
enum = factory.assemble("TestEnum")
|
||||
|
||||
assert list(enum.values.values()) == list(range(7))
|
||||
|
||||
|
||||
def test_enum_size_calc():
|
||||
assert FactoryEnumeration.calculate_bitsize(list(range(17))) == 5
|
||||
assert FactoryEnumeration.calculate_bitsize(list(range(16))) == 4
|
||||
assert FactoryEnumeration.calculate_bitsize(list(range(9))) == 4
|
||||
assert FactoryEnumeration.calculate_bitsize(list(range(8))) == 3
|
||||
assert FactoryEnumeration.calculate_bitsize(list(range(7))) == 3
|
||||
|
||||
assert FactoryEnumeration.calculate_bitsize([1, 2, 31]) == 5
|
||||
assert FactoryEnumeration.calculate_bitsize([1, 32, 2]) == 6
|
||||
assert FactoryEnumeration.calculate_bitsize([127, 0, 2]) == 7
|
||||
|
||||
assert FactoryEnumeration.calculate_bitsize([]) == 1
|
||||
|
||||
|
||||
def test_enum_auxiliary_data_typemap():
|
||||
|
||||
e = Enumeration("TestEnum", 8)
|
||||
assert e.map_auxiliary_datatypes() == BprotoFieldBaseType.UINT8
|
||||
|
||||
e = Enumeration("TestEnum", 16)
|
||||
assert e.map_auxiliary_datatypes() == BprotoFieldBaseType.UINT16
|
||||
|
||||
e = Enumeration("TestEnum", 24)
|
||||
assert e.map_auxiliary_datatypes() == BprotoFieldBaseType.UINT32
|
||||
|
||||
e = Enumeration("TestEnum", 32)
|
||||
assert e.map_auxiliary_datatypes() == BprotoFieldBaseType.UINT32
|
||||
|
||||
e = Enumeration("TestEnum", 64)
|
||||
assert e.map_auxiliary_datatypes() == BprotoFieldBaseType.UINT64
|
||||
|
||||
e = Enumeration("TestEnum", 65)
|
||||
try:
|
||||
e.map_auxiliary_datatypes()
|
||||
assert False
|
||||
except Exception as err:
|
||||
assert isinstance(err, BprotoEnumBitsizeTooLargeError)
|
||||
|
||||
|
||||
def test_enum_size_calculation():
|
||||
# Uint8
|
||||
factory = FactoryEnumeration()
|
||||
for i in range(3):
|
||||
factory.add_value(f"#{i}", i)
|
||||
e = factory.assemble("TestEnum")
|
||||
assert e.get_size_bits() == 8
|
||||
assert e.get_size_bytes() == 1
|
||||
|
||||
factory = FactoryEnumeration()
|
||||
for i in range(2**8):
|
||||
factory.add_value(f"#{i}", i)
|
||||
e = factory.assemble("TestEnum")
|
||||
assert e.get_size_bits() == 8
|
||||
assert e.get_size_bytes() == 1
|
||||
|
||||
# Uint16
|
||||
factory = FactoryEnumeration()
|
||||
for i in range(2**8 + 1):
|
||||
factory.add_value(f"#{i}", i)
|
||||
e = factory.assemble("TestEnum")
|
||||
assert e.get_size_bits() == 16
|
||||
assert e.get_size_bytes() == 2
|
||||
|
||||
factory = FactoryEnumeration()
|
||||
for i in range(2**16):
|
||||
factory.add_value(f"#{i}", i)
|
||||
e = factory.assemble("TestEnum")
|
||||
assert e.get_size_bits() == 16
|
||||
assert e.get_size_bytes() == 2
|
||||
|
||||
# Uint32
|
||||
factory = FactoryEnumeration()
|
||||
for i in range(17):
|
||||
factory.add_value(f"#{i}", i)
|
||||
factory.add_value(f"#{2**16}", 2**16)
|
||||
# We start couinting from 0 -> 2**16 does not fit in 16 bits
|
||||
|
||||
e = factory.assemble("TestEnum")
|
||||
assert e.get_size_bits() == 32
|
||||
assert e.get_size_bytes() == 4
|
||||
|
||||
factory = FactoryEnumeration()
|
||||
for i in range(17):
|
||||
factory.add_value(f"#{i}", i)
|
||||
factory.add_value(f"#{2**32 - 1}", 2**32 - 1)
|
||||
# We start couinting from 0 2**32 - 1 does barely fit in 32 bits
|
||||
|
||||
e = factory.assemble("TestEnum")
|
||||
assert e.get_size_bits() == 32
|
||||
assert e.get_size_bytes() == 4
|
||||
|
||||
# Uint64
|
||||
factory = FactoryEnumeration()
|
||||
for i in range(17):
|
||||
factory.add_value(f"#{i}", i)
|
||||
factory.add_value(f"#{2**32}", 2**32)
|
||||
# We start couinting from 0 -> 2**32 does not fit in 32 bits
|
||||
|
||||
e = factory.assemble("TestEnum")
|
||||
assert e.get_size_bits() == 64
|
||||
assert e.get_size_bytes() == 8
|
||||
|
||||
factory = FactoryEnumeration()
|
||||
for i in range(17):
|
||||
factory.add_value(f"#{i}", i)
|
||||
factory.add_value(f"#{2**64 - 1}", 2**64 - 1)
|
||||
# We start couinting from 0 2**64 - 1 does barely fit in 64 bits
|
||||
|
||||
e = factory.assemble("TestEnum")
|
||||
assert e.get_size_bits() == 64
|
||||
assert e.get_size_bytes() == 8
|
||||
|
||||
# Too large
|
||||
factory = FactoryEnumeration()
|
||||
for i in range(17):
|
||||
factory.add_value(f"#{i}", i)
|
||||
factory.add_value(f"#{2**64}", 2**64)
|
||||
|
||||
# This can cause rounding errors
|
||||
# log2(2**64) ~ log2(2**64 - 1) ~ 64
|
||||
# This is btw not a problem for 2**32
|
||||
# stupid floating point errors
|
||||
|
||||
# We start couinting from 0 -> 2**64 does not fit in 64 bits
|
||||
|
||||
try:
|
||||
e = factory.assemble("TestEnum")
|
||||
assert False
|
||||
except Exception as err:
|
||||
assert isinstance(err, BprotoEnumBitsizeTooLargeError)
|
||||
98
test/compiler/test_field.py
Normal file
98
test/compiler/test_field.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import sys
|
||||
sys.path.append('src/')
|
||||
|
||||
from protocol_components.dtypes import BprotoFieldBaseType, BprotoArrayPolicyViolationError, BprotoUnknownDataTypeError
|
||||
from protocol_components.field import Field, FactoryField, FieldBitfield, FieldBitfieldRef
|
||||
from protocol_components.bitfields import Bitfield
|
||||
from nameHandling.base import ComponentName
|
||||
|
||||
|
||||
def test_field_object():
|
||||
field = Field("field1", 3, BprotoFieldBaseType.UINT64, 4)
|
||||
|
||||
assert field.name == "field1"
|
||||
assert field.pos == 3
|
||||
assert field.type == BprotoFieldBaseType.UINT64
|
||||
assert field.array_size == 4
|
||||
|
||||
assert field.get_identifier() == "field1"
|
||||
assert field.get_name() == "field1"
|
||||
assert field.get_type_name() == "field"
|
||||
assert field.get_size_bytes() == 8 * 4
|
||||
assert field.get_size_bits() == 64 * 4
|
||||
|
||||
|
||||
def test_field_factory():
|
||||
factory = FactoryField()
|
||||
|
||||
field: Field = factory.assemble("field1", 3, BprotoFieldBaseType.UINT64.value, 4, None)
|
||||
|
||||
assert isinstance(field, Field)
|
||||
assert field.name == "field1"
|
||||
assert field.pos == 3
|
||||
assert field.type == BprotoFieldBaseType.UINT64
|
||||
assert field.array_size == 4
|
||||
|
||||
assert isinstance(field.name, ComponentName)
|
||||
assert isinstance(field.get_identifier(), ComponentName)
|
||||
assert isinstance(field.get_name(), ComponentName)
|
||||
assert isinstance(field.get_type_name(), str)
|
||||
|
||||
|
||||
def test_field_factory_errors_invalid_datatype():
|
||||
factory = FactoryField()
|
||||
try:
|
||||
factory.assemble(
|
||||
"field1", 3, "junkDataType", 4, None
|
||||
)
|
||||
assert False
|
||||
except BprotoUnknownDataTypeError:
|
||||
assert True
|
||||
except Exception as e:
|
||||
assert False, f"Unexpected exception: {e}"
|
||||
|
||||
|
||||
def test_field_factory_errors_invalid_array_policy():
|
||||
factory = FactoryField()
|
||||
try:
|
||||
factory.assemble(
|
||||
"field1", 1, BprotoFieldBaseType.BITFIELD, 4, None
|
||||
)
|
||||
assert False
|
||||
except BprotoArrayPolicyViolationError:
|
||||
assert True
|
||||
except Exception as e:
|
||||
assert False, f"Unexpected exception: {e}"
|
||||
|
||||
|
||||
def test_field_factory_bitfield():
|
||||
factory = FactoryField()
|
||||
|
||||
field: FieldBitfield = factory.assemble(
|
||||
"field1", 3, BprotoFieldBaseType.BITFIELD, 1,
|
||||
Bitfield("test")
|
||||
)
|
||||
|
||||
assert isinstance(field, FieldBitfield)
|
||||
assert field.name == "field1"
|
||||
assert field.pos == 3
|
||||
assert field.type == BprotoFieldBaseType.BITFIELD
|
||||
assert field.array_size == 1
|
||||
assert isinstance(field.bitfield, Bitfield)
|
||||
assert field.bitfield.get_name() == "test"
|
||||
|
||||
|
||||
def test_field_factory_bitfield_ref():
|
||||
factory = FactoryField()
|
||||
|
||||
field: FieldBitfield = factory.assemble(
|
||||
"field1", 3, BprotoFieldBaseType.BITFIELD, 1,
|
||||
"test"
|
||||
)
|
||||
|
||||
assert isinstance(field, FieldBitfieldRef)
|
||||
assert field.name == "field1"
|
||||
assert field.pos == 3
|
||||
assert field.type == BprotoFieldBaseType.BITFIELD
|
||||
assert field.array_size == 1
|
||||
assert field.ref == "test"
|
||||
71
test/compiler/test_message.py
Normal file
71
test/compiler/test_message.py
Normal file
@@ -0,0 +1,71 @@
|
||||
import sys
|
||||
sys.path.append('src/')
|
||||
|
||||
from nameHandling.base import ComponentName, NameStyleBproto
|
||||
from protocol_components.message import FactoryMessage, Message
|
||||
from protocol_components.field import FactoryField
|
||||
from errors import BprotoDuplicateNameError, BprotoMessageIDAlreadyUsed
|
||||
|
||||
|
||||
def test_message_factory():
|
||||
factory = FactoryMessage()
|
||||
field1 = FactoryField().assemble("field1", 0, "uint64", 4, None)
|
||||
field2 = FactoryField().assemble("field2", 1, "uint64", 4, None)
|
||||
field3 = FactoryField().assemble("field3", 2, "uint64", 4, None)
|
||||
field4 = FactoryField().assemble("field4", 3, "uint64", 4, None)
|
||||
|
||||
factory.add_field(field3)
|
||||
factory.add_field(field2)
|
||||
factory.add_field(field4)
|
||||
factory.add_field(field1)
|
||||
|
||||
message: Message = factory.assemble("TestMessage", 42)
|
||||
|
||||
assert message.name == "TestMessage"
|
||||
assert isinstance(message.name, ComponentName)
|
||||
assert isinstance(message.get_name(), ComponentName)
|
||||
|
||||
assert message.message_index_number == 42
|
||||
assert message.get_identifier() == 42
|
||||
|
||||
assert message.fields == {
|
||||
NameStyleBproto.fromStr("field1"): field1,
|
||||
NameStyleBproto.fromStr("field2"): field2,
|
||||
NameStyleBproto.fromStr("field3"): field3,
|
||||
NameStyleBproto.fromStr("field4"): field4
|
||||
}
|
||||
|
||||
assert isinstance(list(message.fields.keys())[0], ComponentName)
|
||||
|
||||
assert message.get_size_bytes() == 8 * 4 * 4
|
||||
assert message.get_size_bits() == 64 * 4 * 4
|
||||
|
||||
|
||||
def test_message_factory_error_duplicate_name():
|
||||
field1 = FactoryField().assemble("field1", 0, "uint64", 4, None)
|
||||
field2 = FactoryField().assemble("field1", 1, "uint64", 4, None)
|
||||
|
||||
factory = FactoryMessage()
|
||||
factory.add_field(field1)
|
||||
factory.add_field(field2)
|
||||
|
||||
try:
|
||||
factory.assemble("TestMessage", 42)
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert isinstance(e, BprotoDuplicateNameError)
|
||||
|
||||
|
||||
def test_message_factory_error_duplicate_index():
|
||||
field1 = FactoryField().assemble("field1", 0, "uint64", 4, None)
|
||||
field2 = FactoryField().assemble("field2", 0, "uint64", 4, None)
|
||||
|
||||
factory = FactoryMessage()
|
||||
factory.add_field(field1)
|
||||
factory.add_field(field2)
|
||||
|
||||
try:
|
||||
factory.assemble("TestMessage", 42)
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert isinstance(e, BprotoMessageIDAlreadyUsed)
|
||||
181
test/compiler/test_protocol.py
Normal file
181
test/compiler/test_protocol.py
Normal file
@@ -0,0 +1,181 @@
|
||||
import sys
|
||||
sys.path.append('src/')
|
||||
|
||||
from protocol_components.dtypes import BprotoFieldBaseType
|
||||
from nameHandling.base import ComponentName, NameStyleBproto
|
||||
from protocol_components.message import FactoryMessage
|
||||
from protocol_components.enumeration import FactoryEnumeration, Enumeration
|
||||
from protocol_components.bitfields import FactoryBitfield, Bitfield
|
||||
from protocol_components.protocolFactory import FactoryProtocolDefition
|
||||
from protocol_components.field import FactoryField, Field, FieldEnum, FieldBitfield, FieldEnumRef, FieldBitfieldRef
|
||||
from errors import BprotoUnresolvedReferenceError, BprotoAlreadyDefinedError
|
||||
|
||||
from nameHandling.resolver import ProtocolReferenceResolver
|
||||
|
||||
|
||||
def test_protocol_factory():
|
||||
factory = FactoryProtocolDefition()
|
||||
factory.add_message(FactoryMessage().assemble("Message1", 42))
|
||||
factory.add_message(FactoryMessage().assemble("Message2", 43))
|
||||
|
||||
message_with_fields_factory = FactoryMessage()
|
||||
message_with_fields_factory.add_field(FactoryField().assemble("field1", 0, "uint64", 1, None))
|
||||
message_with_fields_factory.add_field(FactoryField().assemble("enum_ref", 1, BprotoFieldBaseType.ENUM, 1, "Enum1"))
|
||||
message_with_fields_factory.add_field(FactoryField().assemble("bitfield_ref", 2, BprotoFieldBaseType.BITFIELD, 1, "Bitfield2"))
|
||||
|
||||
factory.add_message(
|
||||
message_with_fields_factory.assemble("Message3", 44)
|
||||
)
|
||||
|
||||
factory.add_enum(FactoryEnumeration().assemble("Enum1"))
|
||||
factory.add_enum(FactoryEnumeration().assemble("Enum2"))
|
||||
factory.add_enum(FactoryEnumeration().assemble("Enum3"))
|
||||
|
||||
factory.add_bitfield(FactoryBitfield().assemble("Bitfield1"))
|
||||
factory.add_bitfield(FactoryBitfield().assemble("Bitfield2"))
|
||||
factory.add_bitfield(FactoryBitfield().assemble("Bitfield3"))
|
||||
|
||||
protocol = factory.assemble("TESTPROTOCOL", 1)
|
||||
|
||||
assert protocol.name.name_parts == ["testprotocol"]
|
||||
assert isinstance(protocol.name, ComponentName)
|
||||
assert protocol.version == 1
|
||||
|
||||
assert protocol.messages == {
|
||||
NameStyleBproto.fromStr("Message1"): factory.messages.get(NameStyleBproto.fromStr("Message1")),
|
||||
NameStyleBproto.fromStr("Message2"): factory.messages.get(NameStyleBproto.fromStr("Message2")),
|
||||
NameStyleBproto.fromStr("Message3"): factory.messages.get(NameStyleBproto.fromStr("Message3"))
|
||||
}
|
||||
|
||||
assert protocol.enums == {
|
||||
NameStyleBproto.fromStr("Enum1"): factory.enums.get(NameStyleBproto.fromStr("Enum1")),
|
||||
NameStyleBproto.fromStr("Enum2"): factory.enums.get(NameStyleBproto.fromStr("Enum2")),
|
||||
NameStyleBproto.fromStr("Enum3"): factory.enums.get(NameStyleBproto.fromStr("Enum3"))
|
||||
}
|
||||
|
||||
assert protocol.bitfields == {
|
||||
NameStyleBproto.fromStr("Bitfield1"): factory.bitfields.get(NameStyleBproto.fromStr("Bitfield1")),
|
||||
NameStyleBproto.fromStr("Bitfield2"): factory.bitfields.get(NameStyleBproto.fromStr("Bitfield2")),
|
||||
NameStyleBproto.fromStr("Bitfield3"): factory.bitfields.get(NameStyleBproto.fromStr("Bitfield3"))
|
||||
}
|
||||
|
||||
# Check if references are resolved works
|
||||
assert isinstance(protocol.messages.get(NameStyleBproto.fromStr("Message3")).fields.get(NameStyleBproto.fromStr("enum_ref")), FieldEnum)
|
||||
assert isinstance(protocol.messages.get(NameStyleBproto.fromStr("Message3")).fields.get(NameStyleBproto.fromStr("bitfield_ref")), FieldBitfield)
|
||||
|
||||
|
||||
def test_protocol_resolve_refernces():
|
||||
enum1 = FactoryEnumeration().assemble("Enum1")
|
||||
bitfield1 = FactoryBitfield().assemble("Bitfield1")
|
||||
|
||||
message1Factory = FactoryMessage()
|
||||
message1Factory.add_field(FactoryField().assemble("field1", 0, "uint64", 1, None))
|
||||
message1Factory.add_field(FactoryField().assemble("enum_field", 1, BprotoFieldBaseType.ENUM, 1, enum1))
|
||||
message1Factory.add_field(FactoryField().assemble("enum_ref_field", 2, BprotoFieldBaseType.ENUM, 1, "Enum1"))
|
||||
message1Factory.add_field(FactoryField().assemble("bitfield_field", 3, BprotoFieldBaseType.BITFIELD, 1, bitfield1))
|
||||
message1Factory.add_field(FactoryField().assemble("bitfield_ref_field", 4, BprotoFieldBaseType.BITFIELD, 1, "Bitfield1"))
|
||||
message1 = message1Factory.assemble("Message1", 42)
|
||||
|
||||
# Check if message is correctly assembled
|
||||
assert isinstance(message1.fields.get(NameStyleBproto.fromStr("field1")), Field)
|
||||
assert message1.fields.get(NameStyleBproto.fromStr("field1")).type == BprotoFieldBaseType.UINT64
|
||||
assert message1.fields.get(NameStyleBproto.fromStr("field1")).array_size == 1
|
||||
assert message1.fields.get(NameStyleBproto.fromStr("field1")).ref is None
|
||||
assert isinstance(message1.fields.get(NameStyleBproto.fromStr("field1")).ref, type(None))
|
||||
|
||||
assert isinstance(message1.fields.get(NameStyleBproto.fromStr("enum_field")), FieldEnum)
|
||||
assert message1.fields.get(NameStyleBproto.fromStr("enum_field")).type == BprotoFieldBaseType.ENUM
|
||||
assert isinstance(message1.fields.get(NameStyleBproto.fromStr("enum_field")).enum, Enumeration)
|
||||
assert message1.fields.get(NameStyleBproto.fromStr("enum_field")).enum == enum1
|
||||
|
||||
assert isinstance(message1.fields.get(NameStyleBproto.fromStr("enum_ref_field")), FieldEnumRef)
|
||||
assert message1.fields.get(NameStyleBproto.fromStr("enum_ref_field")).type == BprotoFieldBaseType.ENUM
|
||||
assert message1.fields.get(NameStyleBproto.fromStr("enum_ref_field")).ref == "Enum1"
|
||||
|
||||
assert isinstance(message1.fields.get(NameStyleBproto.fromStr("bitfield_field")), FieldBitfield)
|
||||
assert message1.fields.get(NameStyleBproto.fromStr("bitfield_field")).type == BprotoFieldBaseType.BITFIELD
|
||||
assert isinstance(message1.fields.get(NameStyleBproto.fromStr("bitfield_field")).bitfield, Bitfield)
|
||||
assert message1.fields.get(NameStyleBproto.fromStr("bitfield_field")).bitfield == bitfield1
|
||||
|
||||
assert isinstance(message1.fields.get(NameStyleBproto.fromStr("bitfield_ref_field")), FieldBitfieldRef)
|
||||
assert message1.fields.get(NameStyleBproto.fromStr("bitfield_ref_field")).type == BprotoFieldBaseType.BITFIELD
|
||||
assert message1.fields.get(NameStyleBproto.fromStr("bitfield_ref_field")).ref == "Bitfield1"
|
||||
|
||||
factory = FactoryProtocolDefition()
|
||||
factory.add_message(message1)
|
||||
factory.add_enum(enum1)
|
||||
factory.add_bitfield(bitfield1)
|
||||
protocol = factory.assemble("TestProtocol", 1)
|
||||
|
||||
# Check if references are resolved works
|
||||
|
||||
resolver = ProtocolReferenceResolver(protocol)
|
||||
resolver.resolve_refrence_protocol()
|
||||
|
||||
assert protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("enum_field")).type == BprotoFieldBaseType.ENUM
|
||||
assert isinstance(protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("enum_field")), FieldEnum)
|
||||
assert protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("enum_field")).enum == enum1
|
||||
|
||||
assert protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("enum_ref_field")).type == BprotoFieldBaseType.ENUM
|
||||
assert isinstance(protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("enum_ref_field")), FieldEnum)
|
||||
assert protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("enum_ref_field")).enum == enum1
|
||||
|
||||
assert protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("bitfield_field")).type == BprotoFieldBaseType.BITFIELD
|
||||
assert isinstance(protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("bitfield_field")), FieldBitfield)
|
||||
assert protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("bitfield_field")).bitfield == bitfield1
|
||||
|
||||
assert protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("bitfield_ref_field")).type == BprotoFieldBaseType.BITFIELD
|
||||
assert isinstance(protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("bitfield_ref_field")), FieldBitfield)
|
||||
assert protocol.messages.get(NameStyleBproto.fromStr("Message1")).fields.get(NameStyleBproto.fromStr("bitfield_ref_field")).bitfield == bitfield1
|
||||
|
||||
|
||||
def test_protocol_resolve_refernces_unknown_refernces():
|
||||
message1Factory = FactoryMessage()
|
||||
message1Factory.add_field(FactoryField().assemble("field1", 0, "uint64", 1, None))
|
||||
message1Factory.add_field(FactoryField().assemble("enum_ref_field", 1, BprotoFieldBaseType.ENUM, 1, "Enum1"))
|
||||
message1Factory.add_field(FactoryField().assemble("bitfield_ref_field", 2, BprotoFieldBaseType.BITFIELD, 1, "Bitfield1",))
|
||||
message1 = message1Factory.assemble("Message1", 42)
|
||||
|
||||
factory = FactoryProtocolDefition()
|
||||
factory.add_message(message1)
|
||||
|
||||
try:
|
||||
factory.assemble("TestProtocol", 1)
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert isinstance(e, BprotoUnresolvedReferenceError)
|
||||
|
||||
try:
|
||||
factory.assemble("TestProtocol", 1)
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert isinstance(e, BprotoUnresolvedReferenceError)
|
||||
|
||||
|
||||
def test_protocol_factory_already_define_error():
|
||||
factory = FactoryProtocolDefition()
|
||||
factory.add_message(FactoryMessage().assemble("Message1", 42))
|
||||
try:
|
||||
factory.add_message(FactoryMessage().assemble("Message1", 42))
|
||||
factory.assemble("A", 1)
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert isinstance(e, BprotoAlreadyDefinedError)
|
||||
|
||||
factory = FactoryProtocolDefition()
|
||||
factory.add_enum(FactoryEnumeration().assemble("Enum1"))
|
||||
try:
|
||||
factory.assemble("A", 1)
|
||||
factory.add_enum(FactoryEnumeration().assemble("Enum1"))
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert isinstance(e, BprotoAlreadyDefinedError)
|
||||
|
||||
factory = FactoryProtocolDefition()
|
||||
factory.add_bitfield(FactoryBitfield().assemble("Bitfield1"))
|
||||
try:
|
||||
factory.add_bitfield(FactoryBitfield().assemble("Bitfield1"))
|
||||
factory.assemble("A", 1)
|
||||
assert False
|
||||
except Exception as e:
|
||||
assert isinstance(e, BprotoAlreadyDefinedError)
|
||||
Reference in New Issue
Block a user