PathFuncTest.pas 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. unit PathFuncTest;
  2. {
  3. Inno Setup
  4. Copyright (C) 1997-2010 Jordan Russell
  5. Portions by Martijn Laan
  6. For conditions of distribution and use, see LICENSE.TXT.
  7. Test unit for PathFunc
  8. }
  9. interface
  10. procedure PathFuncRunTests(const AlsoTestJapaneseDBCS: Boolean);
  11. implementation
  12. uses
  13. Windows, SysUtils, PathFunc;
  14. procedure PathFuncRunTests(const AlsoTestJapaneseDBCS: Boolean);
  15. procedure Test(const Filename: String;
  16. const DrivePartFalse, DrivePartTrue, PathPartFalse, PathPartTrue: Integer);
  17. begin
  18. if PathDrivePartLengthEx(Filename, False) <> DrivePartFalse then
  19. raise Exception.CreateFmt('"%s" drive part(False) test failed', [Filename]);
  20. if PathDrivePartLengthEx(Filename, True) <> DrivePartTrue then
  21. raise Exception.CreateFmt('"%s" drive part(True) test failed', [Filename]);
  22. if PathPathPartLength(Filename, False) <> PathPartFalse then
  23. raise Exception.CreateFmt('"%s" path part(False) test failed', [Filename]);
  24. if PathPathPartLength(Filename, True) <> PathPartTrue then
  25. raise Exception.CreateFmt('"%s" path part(True) test failed', [Filename]);
  26. if PathIsRooted(Filename) <> (PathDrivePartLengthEx(Filename, True) <> 0) then
  27. raise Exception.CreateFmt('"%s" PathIsRooted test failed', [Filename]);
  28. end;
  29. procedure TestRemoveBackslash(const Filename, ExpectedResult: String);
  30. begin
  31. if RemoveBackslash(Filename) <> ExpectedResult then
  32. raise Exception.Create('RemoveBackslash test failed');
  33. end;
  34. procedure TestRemoveBackslashUnlessRoot(const Filename, ExpectedResult: String);
  35. begin
  36. if RemoveBackslashUnlessRoot(Filename) <> ExpectedResult then
  37. raise Exception.Create('RemoveBackslashUnlessRoot test failed');
  38. end;
  39. procedure TestPathChangeExt(const Filename, Extension, ExpectedResult: String);
  40. begin
  41. if PathChangeExt(Filename, Extension) <> ExpectedResult then
  42. raise Exception.Create('PathChangeExt test failed');
  43. end;
  44. procedure TestPathExtractExt(const Filename, ExpectedResult: String);
  45. begin
  46. if PathExtractExt(Filename) <> ExpectedResult then
  47. raise Exception.Create('PathExtractExt test failed');
  48. end;
  49. procedure TestPathCombine(const Dir, Filename, ExpectedResult: String);
  50. begin
  51. if PathCombine(Dir, Filename) <> ExpectedResult then
  52. raise Exception.Create('PathCombine test failed');
  53. end;
  54. procedure TestPathStartsWith(const S, AStartsWith: String; const ExpectedResult: Boolean);
  55. begin
  56. if PathStartsWith(S, AStartsWith) <> ExpectedResult then
  57. raise Exception.Create('PathStartsWith test failed');
  58. end;
  59. const
  60. DBChar = #131'\'; { a double-byte character whose 2nd byte happens to be a backslash }
  61. begin
  62. {$IFDEF UNICODE}
  63. if AlsoTestJapaneseDBCS then
  64. raise Exception.Create('DBCS tests not supported in Unicode build');
  65. {$ENDIF}
  66. if AlsoTestJapaneseDBCS and (GetACP <> 932) then
  67. raise Exception.Create('Must be running in Japanese code page to run these tests');
  68. { * = Bogus path case. What the "correct" result should be is debatable. }
  69. { ** = Possible access to NTFS alternate data stream. The characters before
  70. and after the colon must be kept together as a single component. }
  71. Test('', 0, 0, 0, 0);
  72. Test('\', 0, 1, 1, 1);
  73. Test('\a', 0, 1, 1, 1);
  74. Test('\a\', 0, 1, 2, 3);
  75. Test('\a\b', 0, 1, 2, 3);
  76. Test('a', 0, 0, 0, 0);
  77. Test('a\', 0, 0, 1, 2);
  78. Test('a\\', 0, 0, 1, 3);
  79. Test('a\\\', 0, 0, 1, 4);
  80. Test('a\b', 0, 0, 1, 2);
  81. Test('a\b:c', 0, 0, 1, 2); {**}
  82. Test('1:', 2, 2, 2, 2); {*}
  83. Test('\:', 0, 1, 1, 1); {*}
  84. { Yes, the following is a valid path -- it specifies a stream named 'stream'
  85. on the root directory of the current drive. (Yes, directories can have
  86. named streams.) }
  87. Test('\:stream', 0, 1, 1, 1); {**}
  88. Test('c:', 2, 2, 2, 2);
  89. Test('c:a', 2, 2, 2, 2);
  90. Test('c:\', 2, 3, 3, 3);
  91. Test('c:\\', 2, 3, 3, 4);
  92. Test('c:\\\', 2, 3, 3, 5);
  93. Test('c:\a', 2, 3, 3, 3);
  94. Test('c:\a\', 2, 3, 4, 5);
  95. Test('c:\a\\', 2, 3, 4, 6);
  96. Test('c:\a\\\', 2, 3, 4, 7);
  97. Test('c:\a\b', 2, 3, 4, 5);
  98. Test('c:\a\b:c', 2, 3, 4, 5); {**}
  99. Test('\\', 2, 2, 2, 2); {*}
  100. { Odd cases follow: The extra slashes are considered to be in the drive part
  101. since PathDrivePartLength keeps slurping slashes looking for a share name
  102. that doesn't exist. }
  103. Test('\\\', 3, 3, 3, 3); {*}
  104. Test('\\\\', 4, 4, 4, 4); {*}
  105. Test('\\\\\', 5, 5, 5, 5); {*}
  106. Test('\\a', 3, 3, 3, 3); {*}
  107. Test('\\a\', 4, 4, 4, 4); {*}
  108. Test('\\a\b', 5, 5, 5, 5);
  109. Test('\\a\b\', 5, 5, 5, 6);
  110. Test('\\a\b\c', 5, 5, 5, 6);
  111. Test('\\a\b\c\', 5, 5, 7, 8);
  112. Test('\\a\b\c\d', 5, 5, 7, 8);
  113. Test('\\a\b\c\d:e', 5, 5, 7, 8); {**}
  114. Test('\\a\\\b', 7, 7, 7, 7);
  115. Test('\\a\\\b\\\', 7, 7, 7, 10);
  116. Test('\\a\\\b\\\c', 7, 7, 7, 10);
  117. Test('\\a\\\b\\\c\\\', 7, 7, 11, 14);
  118. if AlsoTestJapaneseDBCS then begin
  119. Test('\\'+DBChar+DBChar+'\b', 8, 8, 8, 8);
  120. Test('\\'+DBChar+DBChar+'\b\c', 8, 8, 8, 9);
  121. Test('\\'+DBChar+DBChar+'\b\c\', 8, 8, 10, 11);
  122. Test('c:\'+DBChar+'\b', 2, 3, 5, 6);
  123. Test(DBChar+':', 3, 3, 3, 3); {*} { double-byte drive letter? bogus, but be like Windows... }
  124. end;
  125. TestRemoveBackslash('', '');
  126. TestRemoveBackslash('\', '');
  127. TestRemoveBackslash('\\', '');
  128. TestRemoveBackslash('\\\', '');
  129. TestRemoveBackslash('c:', 'c:');
  130. TestRemoveBackslash('c:\', 'c:');
  131. TestRemoveBackslash('c:\\', 'c:');
  132. TestRemoveBackslash('c:\\\', 'c:');
  133. if AlsoTestJapaneseDBCS then begin
  134. TestRemoveBackslash(DBChar, DBChar);
  135. TestRemoveBackslash(DBChar+'\', DBChar);
  136. TestRemoveBackslash(DBChar+'\\', DBChar);
  137. end;
  138. TestRemoveBackslashUnlessRoot('', '');
  139. TestRemoveBackslashUnlessRoot('\', '\');
  140. TestRemoveBackslashUnlessRoot('\\', '\\'); {*}
  141. TestRemoveBackslashUnlessRoot('\\\', '\\\'); {*}
  142. TestRemoveBackslashUnlessRoot('\\\\', '\\\\'); {*}
  143. TestRemoveBackslashUnlessRoot('a', 'a');
  144. TestRemoveBackslashUnlessRoot('a\', 'a');
  145. TestRemoveBackslashUnlessRoot('a\\', 'a');
  146. TestRemoveBackslashUnlessRoot('c:', 'c:');
  147. TestRemoveBackslashUnlessRoot('c:\', 'c:\');
  148. TestRemoveBackslashUnlessRoot('c:\a', 'c:\a');
  149. TestRemoveBackslashUnlessRoot('c:\a\', 'c:\a');
  150. TestRemoveBackslashUnlessRoot('c:\a\\', 'c:\a');
  151. TestRemoveBackslashUnlessRoot('\\a\b', '\\a\b');
  152. TestRemoveBackslashUnlessRoot('\\a\b\', '\\a\b');
  153. TestRemoveBackslashUnlessRoot('\\a\b\\', '\\a\b');
  154. TestPathChangeExt('c:', '.txt', 'c:.txt'); {*} { weird, but same as Delphi's ChangeFileExt }
  155. TestPathChangeExt('c:\', '.txt', 'c:\.txt'); {*}
  156. TestPathChangeExt('c:\a', '.txt', 'c:\a.txt');
  157. TestPathChangeExt('c:\a.', '.txt', 'c:\a.txt');
  158. TestPathChangeExt('c:\a.tar', '.txt', 'c:\a.txt');
  159. TestPathChangeExt('c:\a.tar.gz', '.txt', 'c:\a.tar.txt');
  160. TestPathChangeExt('c:\x.y\a', '.txt', 'c:\x.y\a.txt');
  161. TestPathChangeExt('\\x.y\a', '.txt', '\\x.y\a.txt'); {*} { ditto above }
  162. TestPathChangeExt('\\x.y\a\', '.txt', '\\x.y\a\.txt'); {*}
  163. TestPathExtractExt('c:', '');
  164. TestPathExtractExt('c:\', '');
  165. TestPathExtractExt('c:\a', '');
  166. TestPathExtractExt('c:\a.', '.');
  167. TestPathExtractExt('c:\a.txt', '.txt');
  168. TestPathExtractExt('c:\a.txt.gz', '.gz');
  169. TestPathExtractExt('c:\x.y\a', '');
  170. TestPathExtractExt('\\x.y\a', '');
  171. TestPathExtractExt('\\x.y\a.b', '');
  172. TestPathExtractExt('\\x.y\a.b\c', '');
  173. TestPathExtractExt('\\x.y\a.b\c.txt', '.txt');
  174. TestPathCombine('', 'x', 'x');
  175. TestPathCombine('a', 'x', 'a\x');
  176. TestPathCombine('a\', 'x', 'a\x');
  177. TestPathCombine('a\\', 'x', 'a\\x');
  178. TestPathCombine('c:', 'x', 'c:x');
  179. TestPathCombine('c:\', 'x', 'c:\x');
  180. TestPathCombine('c:\\', 'x', 'c:\\x');
  181. TestPathCombine('c:\a', 'x', 'c:\a\x');
  182. TestPathCombine('\', 'x', '\x');
  183. if AlsoTestJapaneseDBCS then begin
  184. TestPathCombine(DBChar+':', 'x', DBChar+':x'); {*} { double-byte drive letter? bogus, but be like Windows... }
  185. TestPathCombine('c:\'+DBChar, 'x', 'c:\'+DBChar+'\x');
  186. end;
  187. TestPathCombine('c:\', '', '');
  188. TestPathCombine('c:\', 'e:x', 'e:x');
  189. TestPathCombine('c:\', 'e:\x', 'e:\x');
  190. TestPathCombine('c:\', '\x', '\x');
  191. TestPathCombine('c:\', '\\a\b\c', '\\a\b\c');
  192. TestPathCombine('c:\', 'ee:x', 'c:\ee:x'); {**}
  193. TestPathStartsWith('C:', 'c:\', False);
  194. TestPathStartsWith('C:\', 'c:\', True);
  195. TestPathStartsWith('C:\test', 'c:\', True);
  196. if AlsoTestJapaneseDBCS then begin
  197. { Test PathStartsWith's PathCharIsTrailByte call; it shouldn't chop a
  198. double-byte character in half }
  199. TestPathStartsWith('C:'+DBChar, 'c:\', False);
  200. TestPathStartsWith('C:'+DBChar, 'c:'+DBChar[1], False);
  201. end;
  202. end;
  203. end.