Test_URLRouter.dpr 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174
  1. (* _ _
  2. * | |__ _ __ ___ ___ | | __
  3. * | '_ \| '__/ _ \ / _ \| |/ /
  4. * | |_) | | | (_) | (_) | <
  5. * |_.__/|_| \___/ \___/|_|\_\
  6. *
  7. * Microframework which helps to develop web Pascal applications.
  8. *
  9. * Copyright (c) 2012-2020 Silvio Clecio <[email protected]>
  10. *
  11. * Brook framework is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation; either
  14. * version 2.1 of the License, or (at your option) any later version.
  15. *
  16. * Brook framework is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with Brook framework; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *)
  25. program Test_URLRouter;
  26. {$I Tests.inc}
  27. uses
  28. SysUtils,
  29. Classes,
  30. Platform,
  31. libsagui,
  32. BrookLibraryLoader,
  33. BrookUtility,
  34. BrookStringMap,
  35. BrookURLRouter,
  36. BrookHTTPRequest,
  37. BrookHTTPResponse,
  38. Test;
  39. type
  40. { TFakeURLRoutes }
  41. TFakeURLRoutes = class(TBrookURLRoutes)
  42. public
  43. procedure Prepare; override;
  44. procedure Unprepare; override;
  45. function NewPattern: string; override;
  46. end;
  47. { TFakeURLRoute }
  48. TFakeURLRoute = class(TBrookURLRoute)
  49. protected
  50. function GetHandle: Pointer; override;
  51. procedure HandleMatch(ARoute: TBrookURLRoute); override;
  52. procedure FakeOnMath(ARoute: TBrookURLRoute);
  53. procedure FakeOnRequestMethod(ASender: TObject; ARoute: TBrookURLRoute;
  54. ARequest: TBrookHTTPRequest; AResponse: TBrookHTTPResponse;
  55. var AAllowed: Boolean);
  56. procedure FakeOnRequest(ASender: TObject; ARoute: TBrookURLRoute;
  57. ARequest: TBrookHTTPRequest; AResponse: TBrookHTTPResponse);
  58. public
  59. constructor Create(ACollection: TCollection); override;
  60. procedure TestOnMath;
  61. procedure TestOnRequestMethod(var AAllowed: Boolean);
  62. procedure TestOnRequest;
  63. end;
  64. { TFakeHTTPRequest }
  65. TFakeHTTPRequest = class(TBrookHTTPRequest)
  66. protected
  67. function CreateHeaders(AHandle: Pointer): TBrookStringMap; override;
  68. function CreateCookies(AHandle: Pointer): TBrookStringMap; override;
  69. function CreateParams(AHandle: Pointer): TBrookStringMap; override;
  70. function CreateFields(AHandle: Pointer): TBrookStringMap; override;
  71. public
  72. constructor Create(AHandle: Pointer); override;
  73. destructor Destroy; override;
  74. end;
  75. { TFakeHTTPResponse }
  76. TFakeHTTPResponse = class(TBrookHTTPResponse)
  77. public
  78. constructor Create(AHandle: Pointer); override;
  79. destructor Destroy; override;
  80. end;
  81. { TFakeURLRouter }
  82. TFakeURLRouter = class(TBrookURLRouter)
  83. public
  84. procedure FakeOnRoute(ASender: TObject; const APath: string;
  85. ARequest: TBrookHTTPRequest; AResponse: TBrookHTTPResponse);
  86. procedure FakeOnRequest(ASender: TObject; ARoute: TBrookURLRoute;
  87. ARequest: TBrookHTTPRequest; AResponse: TBrookHTTPResponse);
  88. procedure FakeOnNotFound(ASender: TObject; const ARoute: string;
  89. ARequest: TBrookHTTPRequest; AResponse: TBrookHTTPResponse);
  90. procedure FakeOnActivate(ASender: TObject);
  91. procedure FakeOnDeactivate(ASender: TObject);
  92. end;
  93. const
  94. FakeHandle = Pointer(123);
  95. var
  96. FakeHTTPRequest: TFakeHTTPRequest;
  97. FakeHTTPResponse: TFakeHTTPResponse;
  98. FakeFlag: Boolean;
  99. function fake_router_dispatch1(router: Psg_router; const path: Pcchar;
  100. user_data: Pcvoid): cint; cdecl;
  101. begin
  102. Assert(user_data = FakeHandle);
  103. Assert(path = '/route');
  104. Result := 0;
  105. end;
  106. function fake_router_dispatch2(router: Psg_router; const path: Pcchar;
  107. user_data: Pcvoid): cint; cdecl;
  108. begin
  109. if path <> '/route' then
  110. Exit(ENOENT);
  111. Result := 0;
  112. end;
  113. function fake_httpreq_path(req: Psg_httpreq): Pcchar; cdecl;
  114. begin
  115. Result := '/route';
  116. end;
  117. function fake_httpreq_method(req: Psg_httpreq): Pcchar; cdecl;
  118. begin
  119. Result := 'GET';
  120. end;
  121. procedure TFakeURLRouter.FakeOnRoute(ASender: TObject; const APath: string;
  122. ARequest: TBrookHTTPRequest; AResponse: TBrookHTTPResponse);
  123. begin
  124. Assert(ASender = FakeHandle);
  125. Assert(APath = '/route');
  126. Assert(ARequest = FakeHTTPRequest);
  127. Assert(AResponse = FakeHTTPResponse);
  128. FakeFlag := True;
  129. end;
  130. procedure TFakeURLRouter.FakeOnRequest(ASender: TObject;
  131. ARoute: TBrookURLRoute; ARequest: TBrookHTTPRequest;
  132. AResponse: TBrookHTTPResponse);
  133. begin
  134. Assert(ASender = ARoute);
  135. Assert(ARequest = FakeHTTPRequest);
  136. Assert(AResponse = FakeHTTPResponse);
  137. FakeFlag := True;
  138. end;
  139. procedure TFakeURLRouter.FakeOnNotFound(ASender: TObject; const ARoute: string;
  140. ARequest: TBrookHTTPRequest; AResponse: TBrookHTTPResponse);
  141. begin
  142. Assert(ASender = FakeHandle);
  143. Assert((ARoute = '/') or (ARoute = 'xxx'));
  144. Assert(ARequest = FakeHTTPRequest);
  145. Assert(AResponse = FakeHTTPResponse);
  146. FakeFlag := True;
  147. end;
  148. procedure TFakeURLRouter.FakeOnActivate(ASender: TObject);
  149. begin
  150. Assert(Assigned(ASender));
  151. FakeFlag := True;
  152. end;
  153. procedure TFakeURLRouter.FakeOnDeactivate(ASender: TObject);
  154. begin
  155. Assert(Assigned(ASender));
  156. FakeFlag := True;
  157. end;
  158. { TFakeURLRoutes }
  159. procedure TFakeURLRoutes.Prepare;
  160. begin
  161. inherited Prepare;
  162. end;
  163. procedure TFakeURLRoutes.Unprepare;
  164. begin
  165. inherited Unprepare;
  166. end;
  167. function TFakeURLRoutes.NewPattern: string;
  168. begin
  169. Result := '';
  170. end;
  171. { TFakeURLRoute }
  172. constructor TFakeURLRoute.Create(ACollection: TCollection);
  173. begin
  174. inherited Create(ACollection);
  175. DoRouteCallback(Self, FakeHandle);
  176. end;
  177. function TFakeURLRoute.GetHandle: Pointer;
  178. begin
  179. Result := FakeHandle;
  180. end;
  181. procedure TFakeURLRoute.HandleMatch(ARoute: TBrookURLRoute);
  182. begin
  183. end;
  184. procedure TFakeURLRoute.FakeOnMath(ARoute: TBrookURLRoute);
  185. begin
  186. Assert(ARoute = Self);
  187. FakeFlag := True;
  188. end;
  189. procedure TFakeURLRoute.FakeOnRequestMethod(ASender: TObject;
  190. ARoute: TBrookURLRoute; ARequest: TBrookHTTPRequest;
  191. AResponse: TBrookHTTPResponse; var AAllowed: Boolean);
  192. begin
  193. Assert(ASender = Self);
  194. Assert(ARoute = Self);
  195. Assert(ARequest = FakeHTTPRequest);
  196. Assert(AResponse = FakeHTTPResponse);
  197. AAllowed := True;
  198. FakeFlag := True;
  199. end;
  200. procedure TFakeURLRoute.FakeOnRequest(ASender: TObject; ARoute: TBrookURLRoute;
  201. ARequest: TBrookHTTPRequest; AResponse: TBrookHTTPResponse);
  202. begin
  203. Assert(ASender = Self);
  204. Assert(ARoute = Self);
  205. Assert(ARequest = FakeHTTPRequest);
  206. Assert(AResponse = FakeHTTPResponse);
  207. FakeFlag := True;
  208. end;
  209. procedure TFakeURLRoute.TestOnMath;
  210. begin
  211. DoMatch(Self);
  212. end;
  213. procedure TFakeURLRoute.TestOnRequestMethod(var AAllowed: Boolean);
  214. begin
  215. DoRequestMethod(Self, Self, FakeHTTPRequest, FakeHTTPResponse, AAllowed);
  216. end;
  217. procedure TFakeURLRoute.TestOnRequest;
  218. begin
  219. DoRequest(Self, Self, FakeHTTPRequest, FakeHTTPResponse);
  220. end;
  221. { TFakeHTTPRequest }
  222. constructor TFakeHTTPRequest.Create(AHandle: Pointer);
  223. begin
  224. sg_httpreq_path := fake_httpreq_path;
  225. sg_httpreq_method := fake_httpreq_method;
  226. inherited Create(AHandle);
  227. end;
  228. destructor TFakeHTTPRequest.Destroy;
  229. begin
  230. inherited Destroy;
  231. end;
  232. function TFakeHTTPRequest.CreateHeaders(AHandle: Pointer): TBrookStringMap;
  233. var
  234. X: Pointer;
  235. begin
  236. Result := inherited CreateHeaders(@X);
  237. end;
  238. function TFakeHTTPRequest.CreateCookies(AHandle: Pointer): TBrookStringMap;
  239. var
  240. X: Pointer;
  241. begin
  242. Result := inherited CreateCookies(@X);
  243. end;
  244. function TFakeHTTPRequest.CreateParams(AHandle: Pointer): TBrookStringMap;
  245. var
  246. X: Pointer;
  247. begin
  248. Result := inherited CreateParams(@X);
  249. end;
  250. function TFakeHTTPRequest.CreateFields(AHandle: Pointer): TBrookStringMap;
  251. var
  252. X: Pointer;
  253. begin
  254. Result := inherited CreateFields(@X);
  255. end;
  256. { TFakeHTTPResponse }
  257. constructor TFakeHTTPResponse.Create(AHandle: Pointer);
  258. begin
  259. end;
  260. destructor TFakeHTTPResponse.Destroy;
  261. begin
  262. end;
  263. function fake_route_handle(route: Psg_route): Pcvoid; cdecl;
  264. begin
  265. Result := FakeHandle;
  266. end;
  267. function fake_route_segments_iter(route: Psg_route; cb: sg_segments_iter_cb;
  268. cls: Pcvoid): cint; cdecl;
  269. begin
  270. cb(cls, 0, 'test1');
  271. cb(cls, 1, 'test2');
  272. Result := 0;
  273. end;
  274. function fake_route_vars_iter(route: Psg_route; cb: sg_vars_iter_cb;
  275. cls: Pcvoid): cint; cdecl;
  276. begin
  277. cb(cls, 'name1', 'val1');
  278. cb(cls, 'name2', 'val2');
  279. Result := 0;
  280. end;
  281. function fake_route_rawpattern(route: Psg_route): Pcchar; cdecl;
  282. begin
  283. Result := 'foo';
  284. end;
  285. function fake_route_path(route: Psg_route): Pcchar; cdecl;
  286. begin
  287. Result := 'bar';
  288. end;
  289. function fake_route_user_data(route: Psg_route): Pcvoid; cdecl;
  290. begin
  291. Result := FakeHandle;
  292. end;
  293. procedure Test_URLRouteCreate(AList: TBrookURLRoutes);
  294. var
  295. RT: TBrookURLRoute;
  296. begin
  297. AList.Clear;
  298. RT := TBrookURLRoute.Create(nil);
  299. try
  300. Assert(RT.Pattern = '/');
  301. finally
  302. RT.Free;
  303. end;
  304. RT := TBrookURLRoute.Create(AList);
  305. Assert(RT.Pattern = '/route1');
  306. RT := TBrookURLRoute.Create(AList);
  307. Assert(RT.Pattern = '/route2');
  308. Assert(RT.Methods = [rmGET, rmPOST]);
  309. end;
  310. procedure DoURLEntryPointEmptyRoutePattern(const AArgs: array of const);
  311. begin
  312. TBrookURLRoute(AArgs[0].VObject).Validate;
  313. end;
  314. procedure Test_URLRouteValidate(AList: TBrookURLRoutes);
  315. var
  316. FL: TFakeURLRoutes;
  317. RT: TBrookURLRoute;
  318. begin
  319. AList.Clear;
  320. FL := TFakeURLRoutes.Create(nil);
  321. try
  322. RT := TBrookURLRoute.Create(AList);
  323. RT.Validate;
  324. RT := TBrookURLRoute.Create(FL);
  325. AssertExcept(DoURLEntryPointEmptyRoutePattern, EBrookURLRoute,
  326. Format(SBrookEmptyRoutePattern, [RT.GetNamePath]), [RT]);
  327. finally
  328. FL.Free;
  329. end;
  330. end;
  331. procedure Test_URLRoutePCRE2Handle;
  332. var
  333. RT: TBrookURLRoute;
  334. begin
  335. RT := TFakeURLRoute.Create(nil);
  336. try
  337. sg_route_handle := fake_route_handle;
  338. Assert(Assigned(RT.PCRE2Handle));
  339. Assert(RT.PCRE2Handle = FakeHandle);
  340. finally
  341. RT.Free;
  342. end;
  343. end;
  344. procedure Test_URLRouteSegments;
  345. var
  346. RT: TBrookURLRoute;
  347. begin
  348. RT := TFakeURLRoute.Create(nil);
  349. try
  350. sg_route_segments_iter := fake_route_segments_iter;
  351. Assert(Length(RT.Segments) = 2);
  352. Assert(RT.Segments[0] = 'test1');
  353. Assert(RT.Segments[1] = 'test2');
  354. finally
  355. RT.Free;
  356. end;
  357. end;
  358. procedure Test_URLRouteVariables;
  359. var
  360. RT: TBrookURLRoute;
  361. begin
  362. RT := TFakeURLRoute.Create(nil);
  363. try
  364. sg_route_vars_iter := fake_route_vars_iter;
  365. Assert(Assigned(RT.Variables));
  366. Assert(RT.Variables.Count = 2);
  367. Assert(RT.Variables['name1'] = 'val1');
  368. Assert(RT.Variables['name2'] = 'val2');
  369. finally
  370. RT.Free;
  371. end;
  372. end;
  373. procedure Test_URLRouteRawPattern(AList: TBrookURLRoutes);
  374. var
  375. RT: TBrookURLRoute;
  376. begin
  377. AList.Clear;
  378. RT := TBrookURLRoute.Create(nil);
  379. try
  380. Assert(RT.RawPattern = '^/$');
  381. finally
  382. RT.Free;
  383. end;
  384. RT := TBrookURLRoute.Create(AList);
  385. Assert(RT.RawPattern = '^/route1$');
  386. RT := TBrookURLRoute.Create(AList);
  387. Assert(RT.RawPattern = '^/route2$');
  388. RT := TBrookURLRoute.Create(AList);
  389. Assert(RT.RawPattern = '^/route3$');
  390. RT := TFakeURLRoute.Create(AList);
  391. sg_route_rawpattern := fake_route_rawpattern;
  392. Assert(RT.RawPattern = 'foo');
  393. end;
  394. procedure Test_URLRoutePath;
  395. var
  396. RT: TBrookURLRoute;
  397. begin
  398. RT := TBrookURLRoute.Create(nil);
  399. try
  400. Assert(RT.Path = '');
  401. finally
  402. RT.Free;
  403. end;
  404. RT := TFakeURLRoute.Create(nil);
  405. try
  406. sg_route_path := fake_route_path;
  407. Assert(RT.Path = 'bar');
  408. finally
  409. RT.Free;
  410. end;
  411. end;
  412. procedure Test_URLRouteUserData;
  413. var
  414. RT: TBrookURLRoute;
  415. begin
  416. RT := TBrookURLRoute.Create(nil);
  417. try
  418. Assert(not Assigned(RT.UserData));
  419. finally
  420. RT.Free;
  421. end;
  422. RT := TFakeURLRoute.Create(nil);
  423. try
  424. sg_route_user_data := fake_route_user_data;
  425. Assert(RT.UserData = FakeHandle);
  426. finally
  427. RT.Free;
  428. end;
  429. end;
  430. procedure Test_URLRouteDefault;
  431. var
  432. RT: TBrookURLRoute;
  433. begin
  434. RT := TBrookURLRoute.Create(nil);
  435. try
  436. Assert(not RT.Default);
  437. RT.Default := True;
  438. Assert(RT.Default);
  439. finally
  440. RT.Free;
  441. end;
  442. end;
  443. procedure Test_URLRoutePattern(AList: TBrookURLRoutes);
  444. var
  445. RT: TBrookURLRoute;
  446. begin
  447. RT := TBrookURLRoute.Create(nil);
  448. try
  449. Assert(RT.Pattern = '/');
  450. RT.Pattern := 'foo';
  451. Assert(RT.Pattern = '/');
  452. finally
  453. RT.Free;
  454. end;
  455. AList.Clear;
  456. RT := TBrookURLRoute.Create(AList);
  457. try
  458. Assert(RT.Pattern = '/route1');
  459. RT.Pattern := 'foo';
  460. Assert(RT.Pattern = '/foo');
  461. finally
  462. RT.Free;
  463. end;
  464. end;
  465. procedure Test_URLRouteMethods;
  466. var
  467. RT: TBrookURLRoute;
  468. begin
  469. RT := TBrookURLRoute.Create(nil);
  470. try
  471. Assert(RT.Methods = [rmGET, rmPOST]);
  472. RT.Methods := [rmPUT, rmDELETE];
  473. Assert(RT.Methods = [rmPUT, rmDELETE]);
  474. finally
  475. RT.Free;
  476. end;
  477. end;
  478. procedure Test_URLRouteOnMath;
  479. var
  480. RT: TFakeURLRoute;
  481. begin
  482. RT := TFakeURLRoute.Create(nil);
  483. try
  484. FakeFlag := False;
  485. RT.OnMath := RT.FakeOnMath;
  486. RT.TestOnMath;
  487. Assert(FakeFlag);
  488. finally
  489. RT.Free;
  490. end;
  491. end;
  492. procedure Test_URLRouteOnRequestMethod;
  493. var
  494. RT: TFakeURLRoute;
  495. A: Boolean;
  496. begin
  497. RT := TFakeURLRoute.Create(nil);
  498. FakeHTTPRequest := TFakeHTTPRequest.Create(nil);
  499. FakeHTTPResponse := TFakeHTTPResponse.Create(nil);
  500. try
  501. FakeFlag := False;
  502. RT.OnRequestMethod := RT.FakeOnRequestMethod;
  503. A := False;
  504. RT.TestOnRequestMethod(A);
  505. Assert(A);
  506. Assert(FakeFlag);
  507. finally
  508. RT.Free;
  509. FakeHTTPRequest.Free;
  510. FakeHTTPResponse.Free;
  511. end;
  512. end;
  513. procedure Test_URLRouteOnRequest;
  514. var
  515. RT: TFakeURLRoute;
  516. begin
  517. RT := TFakeURLRoute.Create(nil);
  518. FakeHTTPRequest := TFakeHTTPRequest.Create(nil);
  519. FakeHTTPResponse := TFakeHTTPResponse.Create(nil);
  520. try
  521. FakeFlag := False;
  522. RT.OnRequest := RT.FakeOnRequest;
  523. RT.TestOnRequest;
  524. Assert(FakeFlag);
  525. finally
  526. RT.Free;
  527. FakeHTTPRequest.Free;
  528. FakeHTTPResponse.Free;
  529. end;
  530. end;
  531. procedure Test_URLRoutesCreate;
  532. var
  533. RS: TFakeURLRoutes;
  534. P: TPersistent;
  535. begin
  536. P := TPersistent.Create;
  537. RS := TFakeURLRoutes.Create(P);
  538. try
  539. Assert(RS.Owner = P);
  540. RS.Add.Pattern := 'foo';
  541. RS.Prepare;
  542. Assert(Assigned(RS.Handle));
  543. TBrookLibraryLoader.Unload;
  544. Assert(not Assigned(RS.Handle));
  545. TBrookLibraryLoader.Load;
  546. finally
  547. RS.Free;
  548. P.Free;
  549. end;
  550. end;
  551. procedure Test_URLRoutesGetRouterClass;
  552. begin
  553. Assert(TBrookURLRoutes.GetRouterClass = TBrookURLRoute);
  554. end;
  555. procedure Test_URLRoutesNewPattern(AList: TBrookURLRoutes);
  556. var
  557. RT: TBrookURLRoute;
  558. begin
  559. AList.Clear;
  560. RT := TBrookURLRoute.Create(AList);
  561. Assert(RT.RawPattern = '^/route1$');
  562. RT := TBrookURLRoute.Create(AList);
  563. Assert(RT.RawPattern = '^/route2$');
  564. RT := TBrookURLRoute.Create(AList);
  565. Assert(RT.RawPattern = '^/route3$');
  566. end;
  567. procedure Test_URLRoutesAdd;
  568. var
  569. RS: TBrookURLRoutes;
  570. RT: TBrookURLRoute;
  571. begin
  572. RS := TBrookURLRoutes.Create(nil);
  573. try
  574. Assert(RS.Count = 0);
  575. RT := RS.Add;
  576. Assert(Assigned(RT));
  577. RT := RS.Add;
  578. Assert(Assigned(RT));
  579. RT := RS.Add;
  580. Assert(Assigned(RT));
  581. Assert(RS.Count = 3);
  582. finally
  583. RS.Free;
  584. end;
  585. end;
  586. procedure Test_URLRoutesFirst(AList: TBrookURLRoutes);
  587. var
  588. RT: TBrookURLRoute;
  589. begin
  590. AList.Clear;
  591. RT := AList.First;
  592. Assert(not Assigned(RT));
  593. AList.Add;
  594. AList.Add;
  595. RT := AList.First;
  596. Assert(Assigned(RT));
  597. Assert(RT.Pattern = '/route1');
  598. end;
  599. procedure Test_URLRoutesLast(AList: TBrookURLRoutes);
  600. var
  601. RT: TBrookURLRoute;
  602. begin
  603. AList.Clear;
  604. RT := AList.Last;
  605. Assert(not Assigned(RT));
  606. AList.Add;
  607. AList.Add;
  608. RT := AList.Last;
  609. Assert(Assigned(RT));
  610. Assert(RT.Pattern = '/route2');
  611. end;
  612. procedure Test_URLRoutesIndexOf(AList: TBrookURLRoutes);
  613. begin
  614. AList.Clear;
  615. Assert(AList.IndexOf('/route1') = -1);
  616. Assert(AList.IndexOf('/route2') = -1);
  617. AList.Add;
  618. AList.Add;
  619. Assert(AList.IndexOf('/route1') = 0);
  620. Assert(AList.IndexOf('/route2') = 1);
  621. end;
  622. procedure Test_URLRoutesFind(AList: TBrookURLRoutes);
  623. begin
  624. AList.Clear;
  625. Assert(not Assigned(AList.Find('/route1')));
  626. Assert(not Assigned(AList.Find('/route2')));
  627. AList.Add;
  628. AList.Add;
  629. Assert(Assigned(AList.Find('/route1')));
  630. Assert(Assigned(AList.Find('/route2')));
  631. end;
  632. procedure DoURLRoutesDefaultRouteAlreadyExists(const AArgs: array of const);
  633. begin
  634. TBrookURLRoute(AArgs[0].VObject).Default := True;
  635. end;
  636. procedure Test_URLRoutesFindDefault(AList: TBrookURLRoutes);
  637. var
  638. RT: TBrookURLRoute;
  639. R: TBrookURLRoute;
  640. begin
  641. AList.Clear;
  642. R := AList.FindDefault;
  643. Assert(not Assigned(R));
  644. AList.Add.Default := True;
  645. R := AList.FindDefault;
  646. Assert(Assigned(R));
  647. RT := AList.Add;
  648. AssertExcept(DoURLRoutesDefaultRouteAlreadyExists, EBrookURLRoute,
  649. SBrookDefaultRouteAlreadyExists, [RT]);
  650. end;
  651. procedure Test_URLRoutesRemove(AList: TBrookURLRoutes);
  652. begin
  653. AList.Clear;
  654. Assert(not Assigned(AList.Find('/route1')));
  655. Assert(not Assigned(AList.Find('/route2')));
  656. AList.Add;
  657. AList.Add;
  658. Assert(Assigned(AList.Find('/route1')));
  659. Assert(Assigned(AList.Find('/route2')));
  660. Assert(AList.Remove('/route1'));
  661. Assert(not Assigned(AList.Find('/route1')));
  662. Assert(Assigned(AList.Find('/route2')));
  663. Assert(not AList.Remove('/route1'));
  664. Assert(AList.Remove('/route2'));
  665. Assert(not Assigned(AList.Find('/route1')));
  666. Assert(not Assigned(AList.Find('/route2')));
  667. Assert(not AList.Remove('/route2'));
  668. end;
  669. procedure Test_URLRoutesClear;
  670. var
  671. RS: TFakeURLRoutes;
  672. begin
  673. RS := TFakeURLRoutes.Create(nil);
  674. try
  675. Assert(RS.Count = 0);
  676. Assert(not Assigned(RS.Handle));
  677. RS.Add.Pattern := 'foo';
  678. RS.Add.Pattern := 'bar';
  679. RS.Prepare;
  680. Assert(Assigned(RS.Handle));
  681. RS.Clear;
  682. Assert(RS.Count = 0);
  683. Assert(not Assigned(RS.Handle));
  684. finally
  685. RS.Free;
  686. end;
  687. end;
  688. procedure Test_URLRoutesItems(AList: TBrookURLRoutes);
  689. var
  690. RT: TBrookURLRoute;
  691. begin
  692. AList.Clear;
  693. Assert(AList.Count = 0);
  694. AList.Add;
  695. AList.Add;
  696. Assert(AList.Count = 2);
  697. RT := AList[0];
  698. Assert(Assigned(RT));
  699. Assert(RT.Pattern = '/route1');
  700. RT := AList[1];
  701. Assert(Assigned(RT));
  702. Assert(RT.Pattern = '/route2');
  703. end;
  704. procedure Test_URLRouterCreate;
  705. var
  706. R: TBrookURLRouter;
  707. begin
  708. R := TBrookURLRouter.Create(nil);
  709. try
  710. Assert(Assigned(R.Routes));
  711. finally
  712. R.Free;
  713. end;
  714. end;
  715. procedure Test_URLRouterAdd;
  716. var
  717. RT: TBrookURLRouter;
  718. R: TBrookURLRoute;
  719. begin
  720. RT := TBrookURLRouter.Create(nil);
  721. try
  722. Assert(RT.Routes.Count = 0);
  723. R := RT.Add;
  724. Assert(Assigned(R));
  725. R := RT.Add;
  726. Assert(Assigned(R));
  727. R := RT.Add;
  728. Assert(Assigned(R));
  729. Assert(RT.Routes.Count = 3);
  730. finally
  731. RT.Free;
  732. end;
  733. end;
  734. procedure Test_URLRouterRemove;
  735. var
  736. RT: TBrookURLRouter;
  737. R: TBrookURLRoute;
  738. begin
  739. RT := TBrookURLRouter.Create(nil);
  740. try
  741. Assert(RT.Routes.Count = 0);
  742. R := RT.Add;
  743. Assert(Assigned(R));
  744. R := RT.Add;
  745. Assert(Assigned(R));
  746. R := RT.Add;
  747. Assert(Assigned(R));
  748. Assert(RT.Routes.Count = 3);
  749. RT.Remove('/route1');
  750. RT.Remove('/route2');
  751. RT.Remove('/route3');
  752. Assert(RT.Routes.Count = 0);
  753. finally
  754. RT.Free;
  755. end;
  756. end;
  757. procedure Test_URLRouterClear;
  758. var
  759. RT: TBrookURLRouter;
  760. R: TBrookURLRoute;
  761. begin
  762. RT := TBrookURLRouter.Create(nil);
  763. try
  764. Assert(RT.Routes.Count = 0);
  765. R := RT.Add;
  766. Assert(Assigned(R));
  767. R := RT.Add;
  768. Assert(Assigned(R));
  769. R := RT.Add;
  770. Assert(Assigned(R));
  771. Assert(RT.Routes.Count = 3);
  772. RT.Clear;
  773. Assert(RT.Routes.Count = 0);
  774. finally
  775. RT.Free;
  776. end;
  777. end;
  778. procedure Test_URLRouterOpen;
  779. var
  780. R: TBrookURLRouter;
  781. begin
  782. R := TBrookURLRouter.Create(nil);
  783. try
  784. Assert(not R.Active);
  785. R.Open;
  786. Assert(not R.Active);
  787. R.Routes.Add;
  788. R.Open;
  789. Assert(R.Active);
  790. R.Open;
  791. finally
  792. R.Free;
  793. end;
  794. end;
  795. procedure Test_URLRouterClose;
  796. var
  797. R: TBrookURLRouter;
  798. begin
  799. R := TBrookURLRouter.Create(nil);
  800. try
  801. R.Routes.Add;
  802. R.Open;
  803. Assert(R.Active);
  804. R.Close;
  805. Assert(not R.Active);
  806. R.Close;
  807. finally
  808. R.Free;
  809. end;
  810. end;
  811. procedure DoURLRouterNoRoutesDefined(const AArgs: array of const);
  812. begin
  813. TBrookURLRouter(AArgs[0].VObject).DispatchRoute('/route', nil);
  814. end;
  815. procedure DoURLRouterInactiveRouter(const AArgs: array of const);
  816. begin
  817. TBrookURLRouter(AArgs[0].VObject).DispatchRoute('/route', nil);
  818. end;
  819. procedure Test_URLRouterDispatchRoute;
  820. var
  821. R: TBrookURLRouter;
  822. begin
  823. R := TBrookURLRouter.Create(nil);
  824. try
  825. R.Routes.Add.Pattern := '/foo';
  826. R.Open;
  827. sg_router_dispatch := fake_router_dispatch1;
  828. R.DispatchRoute('/route', FakeHandle);
  829. R.Routes.Clear;
  830. AssertExcept(DoURLRouterNoRoutesDefined, EBrookURLRoutes,
  831. SBrookNoRoutesDefined, [R]);
  832. R.Routes.Add.Pattern := '/foo';
  833. R.Close;
  834. AssertExcept(DoURLRouterInactiveRouter, EInvalidOpException,
  835. SBrookInactiveRouter, [R]);
  836. finally
  837. R.Free;
  838. end;
  839. end;
  840. procedure Test_URLRouterRoute;
  841. var
  842. RT: TFakeURLRouter;
  843. R: TBrookURLRoute;
  844. begin
  845. FakeHTTPRequest := TFakeHTTPRequest.Create(nil);
  846. FakeHTTPResponse := TFakeHTTPResponse.Create(nil);
  847. RT := TFakeURLRouter.Create(nil);
  848. try
  849. RT.Routes.Add.Pattern := '/foo';
  850. RT.Routes.Add.Pattern := '/route';
  851. R := RT.Routes.Add;
  852. R.Default := True;
  853. R.Pattern := '/bar';
  854. R.OnRequest := RT.FakeOnRequest;
  855. RT.Open;
  856. RT.OnRoute := RT.FakeOnRoute;
  857. sg_router_dispatch := fake_router_dispatch2;
  858. FakeFlag := False;
  859. RT.Route(FakeHandle, '/route', FakeHTTPRequest, FakeHTTPResponse);
  860. Assert(FakeFlag);
  861. FakeFlag := False;
  862. RT.Route(FakeHandle, FakeHTTPRequest, FakeHTTPResponse);
  863. Assert(FakeFlag);
  864. FakeFlag := False;
  865. RT.Route(R, '/', FakeHTTPRequest, FakeHTTPResponse);
  866. Assert(FakeFlag);
  867. RT.Routes.Remove('/bar');
  868. RT.OnNotFound := RT.FakeOnNotFound;
  869. FakeFlag := False;
  870. RT.Route(FakeHandle, '/', FakeHTTPRequest, FakeHTTPResponse);
  871. Assert(FakeFlag);
  872. finally
  873. RT.Free;
  874. FakeHTTPResponse.Free;
  875. FakeHTTPRequest.Free;
  876. end;
  877. end;
  878. procedure Test_URLRouterItems;
  879. var
  880. R: TBrookURLRouter;
  881. begin
  882. R := TBrookURLRouter.Create(nil);
  883. try
  884. R.Add;
  885. R.Add;
  886. R.Add;
  887. Assert(R[0].Pattern = '/route1');
  888. Assert(R[1].Pattern = '/route2');
  889. Assert(R[2].Pattern = '/route3');
  890. finally
  891. R.Free;
  892. end;
  893. end;
  894. procedure Test_URLRouterActive;
  895. var
  896. R: TBrookURLRouter;
  897. begin
  898. R := TBrookURLRouter.Create(nil);
  899. try
  900. R.Routes.Add;
  901. Assert(not R.Active);
  902. R.Active := not R.Active;
  903. Assert(R.Active);
  904. Assert(Assigned(R.Routes.Handle));
  905. finally
  906. R.Free;
  907. end;
  908. end;
  909. procedure Test_URLRouterRoutes;
  910. var
  911. R: TBrookURLRouter;
  912. begin
  913. R := TBrookURLRouter.Create(nil);
  914. try
  915. Assert(Assigned(R.Routes));
  916. finally
  917. R.Free;
  918. end;
  919. end;
  920. procedure Test_URLRouterOnRoute;
  921. var
  922. RT: TFakeURLRouter;
  923. begin
  924. FakeHTTPRequest := TFakeHTTPRequest.Create(nil);
  925. FakeHTTPResponse := TFakeHTTPResponse.Create(nil);
  926. RT := TFakeURLRouter.Create(nil);
  927. try
  928. RT.Routes.Add.Pattern := '/route';
  929. RT.Open;
  930. RT.OnRoute := RT.FakeOnRoute;
  931. FakeFlag := False;
  932. RT.Route(FakeHandle, FakeHTTPRequest, FakeHTTPResponse);
  933. Assert(FakeFlag);
  934. finally
  935. RT.Free;
  936. FakeHTTPRequest.Free;
  937. FakeHTTPResponse.Free;
  938. end;
  939. end;
  940. procedure Test_URLRouterOnNotFound;
  941. var
  942. R: TFakeURLRouter;
  943. begin
  944. FakeHTTPRequest := TFakeHTTPRequest.Create(nil);
  945. FakeHTTPResponse := TFakeHTTPResponse.Create(nil);
  946. R := TFakeURLRouter.Create(nil);
  947. try
  948. R.Routes.Add;
  949. R.Open;
  950. R.OnNotFound := R.FakeOnNotFound;
  951. FakeFlag := False;
  952. R.Route(FakeHandle, 'xxx', FakeHTTPRequest, FakeHTTPResponse);
  953. Assert(FakeFlag);
  954. finally
  955. R.Free;
  956. FakeHTTPRequest.Free;
  957. FakeHTTPResponse.Free;
  958. end;
  959. end;
  960. procedure Test_URLRouterOnActivate;
  961. var
  962. R: TFakeURLRouter;
  963. begin
  964. R := TFakeURLRouter.Create(nil);
  965. try
  966. R.OnActivate := R.FakeOnActivate;
  967. FakeFlag := False;
  968. R.Routes.Add.Pattern := '/foo';
  969. R.Open;
  970. Assert(FakeFlag);
  971. finally
  972. R.Free;
  973. end;
  974. end;
  975. procedure Test_URLRouterOnDeactivate;
  976. var
  977. R: TFakeURLRouter;
  978. begin
  979. R := TFakeURLRouter.Create(nil);
  980. try
  981. R.Routes.Add;
  982. R.Open;
  983. R.OnDeactivate := R.FakeOnDeactivate;
  984. FakeFlag := False;
  985. R.Close;
  986. Assert(FakeFlag);
  987. finally
  988. R.Free;
  989. end;
  990. end;
  991. var
  992. RS: TBrookURLRoutes;
  993. begin
  994. {$IF (NOT DEFINED(FPC)) AND DEFINED(DEBUG)}
  995. ReportMemoryLeaksOnShutdown := True;
  996. {$ENDIF}
  997. TBrookLibraryLoader.Load;
  998. RS := TBrookURLRoutes.Create(nil);
  999. try
  1000. Test_URLRouteCreate(RS);
  1001. Test_URLRouteValidate(RS);
  1002. Test_URLRoutePCRE2Handle;
  1003. Test_URLRouteSegments;
  1004. Test_URLRouteVariables;
  1005. Test_URLRouteRawPattern(RS);
  1006. Test_URLRoutePath;
  1007. Test_URLRouteUserData;
  1008. Test_URLRouteDefault;
  1009. Test_URLRoutePattern(RS);
  1010. Test_URLRouteMethods;
  1011. Test_URLRouteOnMath;
  1012. Test_URLRouteOnRequestMethod;
  1013. Test_URLRouteOnRequest;
  1014. Test_URLRoutesCreate;
  1015. Test_URLRoutesGetRouterClass;
  1016. Test_URLRoutesNewPattern(RS);
  1017. Test_URLRoutesAdd;
  1018. Test_URLRoutesFirst(RS);
  1019. Test_URLRoutesLast(RS);
  1020. Test_URLRoutesIndexOf(RS);
  1021. Test_URLRoutesFind(RS);
  1022. Test_URLRoutesFindDefault(RS);
  1023. Test_URLRoutesRemove(RS);
  1024. Test_URLRoutesClear;
  1025. Test_URLRoutesItems(RS);
  1026. Test_URLRouterCreate;
  1027. Test_URLRouterAdd;
  1028. Test_URLRouterRemove;
  1029. Test_URLRouterClear;
  1030. Test_URLRouterOpen;
  1031. Test_URLRouterClose;
  1032. Test_URLRouterDispatchRoute;
  1033. Test_URLRouterRoute;
  1034. Test_URLRouterItems;
  1035. Test_URLRouterActive;
  1036. Test_URLRouterRoutes;
  1037. Test_URLRouterOnRoute;
  1038. Test_URLRouterOnNotFound;
  1039. Test_URLRouterOnActivate;
  1040. Test_URLRouterOnDeactivate;
  1041. finally
  1042. RS.Free;
  1043. TBrookLibraryLoader.Unload;
  1044. end;
  1045. end.