PathFuncTest.pas 8.7 KB

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