Test_URLRouter.dpr 25 KB

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