diff --git a/test/ZoneCodeGeneratorTests/Parsing/C_Header/Tests/TestStructTest.cs b/test/ZoneCodeGeneratorTests/Parsing/C_Header/Tests/TestStructTest.cs new file mode 100644 index 00000000..85964ff5 --- /dev/null +++ b/test/ZoneCodeGeneratorTests/Parsing/C_Header/Tests/TestStructTest.cs @@ -0,0 +1,181 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using ZoneCodeGenerator.Domain; +using ZoneCodeGenerator.Parsing; +using ZoneCodeGenerator.Parsing.C_Header; +using ZoneCodeGenerator.Parsing.C_Header.Blocks; +using ZoneCodeGenerator.Parsing.C_Header.Tests; +using ZoneCodeGenerator.Parsing.Testing; + +namespace ZoneCodeGeneratorTests.Parsing.C_Header.Tests +{ + [TestClass] + public class TestStructTest + { + private Mock parserStateMock; + private List typesOfState; + private Namespace currentNamespace; + private BlockStruct pushedStruct; + + private Mock lexerMock; + private int tokenOffset; + private List tokens; + + [TestInitialize] + public void Setup() + { + currentNamespace = new Namespace(); + + parserStateMock = new Mock(); + typesOfState = new List(); + parserStateMock.SetupGet(state => state.CurrentNamespace) + .Returns(() => currentNamespace); + parserStateMock.Setup(state => state.PushBlock(It.IsAny())) + .Callback((Block block) => pushedStruct = block as BlockStruct); + parserStateMock.Setup(state => state.FindType(It.IsAny())) + .Returns((string query) => typesOfState.FirstOrDefault(type => type.FullName.Equals(query))); + + pushedStruct = null; + tokenOffset = 0; + tokens = new List(); + lexerMock = new Mock(); + + lexerMock.Setup(lexer => lexer.PeekToken(It.IsAny())) + .Returns((int index) => tokens.ElementAtOrDefault(index + tokenOffset)); + lexerMock.Setup(lexer => lexer.NextToken()) + .Returns(() => tokens.ElementAtOrDefault(tokenOffset++)); + lexerMock.Setup(lexer => lexer.SkipTokens(It.IsAny())) + .Callback((int count) => tokenOffset += count); + } + + [TestMethod] + public void EnsureAcceptsSimpleStructStatement() + { + tokens.AddRange(new List + { + "struct", "{" + }); + + var test = new TestStruct(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(2, test.ConsumedTokenCount); + + Assert.IsNotNull(pushedStruct); + Assert.IsFalse(pushedStruct.IsTypedef); + } + + [TestMethod] + public void EnsureAcceptsNamedStructStatement() + { + tokens.AddRange(new List + { + "struct", "test_struct", "{" + }); + + var test = new TestStruct(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(3, test.ConsumedTokenCount); + + Assert.IsNotNull(pushedStruct); + Assert.IsFalse(pushedStruct.IsTypedef); + Assert.AreEqual("test_struct", pushedStruct.Name); + } + + [TestMethod] + public void EnsureCanBeTypedef() + { + tokens.AddRange(new List + { + "typedef", "struct", "test_struct", "{" + }); + + var test = new TestStruct(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(4, test.ConsumedTokenCount); + + Assert.IsNotNull(pushedStruct); + Assert.IsTrue(pushedStruct.IsTypedef); + Assert.AreEqual("test_struct", pushedStruct.Name); + } + + [TestMethod] + public void EnsureAcceptsCustomSpecifiedAlignment() + { + tokens.AddRange(new List + { + "struct", "__declspec", "(", "align", "(", "64", ")", ")", "test_struct", "{" + }); + + var test = new TestStruct(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(10, test.ConsumedTokenCount); + + Assert.IsNotNull(pushedStruct); + Assert.IsFalse(pushedStruct.IsTypedef); + Assert.AreEqual("test_struct", pushedStruct.Name); + Assert.AreEqual(64, pushedStruct.CustomAlignment); + } + + [TestMethod] + public void EnsureCanSpecifyParent() + { + tokens.AddRange(new List + { + "struct", "test_struct", ":", "test", ":", ":", "parent", "{" + }); + + var test = new TestStruct(); + + var parent = new DataTypeStruct("test", "parent", 4); + var parentEntry = new Variable("test_int", new TypeDeclaration(DataTypeBaseType.INT, new List())); + parent.Members.Add(parentEntry); + typesOfState.Add(parent); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(8, test.ConsumedTokenCount); + + Assert.IsNotNull(pushedStruct); + Assert.IsFalse(pushedStruct.IsTypedef); + Assert.AreEqual("test_struct", pushedStruct.Name); + Assert.AreEqual(1, pushedStruct.Variables.Count); + Assert.AreEqual(parentEntry, pushedStruct.Variables[0]); + } + + [TestMethod] + public void EnsureFailsWhenParentTypeCannotBeFound() + { + tokens.AddRange(new List + { + "struct", "test_struct", ":", "test", ":", ":", "parent", "{" + }); + + var test = new TestStruct(); + + Assert.ThrowsException( + () => test.PerformTest(parserStateMock.Object, lexerMock.Object)); + } + + [TestMethod] + public void EnsureFailsWhenParentTypeIsNotDataTypeWithMembers() + { + tokens.AddRange(new List + { + "struct", "test_struct", ":", "test", ":", ":", "parent", "{" + }); + + var test = new TestStruct(); + + var testEnum = new DataTypeEnum("test", "parent", DataTypeBaseType.INT); + typesOfState.Add(testEnum); + + Assert.ThrowsException( + () => test.PerformTest(parserStateMock.Object, lexerMock.Object)); + } + } +} diff --git a/test/ZoneCodeGeneratorTests/Parsing/C_Header/Tests/TestUnionTest.cs b/test/ZoneCodeGeneratorTests/Parsing/C_Header/Tests/TestUnionTest.cs new file mode 100644 index 00000000..9e397d1f --- /dev/null +++ b/test/ZoneCodeGeneratorTests/Parsing/C_Header/Tests/TestUnionTest.cs @@ -0,0 +1,181 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using ZoneCodeGenerator.Domain; +using ZoneCodeGenerator.Parsing; +using ZoneCodeGenerator.Parsing.C_Header; +using ZoneCodeGenerator.Parsing.C_Header.Blocks; +using ZoneCodeGenerator.Parsing.C_Header.Tests; +using ZoneCodeGenerator.Parsing.Testing; + +namespace ZoneCodeGeneratorTests.Parsing.C_Header.Tests +{ + [TestClass] + public class TestUnionTest + { + private Mock parserStateMock; + private List typesOfState; + private Namespace currentNamespace; + private BlockUnion pushedUnion; + + private Mock lexerMock; + private int tokenOffset; + private List tokens; + + [TestInitialize] + public void Setup() + { + currentNamespace = new Namespace(); + + parserStateMock = new Mock(); + typesOfState = new List(); + parserStateMock.SetupGet(state => state.CurrentNamespace) + .Returns(() => currentNamespace); + parserStateMock.Setup(state => state.PushBlock(It.IsAny())) + .Callback((Block block) => pushedUnion = block as BlockUnion); + parserStateMock.Setup(state => state.FindType(It.IsAny())) + .Returns((string query) => typesOfState.FirstOrDefault(type => type.FullName.Equals(query))); + + pushedUnion = null; + tokenOffset = 0; + tokens = new List(); + lexerMock = new Mock(); + + lexerMock.Setup(lexer => lexer.PeekToken(It.IsAny())) + .Returns((int index) => tokens.ElementAtOrDefault(index + tokenOffset)); + lexerMock.Setup(lexer => lexer.NextToken()) + .Returns(() => tokens.ElementAtOrDefault(tokenOffset++)); + lexerMock.Setup(lexer => lexer.SkipTokens(It.IsAny())) + .Callback((int count) => tokenOffset += count); + } + + [TestMethod] + public void EnsureAcceptsSimpleUnionStatement() + { + tokens.AddRange(new List + { + "union", "{" + }); + + var test = new TestUnion(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(2, test.ConsumedTokenCount); + + Assert.IsNotNull(pushedUnion); + Assert.IsFalse(pushedUnion.IsTypedef); + } + + [TestMethod] + public void EnsureAcceptsNamedUnionStatement() + { + tokens.AddRange(new List + { + "union", "test_union", "{" + }); + + var test = new TestUnion(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(3, test.ConsumedTokenCount); + + Assert.IsNotNull(pushedUnion); + Assert.IsFalse(pushedUnion.IsTypedef); + Assert.AreEqual("test_union", pushedUnion.Name); + } + + [TestMethod] + public void EnsureCanBeTypedef() + { + tokens.AddRange(new List + { + "typedef", "union", "test_union", "{" + }); + + var test = new TestUnion(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(4, test.ConsumedTokenCount); + + Assert.IsNotNull(pushedUnion); + Assert.IsTrue(pushedUnion.IsTypedef); + Assert.AreEqual("test_union", pushedUnion.Name); + } + + [TestMethod] + public void EnsureAcceptsCustomSpecifiedAlignment() + { + tokens.AddRange(new List + { + "union", "__declspec", "(", "align", "(", "64", ")", ")", "test_union", "{" + }); + + var test = new TestUnion(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(10, test.ConsumedTokenCount); + + Assert.IsNotNull(pushedUnion); + Assert.IsFalse(pushedUnion.IsTypedef); + Assert.AreEqual("test_union", pushedUnion.Name); + Assert.AreEqual(64, pushedUnion.CustomAlignment); + } + + [TestMethod] + public void EnsureCanSpecifyParent() + { + tokens.AddRange(new List + { + "union", "test_union", ":", "test", ":", ":", "parent", "{" + }); + + var test = new TestUnion(); + + var parent = new DataTypeUnion("test", "parent", 4); + var parentEntry = new Variable("test_int", new TypeDeclaration(DataTypeBaseType.INT, new List())); + parent.Members.Add(parentEntry); + typesOfState.Add(parent); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(8, test.ConsumedTokenCount); + + Assert.IsNotNull(pushedUnion); + Assert.IsFalse(pushedUnion.IsTypedef); + Assert.AreEqual("test_union", pushedUnion.Name); + Assert.AreEqual(1, pushedUnion.Variables.Count); + Assert.AreEqual(parentEntry, pushedUnion.Variables[0]); + } + + [TestMethod] + public void EnsureFailsWhenParentTypeCannotBeFound() + { + tokens.AddRange(new List + { + "union", "test_union", ":", "test", ":", ":", "parent", "{" + }); + + var test = new TestUnion(); + + Assert.ThrowsException( + () => test.PerformTest(parserStateMock.Object, lexerMock.Object)); + } + + [TestMethod] + public void EnsureFailsWhenParentTypeIsNotDataTypeWithMembers() + { + tokens.AddRange(new List + { + "union", "test_union", ":", "test", ":", ":", "parent", "{" + }); + + var test = new TestUnion(); + + var testEnum = new DataTypeEnum("test", "parent", DataTypeBaseType.INT); + typesOfState.Add(testEnum); + + Assert.ThrowsException( + () => test.PerformTest(parserStateMock.Object, lexerMock.Object)); + } + } +} diff --git a/test/ZoneCodeGeneratorTests/Parsing/C_Header/Tests/TestVariableTest.cs b/test/ZoneCodeGeneratorTests/Parsing/C_Header/Tests/TestVariableTest.cs new file mode 100644 index 00000000..c8610339 --- /dev/null +++ b/test/ZoneCodeGeneratorTests/Parsing/C_Header/Tests/TestVariableTest.cs @@ -0,0 +1,443 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; +using ZoneCodeGenerator.Domain; +using ZoneCodeGenerator.Parsing; +using ZoneCodeGenerator.Parsing.C_Header; +using ZoneCodeGenerator.Parsing.C_Header.Blocks; +using ZoneCodeGenerator.Parsing.C_Header.Tests; +using ZoneCodeGenerator.Parsing.Testing; + +namespace ZoneCodeGeneratorTests.Parsing.C_Header.Tests +{ + [TestClass] + public class TestVariableTest + { + private Mock parserStateMock; + private List typesOfState; + private Namespace currentNamespace; + private Stack blocks; + + private Mock lexerMock; + private int tokenOffset; + private List tokens; + + [TestInitialize] + public void Setup() + { + currentNamespace = new Namespace(); + blocks = new Stack(); + + parserStateMock = new Mock(); + typesOfState = new List(); + parserStateMock.SetupGet(state => state.CurrentNamespace) + .Returns(() => currentNamespace); + parserStateMock.SetupGet(state => state.CurrentBlock) + .Returns(() => blocks.Peek()); + parserStateMock.Setup(state => state.FindType(It.IsAny())) + .Returns((string query) => typesOfState.Concat(DataTypeBaseType.BASE_TYPES).FirstOrDefault(type => type.FullName.Equals(query))); + + tokenOffset = 0; + tokens = new List(); + lexerMock = new Mock(); + + lexerMock.Setup(lexer => lexer.PeekToken(It.IsAny())) + .Returns((int index) => tokens.ElementAtOrDefault(index + tokenOffset)); + lexerMock.Setup(lexer => lexer.NextToken()) + .Returns(() => tokens.ElementAtOrDefault(tokenOffset++)); + lexerMock.Setup(lexer => lexer.SkipTokens(It.IsAny())) + .Callback((int count) => tokenOffset += count); + } + + [TestMethod] + public void EnsureAcceptsSimpleVariableStatement() + { + tokens.AddRange(new List + { + "int", "test", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(3, test.ConsumedTokenCount); + + Assert.AreEqual(1, block.Variables.Count); + + var variable = block.Variables[0]; + + Assert.AreEqual("test", variable.Name); + Assert.IsNull(variable.AlignmentOverride); + Assert.IsFalse(variable.VariableType.IsConst); + Assert.IsFalse(variable.VariableType.HasCustomBitSize); + + Assert.AreEqual(0, variable.VariableType.References.Count); + Assert.AreEqual(DataTypeBaseType.INT, variable.VariableType.Type); + } + + [TestMethod] + public void EnsureAcceptsCustomStructures() + { + tokens.AddRange(new List + { + "test_namespace", ":", ":", "customStruct", "hey_ho", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var customStruct = new DataTypeStruct("test_namespace", "customStruct", 4); + typesOfState.Add(customStruct); + + var test = new TestVariable(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(6, test.ConsumedTokenCount); + + Assert.AreEqual(1, block.Variables.Count); + + var variable = block.Variables[0]; + + Assert.AreEqual("hey_ho", variable.Name); + Assert.IsNull(variable.AlignmentOverride); + Assert.IsFalse(variable.VariableType.IsConst); + Assert.IsFalse(variable.VariableType.HasCustomBitSize); + + Assert.AreEqual(0, variable.VariableType.References.Count); + Assert.AreEqual(customStruct, variable.VariableType.Type); + } + + [TestMethod] + public void EnsureFailsWhenTypeCannotBeFound() + { + tokens.AddRange(new List + { + "test_namespace", ":", ":", "customStruct", "hey_ho", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.ThrowsException( + () => test.PerformTest(parserStateMock.Object, lexerMock.Object)); + } + + [TestMethod] + public void EnsureCanHandlePointers() + { + tokens.AddRange(new List + { + "float", "*", "santa_claus", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(4, test.ConsumedTokenCount); + + Assert.AreEqual(1, block.Variables.Count); + + var variable = block.Variables[0]; + + Assert.AreEqual("santa_claus", variable.Name); + Assert.IsNull(variable.AlignmentOverride); + Assert.IsFalse(variable.VariableType.IsConst); + Assert.IsFalse(variable.VariableType.HasCustomBitSize); + + Assert.AreEqual(1, variable.VariableType.References.Count); + Assert.IsInstanceOfType(variable.VariableType.References[0], typeof(ReferenceTypePointer)); + + Assert.AreEqual(DataTypeBaseType.FLOAT, variable.VariableType.Type); + } + + [TestMethod] + public void EnsureCanHandleMultiPointers() + { + tokens.AddRange(new List + { + "float", "*", "*", "*", "*", "santa_claus", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(7, test.ConsumedTokenCount); + + Assert.AreEqual(1, block.Variables.Count); + + var variable = block.Variables[0]; + + Assert.AreEqual("santa_claus", variable.Name); + Assert.IsNull(variable.AlignmentOverride); + Assert.IsFalse(variable.VariableType.IsConst); + Assert.IsFalse(variable.VariableType.HasCustomBitSize); + + Assert.AreEqual(4, variable.VariableType.References.Count); + Assert.IsInstanceOfType(variable.VariableType.References[0], typeof(ReferenceTypePointer)); + Assert.IsInstanceOfType(variable.VariableType.References[1], typeof(ReferenceTypePointer)); + Assert.IsInstanceOfType(variable.VariableType.References[2], typeof(ReferenceTypePointer)); + Assert.IsInstanceOfType(variable.VariableType.References[3], typeof(ReferenceTypePointer)); + + Assert.AreEqual(DataTypeBaseType.FLOAT, variable.VariableType.Type); + } + + [TestMethod] + public void EnsureCanHandleArrays() + { + tokens.AddRange(new List + { + "double", "pepper", "[", "9", "]", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(6, test.ConsumedTokenCount); + + Assert.AreEqual(1, block.Variables.Count); + + var variable = block.Variables[0]; + + Assert.AreEqual("pepper", variable.Name); + Assert.IsNull(variable.AlignmentOverride); + Assert.IsFalse(variable.VariableType.IsConst); + Assert.IsFalse(variable.VariableType.HasCustomBitSize); + + Assert.AreEqual(1, variable.VariableType.References.Count); + Assert.IsInstanceOfType(variable.VariableType.References[0], typeof(ReferenceTypeArray)); + Assert.AreEqual(9, ((ReferenceTypeArray) variable.VariableType.References[0]).ArraySize); + + Assert.AreEqual(DataTypeBaseType.DOUBLE, variable.VariableType.Type); + } + + [TestMethod] + public void EnsureCanHandleMultipleArrays() + { + tokens.AddRange(new List + { + "long", "long", "salt", "[", "4", "]", "[", "2", "]", "[", "1", "]", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(13, test.ConsumedTokenCount); + + Assert.AreEqual(1, block.Variables.Count); + + var variable = block.Variables[0]; + + Assert.AreEqual("salt", variable.Name); + Assert.IsNull(variable.AlignmentOverride); + Assert.IsFalse(variable.VariableType.IsConst); + Assert.IsFalse(variable.VariableType.HasCustomBitSize); + + Assert.AreEqual(3, variable.VariableType.References.Count); + Assert.IsInstanceOfType(variable.VariableType.References[0], typeof(ReferenceTypeArray)); + Assert.AreEqual(4, ((ReferenceTypeArray) variable.VariableType.References[0]).ArraySize); + Assert.IsInstanceOfType(variable.VariableType.References[1], typeof(ReferenceTypeArray)); + Assert.AreEqual(2, ((ReferenceTypeArray) variable.VariableType.References[1]).ArraySize); + Assert.IsInstanceOfType(variable.VariableType.References[2], typeof(ReferenceTypeArray)); + Assert.AreEqual(1, ((ReferenceTypeArray) variable.VariableType.References[2]).ArraySize); + + Assert.AreEqual(DataTypeBaseType.LONG_LONG, variable.VariableType.Type); + } + + [TestMethod] + public void EnsureCanHandleArrayOfPointers() + { + tokens.AddRange(new List + { + "unsigned", "long", "long", "*", "*", "what_a_var", "[", "6", "]", "[", "9", "]", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(13, test.ConsumedTokenCount); + + Assert.AreEqual(1, block.Variables.Count); + + var variable = block.Variables[0]; + + Assert.AreEqual("what_a_var", variable.Name); + Assert.IsNull(variable.AlignmentOverride); + Assert.IsFalse(variable.VariableType.IsConst); + Assert.IsFalse(variable.VariableType.HasCustomBitSize); + + Assert.AreEqual(4, variable.VariableType.References.Count); + Assert.IsInstanceOfType(variable.VariableType.References[0], typeof(ReferenceTypeArray)); + Assert.AreEqual(6, ((ReferenceTypeArray) variable.VariableType.References[0]).ArraySize); + Assert.IsInstanceOfType(variable.VariableType.References[1], typeof(ReferenceTypeArray)); + Assert.AreEqual(9, ((ReferenceTypeArray) variable.VariableType.References[1]).ArraySize); + Assert.IsInstanceOfType(variable.VariableType.References[2], typeof(ReferenceTypePointer)); + Assert.IsInstanceOfType(variable.VariableType.References[3], typeof(ReferenceTypePointer)); + + Assert.AreEqual(DataTypeBaseType.UNSIGNED_LONG_LONG, variable.VariableType.Type); + } + + [TestMethod] + public void EnsureCanHandlePointerToArray() + { + tokens.AddRange(new List + { + "unsigned", "char", "(", "*", "*", "send_halp", ")", "[", "1", "]", "[", "3", "]", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(14, test.ConsumedTokenCount); + + Assert.AreEqual(1, block.Variables.Count); + + var variable = block.Variables[0]; + + Assert.AreEqual("send_halp", variable.Name); + Assert.IsNull(variable.AlignmentOverride); + Assert.IsFalse(variable.VariableType.IsConst); + Assert.IsFalse(variable.VariableType.HasCustomBitSize); + + Assert.AreEqual(4, variable.VariableType.References.Count); + Assert.IsInstanceOfType(variable.VariableType.References[0], typeof(ReferenceTypePointer)); + Assert.IsInstanceOfType(variable.VariableType.References[1], typeof(ReferenceTypePointer)); + Assert.IsInstanceOfType(variable.VariableType.References[2], typeof(ReferenceTypeArray)); + Assert.AreEqual(1, ((ReferenceTypeArray) variable.VariableType.References[2]).ArraySize); + Assert.IsInstanceOfType(variable.VariableType.References[3], typeof(ReferenceTypeArray)); + Assert.AreEqual(3, ((ReferenceTypeArray) variable.VariableType.References[3]).ArraySize); + + Assert.AreEqual(DataTypeBaseType.UNSIGNED_CHAR, variable.VariableType.Type); + } + + [TestMethod] + public void EnsureAcceptsConstVariables() + { + tokens.AddRange(new List + { + "const", "int", "test", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(4, test.ConsumedTokenCount); + + Assert.AreEqual(1, block.Variables.Count); + + var variable = block.Variables[0]; + + Assert.AreEqual("test", variable.Name); + Assert.IsNull(variable.AlignmentOverride); + Assert.IsTrue(variable.VariableType.IsConst); + Assert.IsFalse(variable.VariableType.HasCustomBitSize); + + Assert.AreEqual(0, variable.VariableType.References.Count); + Assert.AreEqual(DataTypeBaseType.INT, variable.VariableType.Type); + } + + [TestMethod] + public void EnsureAcceptsConstPointerVariables() + { + tokens.AddRange(new List + { + "const", "char", "*", "str", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(5, test.ConsumedTokenCount); + + Assert.AreEqual(1, block.Variables.Count); + + var variable = block.Variables[0]; + + Assert.AreEqual("str", variable.Name); + Assert.IsNull(variable.AlignmentOverride); + Assert.IsTrue(variable.VariableType.IsConst); + Assert.IsFalse(variable.VariableType.HasCustomBitSize); + + Assert.AreEqual(1, variable.VariableType.References.Count); + Assert.IsInstanceOfType(variable.VariableType.References[0], typeof(ReferenceTypePointer)); + Assert.AreEqual(DataTypeBaseType.CHAR, variable.VariableType.Type); + } + + [TestMethod] + public void EnsureAcceptsCustomBitSizes() + { + tokens.AddRange(new List + { + "int", "test", ":", "3", ";" + }); + + var block = new BlockStruct(parserStateMock.Object, "test_struct", false); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.AreEqual(TokenTestResult.Match, test.PerformTest(parserStateMock.Object, lexerMock.Object)); + Assert.AreEqual(5, test.ConsumedTokenCount); + + Assert.AreEqual(1, block.Variables.Count); + + var variable = block.Variables[0]; + + Assert.AreEqual("test", variable.Name); + Assert.IsNull(variable.AlignmentOverride); + Assert.IsFalse(variable.VariableType.IsConst); + + Assert.IsTrue(variable.VariableType.HasCustomBitSize); + Assert.AreEqual(3, variable.VariableType.CustomBitSize); + + Assert.AreEqual(0, variable.VariableType.References.Count); + Assert.AreEqual(DataTypeBaseType.INT, variable.VariableType.Type); + } + + [TestMethod] + public void EnsureThrowsExceptionWhenNotInBlockThatCanHoldVariables() + { + tokens.AddRange(new List + { + "int", "test", ";" + }); + + var block = new BlockNamespace(parserStateMock.Object, "asdf"); + blocks.Push(block); + + var test = new TestVariable(); + + Assert.ThrowsException(() => test.PerformTest(parserStateMock.Object, lexerMock.Object)); + } + } +}