LexerTests.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. using Lua.CodeAnalysis.Syntax;
  2. namespace Lua.Tests;
  3. public class LexerTests
  4. {
  5. [Test]
  6. [TestCase("0")]
  7. [TestCase("123")]
  8. [TestCase("1234567890")]
  9. public void Test_Numeric_Integer(string x)
  10. {
  11. var expected = new[]
  12. {
  13. SyntaxToken.Number(x, new(1, 0))
  14. };
  15. var actual = GetTokens(x);
  16. CollectionAssert.AreEqual(expected, actual);
  17. }
  18. [Test]
  19. [TestCase("1.2")]
  20. [TestCase("123.45")]
  21. [TestCase("12345.6789")]
  22. public void Test_Numeric_Decimal(string x)
  23. {
  24. var expected = new[]
  25. {
  26. SyntaxToken.Number(x, new(1, 0))
  27. };
  28. var actual = GetTokens(x);
  29. CollectionAssert.AreEqual(expected, actual);
  30. }
  31. [Test]
  32. [TestCase("0x123")]
  33. [TestCase("0x456")]
  34. [TestCase("0x789")]
  35. public void Test_Numeric_Hex(string x)
  36. {
  37. var expected = new[]
  38. {
  39. SyntaxToken.Number(x, new(1, 0))
  40. };
  41. var actual = GetTokens(x);
  42. CollectionAssert.AreEqual(expected, actual);
  43. }
  44. [Test]
  45. [TestCase("12E3")]
  46. [TestCase("45E+6")]
  47. [TestCase("78E-9")]
  48. [TestCase("1e+2")]
  49. [TestCase("3e-4")]
  50. public void Test_Numeric_Exponential(string x)
  51. {
  52. var expected = new[]
  53. {
  54. SyntaxToken.Number(x, new(1, 0))
  55. };
  56. var actual = GetTokens(x);
  57. CollectionAssert.AreEqual(expected, actual);
  58. }
  59. [Test]
  60. [TestCase("\"hello\"")]
  61. [TestCase("\"1.23\"")]
  62. [TestCase("\"1-2-3-4-5\"")]
  63. [TestCase("\'hello\'")]
  64. public void Test_String(string x)
  65. {
  66. var expected = new[]
  67. {
  68. SyntaxToken.String(x.AsMemory(1, x.Length - 2), new(1, 0))
  69. };
  70. var actual = GetTokens(x);
  71. CollectionAssert.AreEqual(expected, actual);
  72. }
  73. [Test]
  74. [TestCase("foo")]
  75. [TestCase("bar")]
  76. [TestCase("baz")]
  77. public void Test_Identifier(string x)
  78. {
  79. var expected = new[]
  80. {
  81. SyntaxToken.Identifier(x, new(1, 0))
  82. };
  83. var actual = GetTokens(x);
  84. CollectionAssert.AreEqual(expected, actual);
  85. }
  86. [Test]
  87. [TestCase("-- hello!")]
  88. [TestCase("-- how are you?")]
  89. [TestCase("-- goodbye!")]
  90. public void Test_Comment_Line(string code)
  91. {
  92. var expected = Array.Empty<SyntaxToken>();
  93. var actual = GetTokens(code);
  94. CollectionAssert.AreEqual(expected, actual);
  95. }
  96. [Test]
  97. [TestCase(@"--[[
  98. hello!
  99. how are you?
  100. goodbye!
  101. ]]--")]
  102. [TestCase(@"--[[
  103. hello!
  104. how are you?
  105. goodbye!
  106. ]]")]
  107. public void Test_Comment_Block(string code)
  108. {
  109. var expected = Array.Empty<SyntaxToken>();
  110. var actual = GetTokens(code);
  111. CollectionAssert.AreEqual(expected, actual);
  112. }
  113. [Test]
  114. [TestCase("--[[ \n hello")]
  115. [TestCase("--[[ \r hello")]
  116. [TestCase("--[[ \r\n hello")]
  117. public void Test_Comment_Block_Error(string code)
  118. {
  119. Assert.Throws<LuaParseException>(() => GetTokens(code), "main.lua:(1,5): unfinished long comment (starting at line 0)");
  120. }
  121. [Test]
  122. public void Test_Comment_Line_WithCode()
  123. {
  124. var expected = new[]
  125. {
  126. SyntaxToken.Number("10.0", new(1, 0))
  127. };
  128. var actual = GetTokens("10.0 -- this is numeric literal");
  129. CollectionAssert.AreEqual(expected, actual);
  130. }
  131. [Test]
  132. public void Test_Nil()
  133. {
  134. var expected = new[]
  135. {
  136. SyntaxToken.Nil(new(1, 0))
  137. };
  138. var actual = GetTokens("nil");
  139. CollectionAssert.AreEqual(expected, actual);
  140. }
  141. [Test]
  142. public void Test_True()
  143. {
  144. var expected = new[]
  145. {
  146. SyntaxToken.True(new(1, 0))
  147. };
  148. var actual = GetTokens("true");
  149. CollectionAssert.AreEqual(expected, actual);
  150. }
  151. [Test]
  152. public void Test_False()
  153. {
  154. var expected = new[]
  155. {
  156. SyntaxToken.False(new(1, 0))
  157. };
  158. var actual = GetTokens("false");
  159. CollectionAssert.AreEqual(expected, actual);
  160. }
  161. [Test]
  162. public void Test_If()
  163. {
  164. var expected = new[]
  165. {
  166. SyntaxToken.If(new(1, 0)), SyntaxToken.Identifier("x", new(1, 3)), SyntaxToken.Equality(new(1, 5)), SyntaxToken.Number("1.0", new(1, 8)), SyntaxToken.Then(new(1, 12)), SyntaxToken.EndOfLine(new(1, 16)),
  167. SyntaxToken.Return(new(2, 4)), SyntaxToken.Nil(new(2, 11)), SyntaxToken.EndOfLine(new(2, 14)),
  168. SyntaxToken.End(new(3, 0)),
  169. };
  170. var actual = GetTokens(
  171. @"if x == 1.0 then
  172. return nil
  173. end");
  174. CollectionAssert.AreEqual(expected, actual);
  175. }
  176. [Test]
  177. public void Test_If_Else()
  178. {
  179. var expected = new[]
  180. {
  181. SyntaxToken.If(new(1, 0)), SyntaxToken.Identifier("x", new(1, 3)), SyntaxToken.Equality(new(1, 5)), SyntaxToken.Number("1.0", new(1, 8)), SyntaxToken.Then(new(1, 12)), SyntaxToken.EndOfLine(new(1, 16)),
  182. SyntaxToken.Return(new(2, 4)), SyntaxToken.Number("1.0", new(2, 11)), SyntaxToken.EndOfLine(new(2, 14)),
  183. SyntaxToken.Else(new(3, 0)), SyntaxToken.EndOfLine(new(3, 4)),
  184. SyntaxToken.Return(new(4, 4)), SyntaxToken.Number("0.0", new(4, 11)), SyntaxToken.EndOfLine(new(4, 14)),
  185. SyntaxToken.End(new(5, 0)),
  186. };
  187. var actual = GetTokens(
  188. @"if x == 1.0 then
  189. return 1.0
  190. else
  191. return 0.0
  192. end");
  193. CollectionAssert.AreEqual(expected, actual);
  194. }
  195. static SyntaxToken[] GetTokens(string source)
  196. {
  197. var list = new List<SyntaxToken>();
  198. var lexer = new Lexer
  199. {
  200. Source = source.AsMemory(),
  201. ChunkName = "main.lua"
  202. };
  203. while (lexer.MoveNext())
  204. {
  205. list.Add(lexer.Current);
  206. }
  207. return list.ToArray();
  208. }
  209. }