unittest.assembler.pp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2025 by Michael Van Canneyt
  4. pascal embedded assembler highlighter unit test
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit unittest.assembler;
  12. interface
  13. {$mode objfpc}{$H+}
  14. uses
  15. Classes, SysUtils, fpcunit, testregistry,
  16. syntax.highlighter, syntax.pascal;
  17. type
  18. TTestAsmHighlighter = class(TTestCase)
  19. protected
  20. procedure SetUp; override;
  21. procedure TearDown; override;
  22. private
  23. flags: Byte;
  24. published
  25. procedure TestBasicAsmBlock;
  26. procedure TestAsmWithInstructions;
  27. procedure TestAsmWithRegisters;
  28. procedure TestAsmWithComments;
  29. procedure TestAsmWithDirectives;
  30. procedure TestAsmMultiline;
  31. procedure TestEmptyAsm;
  32. end;
  33. implementation
  34. procedure TTestAsmHighlighter.SetUp;
  35. begin
  36. flags := 0;
  37. end;
  38. procedure TTestAsmHighlighter.TearDown;
  39. begin
  40. // Nothing to do
  41. end;
  42. procedure TTestAsmHighlighter.TestBasicAsmBlock;
  43. var
  44. tokens: TSyntaxTokenArray;
  45. begin
  46. tokens := DoPascalHighlighting( 'asm end');
  47. AssertTrue('Should have at least 2 tokens', Length(tokens) >= 2);
  48. AssertEquals('First token should be ASM', 'asm', tokens[0].Text);
  49. AssertEquals('First token should be keyword', Ord(shKeyword), Ord(tokens[0].Kind));
  50. AssertEquals('Last token should be END', 'END', tokens[High(tokens)].Text);
  51. AssertEquals('Last token should be keyword', Ord(shKeyword), Ord(tokens[High(tokens)].Kind));
  52. end;
  53. procedure TTestAsmHighlighter.TestAsmWithInstructions;
  54. var
  55. tokens: TSyntaxTokenArray;
  56. i: Integer;
  57. foundAsmToken: Boolean;
  58. begin
  59. tokens := DoPascalHighlighting( 'asm mov eax, ebx end');
  60. AssertTrue('Should have multiple tokens', Length(tokens) >= 3);
  61. // First token should be ASM keyword
  62. AssertEquals('First token should be ASM', 'asm', tokens[0].Text);
  63. AssertEquals('First token should be keyword', Ord(shKeyword), Ord(tokens[0].Kind));
  64. // Should have assembler content between asm and end
  65. foundAsmToken := False;
  66. for i := 1 to Length(tokens) - 2 do
  67. begin
  68. if tokens[i].Kind = shAssembler then
  69. begin
  70. foundAsmToken := True;
  71. break;
  72. end;
  73. end;
  74. AssertTrue('Should contain assembler tokens', foundAsmToken);
  75. // Last token should be END keyword
  76. AssertEquals('Last token should be END', 'END', tokens[High(tokens)].Text);
  77. AssertEquals('Last token should be keyword', Ord(shKeyword), Ord(tokens[High(tokens)].Kind));
  78. end;
  79. procedure TTestAsmHighlighter.TestAsmWithRegisters;
  80. var
  81. tokens: TSyntaxTokenArray;
  82. i: Integer;
  83. foundAsmToken: Boolean;
  84. begin
  85. tokens := DoPascalHighlighting( 'asm push eax; pop ebx; end');
  86. AssertTrue('Should have multiple tokens', Length(tokens) >= 3);
  87. // Should have assembler content
  88. foundAsmToken := False;
  89. for i := 1 to Length(tokens) - 2 do
  90. begin
  91. if tokens[i].Kind = shAssembler then
  92. begin
  93. foundAsmToken := True;
  94. break;
  95. end;
  96. end;
  97. AssertTrue('Should contain assembler tokens with registers', foundAsmToken);
  98. end;
  99. procedure TTestAsmHighlighter.TestAsmWithComments;
  100. var
  101. tokens: TSyntaxTokenArray;
  102. i: Integer;
  103. foundComment: Boolean;
  104. begin
  105. tokens := DoPascalHighlighting( 'asm { comment } mov eax, ebx end');
  106. AssertTrue('Should have multiple tokens', Length(tokens) >= 3);
  107. // Should have a comment token
  108. foundComment := False;
  109. for i := 0 to High(tokens) do
  110. begin
  111. if tokens[i].Kind = shComment then
  112. begin
  113. foundComment := True;
  114. AssertEquals('Comment should include braces', '{ comment }', tokens[i].Text);
  115. break;
  116. end;
  117. end;
  118. AssertTrue('Should contain comment token', foundComment);
  119. end;
  120. procedure TTestAsmHighlighter.TestAsmWithDirectives;
  121. var
  122. tokens: TSyntaxTokenArray;
  123. i: Integer;
  124. foundDirective: Boolean;
  125. begin
  126. tokens := DoPascalHighlighting( 'asm {$ASMMODE INTEL} mov eax, ebx end');
  127. AssertTrue('Should have multiple tokens', Length(tokens) >= 3);
  128. // Should have a directive token
  129. foundDirective := False;
  130. for i := 0 to High(tokens) do
  131. begin
  132. if tokens[i].Kind = shDirective then
  133. begin
  134. foundDirective := True;
  135. AssertEquals('Directive should include braces', '{$ASMMODE INTEL}', tokens[i].Text);
  136. break;
  137. end;
  138. end;
  139. AssertTrue('Should contain directive token', foundDirective);
  140. end;
  141. procedure TTestAsmHighlighter.TestAsmMultiline;
  142. var
  143. tokens: TSyntaxTokenArray;
  144. source: String;
  145. i: Integer;
  146. foundAsmToken: Boolean;
  147. begin
  148. source := 'asm' + #13#10 + ' mov eax, ebx' + #13#10 + ' add eax, 1' + #13#10 + 'end';
  149. tokens := DoPascalHighlighting( source);
  150. AssertTrue('Should have multiple tokens', Length(tokens) >= 3);
  151. // First token should be ASM keyword
  152. AssertEquals('First token should be ASM', 'asm', tokens[0].Text);
  153. AssertEquals('First token should be keyword', Ord(shKeyword), Ord(tokens[0].Kind));
  154. // Should have assembler content
  155. foundAsmToken := False;
  156. for i := 1 to Length(tokens) - 2 do
  157. begin
  158. if tokens[i].Kind = shAssembler then
  159. begin
  160. foundAsmToken := True;
  161. break;
  162. end;
  163. end;
  164. AssertTrue('Should contain assembler tokens in multiline', foundAsmToken);
  165. // Last token should be END keyword
  166. AssertEquals('Last token should be END', 'END', tokens[High(tokens)].Text);
  167. AssertEquals('Last token should be keyword', Ord(shKeyword), Ord(tokens[High(tokens)].Kind));
  168. end;
  169. procedure TTestAsmHighlighter.TestEmptyAsm;
  170. var
  171. tokens: TSyntaxTokenArray;
  172. begin
  173. tokens := DoPascalHighlighting( 'asm'#13#10'end');
  174. AssertTrue('Should have at least 3 tokens', Length(tokens) >= 3);
  175. // First token should be ASM keyword
  176. AssertEquals('First token should be ASM', 'asm', tokens[0].Text);
  177. AssertEquals('First token should be keyword', Ord(shKeyword), Ord(tokens[0].Kind));
  178. // Should have assembler token (whitespace is treated as assembler inside asm block)
  179. AssertEquals('Second token should be whitespace', #13#10, tokens[1].Text);
  180. AssertEquals('Second token should be assembler', Ord(shAssembler), Ord(tokens[1].Kind));
  181. // Last token should be END keyword
  182. AssertEquals('Last token should be END', 'END', tokens[High(tokens)].Text);
  183. AssertEquals('Last token should be keyword', Ord(shKeyword), Ord(tokens[High(tokens)].Kind));
  184. end;
  185. initialization
  186. RegisterTest(TTestAsmHighlighter);
  187. end.