unittest.ini.pp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2025 by Michael Van Canneyt
  4. INI 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.ini;
  12. interface
  13. {$mode objfpc}{$H+}
  14. uses
  15. Classes, SysUtils, fpcunit, testregistry,
  16. syntax.highlighter, syntax.ini;
  17. type
  18. TTestIniHighlighter = class(TTestCase)
  19. protected
  20. procedure SetUp; override;
  21. procedure TearDown; override;
  22. private
  23. function DoIniHighlighting(const source: string): TSyntaxTokenArray;
  24. published
  25. procedure TestIniSections;
  26. procedure TestIniKeys;
  27. procedure TestIniComments;
  28. procedure TestIniValues;
  29. procedure TestIniQuotedValues;
  30. procedure TestIniSymbols;
  31. procedure TestCompleteIniFile;
  32. procedure TestEmptyLines;
  33. procedure TestSemicolonComment;
  34. procedure TestHashComment;
  35. procedure TestKeyWithSpaces;
  36. end;
  37. implementation
  38. procedure TTestIniHighlighter.SetUp;
  39. begin
  40. end;
  41. procedure TTestIniHighlighter.TearDown;
  42. begin
  43. // Nothing to do
  44. end;
  45. function TTestIniHighlighter.DoIniHighlighting(const source: string): TSyntaxTokenArray;
  46. var
  47. highlighter: TIniSyntaxHighlighter;
  48. begin
  49. highlighter := TIniSyntaxHighlighter.Create;
  50. try
  51. Result := highlighter.Execute(source);
  52. finally
  53. highlighter.Free;
  54. end;
  55. end;
  56. procedure TTestIniHighlighter.TestIniSections;
  57. var
  58. tokens: TSyntaxTokenArray;
  59. begin
  60. // Test simple section
  61. tokens := DoIniHighlighting('[General]');
  62. AssertTrue('Should have at least 1 token', Length(tokens) >= 1);
  63. AssertEquals('Token should be [General]', '[General]', tokens[0].Text);
  64. AssertEquals('Token should be section', Ord(shSection), Ord(tokens[0].Kind));
  65. // Test section with spaces
  66. tokens := DoIniHighlighting('[My Section]');
  67. AssertTrue('Should have at least 1 token', Length(tokens) >= 1);
  68. AssertEquals('Token should be [My Section]', '[My Section]', tokens[0].Text);
  69. AssertEquals('Token should be section', Ord(shSection), Ord(tokens[0].Kind));
  70. // Test section with numbers
  71. tokens := DoIniHighlighting('[Section123]');
  72. AssertTrue('Should have at least 1 token', Length(tokens) >= 1);
  73. AssertEquals('Token should be [Section123]', '[Section123]', tokens[0].Text);
  74. AssertEquals('Token should be section', Ord(shSection), Ord(tokens[0].Kind));
  75. end;
  76. procedure TTestIniHighlighter.TestIniKeys;
  77. var
  78. tokens: TSyntaxTokenArray;
  79. i: Integer;
  80. foundKey: Boolean;
  81. begin
  82. // Test simple key
  83. tokens := DoIniHighlighting('username=admin');
  84. foundKey := False;
  85. for i := 0 to High(tokens) do
  86. begin
  87. if (tokens[i].Text = 'username') and (tokens[i].Kind = shKey) then
  88. begin
  89. foundKey := True;
  90. break;
  91. end;
  92. end;
  93. AssertTrue('Should find key token', foundKey);
  94. // Test key with spaces
  95. tokens := DoIniHighlighting('user name=admin');
  96. foundKey := False;
  97. for i := 0 to High(tokens) do
  98. begin
  99. if (tokens[i].Text = 'user name') and (tokens[i].Kind = shKey) then
  100. begin
  101. foundKey := True;
  102. break;
  103. end;
  104. end;
  105. AssertTrue('Should find key token with spaces', foundKey);
  106. // Test key with underscore
  107. tokens := DoIniHighlighting('user_name=admin');
  108. foundKey := False;
  109. for i := 0 to High(tokens) do
  110. begin
  111. if (tokens[i].Text = 'user_name') and (tokens[i].Kind = shKey) then
  112. begin
  113. foundKey := True;
  114. break;
  115. end;
  116. end;
  117. AssertTrue('Should find key token with underscore', foundKey);
  118. end;
  119. procedure TTestIniHighlighter.TestIniComments;
  120. var
  121. tokens: TSyntaxTokenArray;
  122. i: Integer;
  123. foundComment: Boolean;
  124. begin
  125. // Test semicolon comment
  126. tokens := DoIniHighlighting('; This is a comment');
  127. foundComment := False;
  128. for i := 0 to High(tokens) do
  129. begin
  130. if (tokens[i].Text = '; This is a comment') and (tokens[i].Kind = shComment) then
  131. begin
  132. foundComment := True;
  133. break;
  134. end;
  135. end;
  136. AssertTrue('Should find semicolon comment', foundComment);
  137. // Test hash comment
  138. tokens := DoIniHighlighting('# This is also a comment');
  139. foundComment := False;
  140. for i := 0 to High(tokens) do
  141. begin
  142. if (tokens[i].Text = '# This is also a comment') and (tokens[i].Kind = shComment) then
  143. begin
  144. foundComment := True;
  145. break;
  146. end;
  147. end;
  148. AssertTrue('Should find hash comment', foundComment);
  149. end;
  150. procedure TTestIniHighlighter.TestIniValues;
  151. var
  152. tokens: TSyntaxTokenArray;
  153. i: Integer;
  154. foundValue: Boolean;
  155. begin
  156. // Test simple value
  157. tokens := DoIniHighlighting('key=value');
  158. foundValue := False;
  159. for i := 0 to High(tokens) do
  160. begin
  161. if tokens[i].Text = 'value' then
  162. begin
  163. foundValue := True;
  164. AssertEquals('Value should be default token', Ord(shDefault), Ord(tokens[i].Kind));
  165. break;
  166. end;
  167. end;
  168. AssertTrue('Should find value token', foundValue);
  169. // Test numeric value
  170. tokens := DoIniHighlighting('port=8080');
  171. foundValue := False;
  172. for i := 0 to High(tokens) do
  173. begin
  174. if tokens[i].Text = '8080' then
  175. begin
  176. foundValue := True;
  177. break;
  178. end;
  179. end;
  180. AssertTrue('Should find numeric value', foundValue);
  181. end;
  182. procedure TTestIniHighlighter.TestIniQuotedValues;
  183. var
  184. tokens: TSyntaxTokenArray;
  185. i: Integer;
  186. foundQuotedValue: Boolean;
  187. begin
  188. // Test double-quoted value
  189. tokens := DoIniHighlighting('name="John Doe"');
  190. foundQuotedValue := False;
  191. for i := 0 to High(tokens) do
  192. begin
  193. if (tokens[i].Text = '"John Doe"') and (tokens[i].Kind = shStrings) then
  194. begin
  195. foundQuotedValue := True;
  196. break;
  197. end;
  198. end;
  199. AssertTrue('Should find double-quoted value as string', foundQuotedValue);
  200. // Test single-quoted value
  201. tokens := DoIniHighlighting('path=''C:\Program Files''');
  202. foundQuotedValue := False;
  203. for i := 0 to High(tokens) do
  204. begin
  205. if (tokens[i].Text = '''C:\Program Files''') and (tokens[i].Kind = shStrings) then
  206. begin
  207. foundQuotedValue := True;
  208. break;
  209. end;
  210. end;
  211. AssertTrue('Should find single-quoted value as string', foundQuotedValue);
  212. end;
  213. procedure TTestIniHighlighter.TestIniSymbols;
  214. var
  215. tokens: TSyntaxTokenArray;
  216. i: Integer;
  217. foundEquals: Boolean;
  218. begin
  219. // Test equals sign
  220. tokens := DoIniHighlighting('key=value');
  221. foundEquals := False;
  222. for i := 0 to High(tokens) do
  223. begin
  224. if (tokens[i].Text = '=') and (tokens[i].Kind = shOperator) then
  225. begin
  226. foundEquals := True;
  227. break;
  228. end;
  229. end;
  230. AssertTrue('Should find equals sign as operator', foundEquals);
  231. end;
  232. procedure TTestIniHighlighter.TestCompleteIniFile;
  233. var
  234. tokens: TSyntaxTokenArray;
  235. iniContent: string;
  236. i: Integer;
  237. hasSections, hasKeys, hasValues, hasComments: Boolean;
  238. begin
  239. iniContent := '[Database]' + #13#10 +
  240. 'host=localhost' + #13#10 +
  241. 'port=3306' + #13#10 +
  242. '; Connection timeout in seconds' + #13#10 +
  243. 'timeout=30' + #13#10 +
  244. #13#10 +
  245. '[Application]' + #13#10 +
  246. 'name="My App"' + #13#10 +
  247. 'debug=true';
  248. tokens := DoIniHighlighting(iniContent);
  249. AssertTrue('Should have multiple tokens', Length(tokens) > 10);
  250. // Check that we have different token types
  251. hasSections := False;
  252. hasKeys := False;
  253. hasValues := False;
  254. hasComments := False;
  255. for i := 0 to High(tokens) do
  256. begin
  257. case tokens[i].Kind of
  258. shSection: hasSections := True;
  259. shKey: hasKeys := True;
  260. shDefault: hasValues := True;
  261. shComment: hasComments := True;
  262. end;
  263. end;
  264. AssertTrue('Should contain section tokens', hasSections);
  265. AssertTrue('Should contain key tokens', hasKeys);
  266. AssertTrue('Should contain value tokens', hasValues);
  267. AssertTrue('Should contain comment tokens', hasComments);
  268. end;
  269. procedure TTestIniHighlighter.TestEmptyLines;
  270. var
  271. tokens: TSyntaxTokenArray;
  272. iniContent: string;
  273. begin
  274. iniContent := '[Section1]' + #13#10 +
  275. 'key1=value1' + #13#10 +
  276. #13#10 + // Empty line
  277. 'key2=value2';
  278. tokens := DoIniHighlighting(iniContent);
  279. AssertTrue('Should handle empty lines without crashing', Length(tokens) > 0);
  280. end;
  281. procedure TTestIniHighlighter.TestSemicolonComment;
  282. var
  283. tokens: TSyntaxTokenArray;
  284. i: Integer;
  285. foundComment: Boolean;
  286. begin
  287. tokens := DoIniHighlighting('; Configuration file');
  288. foundComment := False;
  289. for i := 0 to High(tokens) do
  290. begin
  291. if (tokens[i].Kind = shComment) and (Pos(';', tokens[i].Text) = 1) then
  292. begin
  293. foundComment := True;
  294. break;
  295. end;
  296. end;
  297. AssertTrue('Should recognize semicolon comments', foundComment);
  298. end;
  299. procedure TTestIniHighlighter.TestHashComment;
  300. var
  301. tokens: TSyntaxTokenArray;
  302. i: Integer;
  303. foundComment: Boolean;
  304. begin
  305. tokens := DoIniHighlighting('# This is a hash comment');
  306. foundComment := False;
  307. for i := 0 to High(tokens) do
  308. begin
  309. if (tokens[i].Kind = shComment) and (Pos('#', tokens[i].Text) = 1) then
  310. begin
  311. foundComment := True;
  312. break;
  313. end;
  314. end;
  315. AssertTrue('Should recognize hash comments', foundComment);
  316. end;
  317. procedure TTestIniHighlighter.TestKeyWithSpaces;
  318. var
  319. tokens: TSyntaxTokenArray;
  320. i: Integer;
  321. foundKey: Boolean;
  322. begin
  323. tokens := DoIniHighlighting('display name = John Doe');
  324. foundKey := False;
  325. for i := 0 to High(tokens) do
  326. begin
  327. // Writeln('*',tokens[i].Text,'*');
  328. if (tokens[i].Kind = shKey) and (tokens[i].Text = 'display name ') then
  329. begin
  330. foundKey := True;
  331. break;
  332. end;
  333. end;
  334. AssertTrue('Should handle keys with spaces', foundKey);
  335. end;
  336. initialization
  337. RegisterTest(TTestIniHighlighter);
  338. end.